From 14ad036bf2357ff272dc28e8751c8d9146597e3a Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 6 Mar 2026 11:44:39 -0800 Subject: [PATCH 001/151] Create AwdlBwuHandlerTest and add AwdlEndpointChannelTest test. PiperOrigin-RevId: 879740465 --- Package.swift | 1 + connections/implementation/BUILD | 7 + .../implementation/awdl_bwu_handler_test.cc | 529 ++++++++++++++++++ 3 files changed, 537 insertions(+) create mode 100644 connections/implementation/awdl_bwu_handler_test.cc diff --git a/Package.swift b/Package.swift index 6d3d5326..6ac9729b 100644 --- a/Package.swift +++ b/Package.swift @@ -369,6 +369,7 @@ let package = Package( "connections/implementation/payload_manager_test.cc", "connections/implementation/offline_frames_validator_test.cc", "connections/implementation/service_controller_router_test.cc", + "connections/implementation/awdl_bwu_handler_test.cc", "connections/implementation/bluetooth_bwu_test.cc", "connections/implementation/wifi_direct_bwu_test.cc", "connections/implementation/wifi_hotspot_bwu_test.cc", diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index ec42c3d2..cdb58602 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -246,6 +246,7 @@ cc_library( cc_test( name = "bwu_test", srcs = [ + "awdl_bwu_handler_test.cc", "base_bwu_handler_test.cc", "bluetooth_bwu_test.cc", "bwu_manager_test.cc", @@ -258,12 +259,18 @@ cc_test( "//connections:core_types", "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums", + "//internal/analytics:mock_event_logger", "//internal/flags:nearby_flags", "//internal/platform:base", + "//internal/platform:cancellation_flag", + "//internal/platform:comm", "//internal/platform:logging", + "//internal/platform:mock_platform", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/flags:platform_flags", + "//internal/platform/implementation:comm", + "//internal/platform/implementation:platform", # build_cleaner: keep "//internal/platform/implementation/g3", # build_cleaner: keep "//internal/proto/analytics:connections_log_cc_proto", "//proto:connections_enums_cc_proto", diff --git a/connections/implementation/awdl_bwu_handler_test.cc b/connections/implementation/awdl_bwu_handler_test.cc new file mode 100644 index 00000000..a2ef2417 --- /dev/null +++ b/connections/implementation/awdl_bwu_handler_test.cc @@ -0,0 +1,529 @@ +// Copyright 2026 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. + +#include "connections/implementation/awdl_bwu_handler.h" + +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "protobuf-matchers/protocol-buffer-matchers.h" +#include "gtest/gtest.h" +#include "absl/strings/string_view.h" +#include "absl/time/clock.h" +#include "absl/time/time.h" +#include "connections/implementation/awdl_endpoint_channel.h" +#include "connections/implementation/bwu_handler.h" +#include "connections/implementation/client_proxy.h" +#include "connections/implementation/mediums/awdl.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/awdl.h" +#include "internal/platform/byte_array.h" +#include "internal/platform/cancellation_flag.h" +#include "internal/platform/count_down_latch.h" +#include "internal/platform/exception.h" +#include "internal/platform/implementation/awdl.h" +#include "internal/platform/implementation/platform.h" +#include "internal/platform/implementation/psk_info.h" +#include "internal/platform/input_stream.h" +#include "internal/platform/medium_environment.h" +#include "internal/platform/mock_input_stream.h" +#include "internal/platform/mock_output_stream.h" +#include "internal/platform/nsd_service_info.h" +#include "internal/platform/output_stream.h" +#include "internal/proto/analytics/connections_log.pb.h" + +namespace nearby { + +class MockAwdlSocket : public api::AwdlSocket { + public: + MOCK_METHOD(InputStream&, GetInputStream, (), (override)); + MOCK_METHOD(OutputStream&, GetOutputStream, (), (override)); + MOCK_METHOD(Exception, Close, (), (override)); +}; + +class MockAwdlServerSocket : public api::AwdlServerSocket { + public: + MOCK_METHOD(std::string, GetIPAddress, (), (const, override)); + MOCK_METHOD(int, GetPort, (), (const, override)); + MOCK_METHOD(std::unique_ptr, Accept, (), (override)); + MOCK_METHOD(Exception, Close, (), (override)); +}; + +class MockAwdlMedium : public api::AwdlMedium { + public: + MOCK_METHOD(bool, IsNetworkConnected, (), (const, override)); + MOCK_METHOD(bool, StartAdvertising, (const NsdServiceInfo& nsd_service_info), + (override)); + MOCK_METHOD(bool, StopAdvertising, (const NsdServiceInfo& nsd_service_info), + (override)); + MOCK_METHOD(bool, StartDiscovery, + (const std::string& service_type, + DiscoveredServiceCallback callback), + (override)); + MOCK_METHOD(bool, StopDiscovery, (const std::string& service_type), + (override)); + MOCK_METHOD(std::unique_ptr, ConnectToService, + (const NsdServiceInfo& remote_service_info, + CancellationFlag* cancellation_flag), + (override)); + MOCK_METHOD(std::unique_ptr, ConnectToService, + (const NsdServiceInfo& remote_service_info, + const api::PskInfo& psk_info, + CancellationFlag* cancellation_flag), + (override)); + MOCK_METHOD(std::unique_ptr, ListenForService, + (int port), (override)); + MOCK_METHOD(std::unique_ptr, ListenForService, + (const api::PskInfo& psk_info, int port), (override)); + MOCK_METHOD((std::optional>), + GetDynamicPortRange, (), (override)); +}; + +MockAwdlMedium* awdl_medium_mock = nullptr; + +namespace connections { +namespace { + +using ::location::nearby::analytics::proto::ConnectionsLog; +using ::location::nearby::connections::BandwidthUpgradeNegotiationFrame; +using ::location::nearby::connections::OfflineFrame; +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::Matcher; +using ::testing::MockFunction; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::StrictMock; + +constexpr absl::string_view kServiceId{"service_id"}; +constexpr absl::string_view kEndpointId{"endpoint_id"}; +constexpr absl::string_view kServiceName{"awdl_srv"}; +constexpr absl::string_view kServiceType{"_awdl._tcp"}; +constexpr absl::string_view kPassword{"password123"}; +constexpr absl::string_view kChannelName{"channel_name"}; + +class AwdlBwuHandlerTest : public ::testing::Test { + protected: + AwdlBwuHandlerTest() + : handler_(mediums_, incoming_connection_callback_.AsStdFunction()) {} + + void SetUp() override { + // By default, network is connected. + ON_CALL(*awdl_medium_mock, IsNetworkConnected()) + .WillByDefault(Return(true)); + } + + Mediums mediums_; + MockFunction)> + incoming_connection_callback_; + AwdlBwuHandler handler_; + nearby::analytics::MockEventLogger mock_event_logger_; + MockInputStream mock_input_stream_; + MockOutputStream mock_output_stream_; +}; + +TEST_F(AwdlBwuHandlerTest, + CreateUpgradedEndpointChannel_InvalidCredentials_Fails) { + ClientProxy client(&mock_event_logger_); + BandwidthUpgradeNegotiationFrame::UpgradePathInfo path_info; + path_info.mutable_awdl_credentials(); // Empty credentials + + auto result = + static_cast(&handler_)->CreateUpgradedEndpointChannel( + &client, "service_id", "endpoint_id", path_info); + + ASSERT_TRUE(result.has_error()); + EXPECT_EQ(result.error().operation_result_code().value(), + OperationResultCode::CONNECTIVITY_AWDL_INVALID_CREDENTIAL); +} + +TEST_F(AwdlBwuHandlerTest, CreateUpgradedEndpointChannel_Success) { + ClientProxy client(&mock_event_logger_); + client.AddCancellationFlag(std::string(kEndpointId)); + MockInputStream input_stream; + MockOutputStream output_stream; + auto awdl_socket = std::make_unique(); + EXPECT_CALL(*awdl_socket, GetInputStream()) + .WillRepeatedly(ReturnRef(input_stream)); + EXPECT_CALL(*awdl_socket, GetOutputStream()) + .WillRepeatedly(ReturnRef(output_stream)); + + EXPECT_CALL(*awdl_medium_mock, StartDiscovery(_, _)) + .WillOnce([](const std::string& service_type, + api::AwdlMedium::DiscoveredServiceCallback callback) { + NsdServiceInfo service_info; + service_info.SetServiceName(std::string(kServiceName)); + service_info.SetServiceType(service_type); + if (callback.service_discovered_cb) { + NsdServiceInfo service_info_copy = service_info; + callback.service_discovered_cb(service_info_copy); + } + return true; + }); + EXPECT_CALL(*awdl_medium_mock, StopDiscovery(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(*awdl_medium_mock, ConnectToService(_, _, _)) + .WillOnce(Return(ByMove(std::move(awdl_socket)))); + + BandwidthUpgradeNegotiationFrame::UpgradePathInfo path_info; + auto* credentials = path_info.mutable_awdl_credentials(); + credentials->set_service_name(kServiceName); + credentials->set_service_type(kServiceType); + credentials->set_password(kPassword); + + auto result = + static_cast(&handler_)->CreateUpgradedEndpointChannel( + &client, std::string(kServiceId), std::string(kEndpointId), + path_info); + + EXPECT_TRUE(result.has_value()); +} + +TEST_F(AwdlBwuHandlerTest, + InitializeUpgradedMediumForEndpoint_StartAcceptingConnectionsFails) { + MediumEnvironment::Instance().Start({.use_simulated_clock = true}); + ClientProxy client(&mock_event_logger_); + client.AddCancellationFlag(std::string(kEndpointId)); + + EXPECT_CALL(*awdl_medium_mock, ListenForService(_, 0)) + .WillOnce(Return(ByMove(nullptr))); + + ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( + &client, std::string(kServiceId), std::string(kEndpointId)); + + EXPECT_TRUE(result.Empty()); + MediumEnvironment::Instance().Stop(); +} + +TEST_F(AwdlBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { + 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::AWDL, + location::nearby::proto::connections::ConnectionAttemptDirection:: + OUTGOING, + /*connection_token=*/""); + client.AddCancellationFlag(std::string(kEndpointId)); + + auto awdl_server_socket = std::make_unique(); + + EXPECT_CALL(*awdl_medium_mock, ListenForService(_, 0)) + .WillOnce(Return(ByMove(std::move(awdl_server_socket)))); + EXPECT_CALL(*awdl_medium_mock, StartAdvertising(_)).WillOnce(Return(true)); + + ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( + &client, std::string(kServiceId), std::string(kEndpointId)); + + EXPECT_FALSE(result.Empty()); + OfflineFrame result_frame; + EXPECT_TRUE(result_frame.ParseFromString(std::string(result))); + EXPECT_TRUE(result_frame.has_v1()); + EXPECT_TRUE(result_frame.v1().has_bandwidth_upgrade_negotiation()); + EXPECT_TRUE(result_frame.v1() + .bandwidth_upgrade_negotiation() + .has_upgrade_path_info()); + EXPECT_TRUE(result_frame.v1() + .bandwidth_upgrade_negotiation() + .upgrade_path_info() + .has_awdl_credentials()); + + 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: AWDL + 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 + } + } + } + } + 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(); +} + +TEST_F(AwdlBwuHandlerTest, OnIncomingAwdlConnection_Success) { + MediumEnvironment::Instance().Start({.use_simulated_clock = true}); + ClientProxy client(&mock_event_logger_); + client.AddCancellationFlag(std::string(kEndpointId)); + + auto awdl_server_socket = std::make_unique(); + auto* awdl_server_socket_ptr = awdl_server_socket.get(); + EXPECT_CALL(*awdl_server_socket_ptr, Close()) + .WillRepeatedly(Return(Exception{Exception::kSuccess})); + EXPECT_CALL(*awdl_server_socket_ptr, Accept()) + .WillOnce([this]() { + auto awdl_socket = std::make_unique(); + EXPECT_CALL(*awdl_socket, GetInputStream()) + .WillRepeatedly(ReturnRef(mock_input_stream_)); + EXPECT_CALL(*awdl_socket, GetOutputStream()) + .WillRepeatedly(ReturnRef(mock_output_stream_)); + return awdl_socket; + }) + .WillRepeatedly([]() { + absl::SleepFor(absl::Seconds(5)); + return nullptr; + }); + + EXPECT_CALL(*awdl_medium_mock, ListenForService(_, 0)) + .WillOnce(Return(ByMove(std::move(awdl_server_socket)))); + EXPECT_CALL(*awdl_medium_mock, StartAdvertising(_)).WillOnce(Return(true)); + + CountDownLatch latch(1); + EXPECT_CALL(incoming_connection_callback_, Call(&client, _)) + .WillOnce([&latch](ClientProxy* client, + std::unique_ptr + connection) { latch.CountDown(); }); + + ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( + &client, std::string(kServiceId), std::string(kEndpointId)); + EXPECT_FALSE(result.Empty()); + + auto await_result = latch.Await(absl::Seconds(5)); + EXPECT_TRUE(await_result.ok()); + + handler_.RevertInitiatorState(); + MediumEnvironment::Instance().Stop(); +} + +TEST_F(AwdlBwuHandlerTest, AwdlIncomingSocket_ToStringAndClose) { + MediumEnvironment::Instance().Start({.use_simulated_clock = true}); + ClientProxy client(&mock_event_logger_); + client.AddCancellationFlag(std::string(kEndpointId)); + + auto awdl_server_socket = std::make_unique(); + auto* awdl_server_socket_ptr = awdl_server_socket.get(); + EXPECT_CALL(*awdl_server_socket_ptr, Close()) + .WillRepeatedly(Return(Exception{Exception::kSuccess})); + EXPECT_CALL(*awdl_server_socket_ptr, Accept()) + .WillOnce([this]() { + auto awdl_socket = std::make_unique(); + EXPECT_CALL(*awdl_socket, GetInputStream()) + .WillRepeatedly(ReturnRef(mock_input_stream_)); + EXPECT_CALL(*awdl_socket, GetOutputStream()) + .WillRepeatedly(ReturnRef(mock_output_stream_)); + EXPECT_CALL(*awdl_socket, Close()) + .WillOnce(Return(Exception{Exception::kSuccess})); + return awdl_socket; + }) + .WillRepeatedly([]() { + absl::SleepFor(absl::Seconds(5)); + return nullptr; + }); + + EXPECT_CALL(*awdl_medium_mock, ListenForService(_, 0)) + .WillOnce(Return(ByMove(std::move(awdl_server_socket)))); + EXPECT_CALL(*awdl_medium_mock, StartAdvertising(_)).WillOnce(Return(true)); + + CountDownLatch latch(1); + EXPECT_CALL(incoming_connection_callback_, Call(&client, _)) + .WillOnce([&latch](ClientProxy* client, + std::unique_ptr + connection) { + EXPECT_FALSE(connection->socket->ToString().empty()); + connection->socket->Close(); + latch.CountDown(); + }); + + ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( + &client, std::string(kServiceId), std::string(kEndpointId)); + EXPECT_FALSE(result.Empty()); + + auto await_result = latch.Await(absl::Seconds(5)); + EXPECT_TRUE(await_result.ok()); + + handler_.RevertInitiatorState(); + MediumEnvironment::Instance().Stop(); +} + +TEST_F(AwdlBwuHandlerTest, HandleRevertInitiatorStateForService_Success) { + MediumEnvironment::Instance().Start({.use_simulated_clock = true}); + ClientProxy client(&mock_event_logger_); + client.AddCancellationFlag(std::string(kEndpointId)); + + auto awdl_server_socket = std::make_unique(); + auto* awdl_server_socket_ptr = awdl_server_socket.get(); + EXPECT_CALL(*awdl_server_socket_ptr, Close()) + .WillRepeatedly(Return(Exception{Exception::kSuccess})); + EXPECT_CALL(*awdl_server_socket_ptr, Accept()).WillRepeatedly([]() { + absl::SleepFor(absl::Seconds(10)); + return nullptr; + }); + + EXPECT_CALL(*awdl_medium_mock, ListenForService(_, 0)) + .WillOnce(Return(ByMove(std::move(awdl_server_socket)))); + EXPECT_CALL(*awdl_medium_mock, StartAdvertising(_)).WillOnce(Return(true)); + EXPECT_CALL(*awdl_medium_mock, StopAdvertising(_)).WillOnce(Return(true)); + + handler_.InitializeUpgradedMediumForEndpoint(&client, std::string(kServiceId), + std::string(kEndpointId)); + + handler_.RevertInitiatorState(); + MediumEnvironment::Instance().Stop(); +} + +TEST_F(AwdlBwuHandlerTest, GetUpgradeMedium_ReturnsAwdl) { + auto* bwu_handler = static_cast(&handler_); + EXPECT_EQ(bwu_handler->GetUpgradeMedium(), + location::nearby::proto::connections::Medium::AWDL); +} + +TEST_F(AwdlBwuHandlerTest, OnEndpointDisconnect_DoesNotCrash) { + ClientProxy client(&mock_event_logger_); + auto* bwu_handler = static_cast(&handler_); + // This method is a no-op, just verifying it doesn't crash. + bwu_handler->OnEndpointDisconnect(&client, std::string(kEndpointId)); +} + +class AwdlEndpointChannelTest : public ::testing::Test { + protected: + void SetUp() override { + ON_CALL(*awdl_medium_mock, IsNetworkConnected()) + .WillByDefault(Return(true)); + mock_socket_ = std::make_unique>(); + EXPECT_CALL(*mock_socket_, GetInputStream()) + .WillRepeatedly(ReturnRef(mock_input_stream_)); + EXPECT_CALL(*mock_socket_, GetOutputStream()) + .WillRepeatedly(ReturnRef(mock_output_stream_)); + } + + std::unique_ptr> mock_socket_; + StrictMock mock_input_stream_; + StrictMock mock_output_stream_; + Awdl awdl_medium_; +}; + +TEST_F(AwdlEndpointChannelTest, CloseImpl_StopsDiscoveryIfOutgoing) { + EXPECT_CALL(*mock_socket_, Close()) + .WillOnce(Return(Exception{Exception::kSuccess})); + EXPECT_CALL(mock_input_stream_, Close()) + .WillOnce(Return(Exception{Exception::kSuccess})); + EXPECT_CALL(mock_output_stream_, Close()) + .WillOnce(Return(Exception{Exception::kSuccess})); + EXPECT_CALL(*awdl_medium_mock, StartDiscovery(_, _)).WillOnce(Return(true)); + EXPECT_CALL(*awdl_medium_mock, StopDiscovery(_)).WillOnce(Return(true)); + awdl_medium_.StartDiscovery(std::string(kServiceId), {}); + + AwdlEndpointChannel channel( + std::string(kServiceId), std::string(kChannelName), + AwdlSocket(std::move(mock_socket_)), &awdl_medium_, + /*is_outgoing=*/true); + + channel.Close(location::nearby::proto::connections::DisconnectionReason:: + UNKNOWN_DISCONNECTION_REASON); +} + +TEST_F(AwdlEndpointChannelTest, CloseImpl_DoesNotStopDiscoveryIfIncoming) { + EXPECT_CALL(*mock_socket_, Close()) + .WillOnce(Return(Exception{Exception::kSuccess})); + EXPECT_CALL(mock_input_stream_, Close()) + .WillOnce(Return(Exception{Exception::kSuccess})); + EXPECT_CALL(mock_output_stream_, Close()) + .WillOnce(Return(Exception{Exception::kSuccess})); + + AwdlEndpointChannel channel( + std::string(kServiceId), std::string(kChannelName), + AwdlSocket(std::move(mock_socket_)), &awdl_medium_, + /*is_outgoing=*/false); + + channel.Close(location::nearby::proto::connections::DisconnectionReason:: + UNKNOWN_DISCONNECTION_REASON); +} + +TEST_F(AwdlEndpointChannelTest, EnableMultiplexSocket_CallsSocket) { + AwdlEndpointChannel channel( + std::string(kServiceId), std::string(kChannelName), + AwdlSocket(std::move(mock_socket_)), &awdl_medium_, + /*is_outgoing=*/true); + + EXPECT_TRUE(channel.EnableMultiplexSocket()); +} + +} // namespace +} // namespace connections +namespace api { + +std::unique_ptr ImplementationPlatform::CreateAwdlMedium() { + auto medium = std::make_unique(); + awdl_medium_mock = medium.get(); + return medium; +} + +} // namespace api +} // namespace nearby From 0cc01b476cf3332bba6bb57d7166a8d5f934a22b Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 6 Mar 2026 15:44:35 -0800 Subject: [PATCH 002/151] Cleanup PiperOrigin-RevId: 879854458 --- internal/base/BUILD | 3 +- internal/platform/BUILD | 1 - internal/platform/implementation/BUILD | 63 ----------- .../platform/implementation/account_info.h | 35 ------ .../platform/implementation/account_manager.h | 89 --------------- .../platform/implementation/auth_status.h | 88 --------------- .../platform/implementation/signin_attempt.h | 48 --------- .../tachyon_express_signaling_messenger.cc | 1 - .../tachyon_express_signaling_messenger.h | 4 +- internal/test/BUILD | 25 ----- internal/test/fake_account_manager.cc | 101 ------------------ internal/test/fake_account_manager.h | 81 -------------- internal/test/mock_account_manager.h | 57 ---------- internal/test/mock_account_observer.h | 38 ------- sharing/BUILD | 7 +- sharing/certificates/BUILD | 6 +- .../nearby_share_certificate_manager_impl.cc | 13 +-- .../nearby_share_certificate_manager_impl.h | 8 +- ...rby_share_certificate_manager_impl_test.cc | 15 ++- sharing/contacts/BUILD | 6 +- .../nearby_share_contact_manager_impl.cc | 8 +- .../nearby_share_contact_manager_impl.h | 8 +- .../nearby_share_contact_manager_impl_test.cc | 4 +- sharing/internal/api/BUILD | 4 +- sharing/internal/api/mock_sharing_platform.h | 2 +- sharing/internal/api/sharing_platform.h | 2 +- sharing/local_device_data/BUILD | 5 +- ...by_share_local_device_data_manager_impl.cc | 8 +- ...rby_share_local_device_data_manager_impl.h | 2 +- ...are_local_device_data_manager_impl_test.cc | 6 +- sharing/nearby_sharing_service.h | 8 +- sharing/nearby_sharing_service_impl.cc | 2 +- sharing/nearby_sharing_service_impl.h | 4 +- sharing/nearby_sharing_service_impl_test.cc | 12 +-- 34 files changed, 60 insertions(+), 704 deletions(-) delete mode 100644 internal/platform/implementation/account_info.h delete mode 100644 internal/platform/implementation/account_manager.h delete mode 100644 internal/platform/implementation/auth_status.h delete mode 100644 internal/platform/implementation/signin_attempt.h delete mode 100644 internal/test/fake_account_manager.cc delete mode 100644 internal/test/fake_account_manager.h delete mode 100644 internal/test/mock_account_manager.h delete mode 100644 internal/test/mock_account_observer.h diff --git a/internal/base/BUILD b/internal/base/BUILD index 7f8ae71f..6fc220dc 100644 --- a/internal/base/BUILD +++ b/internal/base/BUILD @@ -19,8 +19,6 @@ licenses(["notice"]) cc_library( name = "base", - srcs = [ - ], hdrs = [ "observer_list.h", ], @@ -28,6 +26,7 @@ cc_library( "//internal/account:__subpackages__", "//internal/platform:__subpackages__", "//internal/test:__pkg__", + "//location/nearby/sharing/lib:__subpackages__", "//sharing:__subpackages__", ], deps = [ diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 67f362f5..88e62b1f 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -332,7 +332,6 @@ cc_library( "//connections/implementation/flags:connections_flags", "//internal/base", "//internal/flags:nearby_flags", - "//internal/platform/implementation:account_manager", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", "//internal/platform/implementation:wifi_utils", diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index d9a63885..708acebc 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -17,69 +17,6 @@ load("@rules_cc//cc:cc_test.bzl", "cc_test") licenses(["notice"]) -cc_library( - name = "auth_status", - hdrs = ["auth_status.h"], - visibility = [ - "//internal/auth:__pkg__", - "//internal/platform/implementation:__subpackages__", - "//location/nearby/cpp/sharing/clients/cpp:__subpackages__", - ], -) - -cc_library( - name = "account_info", - hdrs = ["account_info.h"], - visibility = [ - "//internal/auth:__pkg__", - "//internal/platform/implementation:__subpackages__", - "//location/nearby/cpp/sharing/clients/cpp:__subpackages__", - ], -) - -cc_library( - name = "account_manager", - hdrs = ["account_manager.h"], - visibility = [ - "//internal/account:__pkg__", - "//internal/platform:__pkg__", - "//internal/platform/implementation:__subpackages__", - "//internal/test:__subpackages__", - "//location/nearby/cpp/sharing/clients/cpp:__subpackages__", - "//location/nearby/sharing/lib:__subpackages__", - "//location/nearby/sharing/sdk/quick_share_server:__pkg__", - "//sharing:__subpackages__", - ], - deps = [ - ":account_info", - ":signin_attempt", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings:string_view", - ], -) - -cc_library( - name = "signin_attempt", - hdrs = ["signin_attempt.h"], - visibility = [ - "//internal/account:__pkg__", - "//internal/auth:__pkg__", - "//internal/platform/implementation:__subpackages__", - "//internal/test:__subpackages__", - "//location/nearby/cpp/sharing/clients/cpp:__subpackages__", - "//location/nearby/sharing/sdk/quick_share_server:__pkg__", - "//sharing:__subpackages__", - ], - deps = [ - ":account_info", - ":auth_status", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings:string_view", - ], -) - cc_library( name = "types", hdrs = [ diff --git a/internal/platform/implementation/account_info.h b/internal/platform/implementation/account_info.h deleted file mode 100644 index 2cb48535..00000000 --- a/internal/platform/implementation/account_info.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2024 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_ACCOUNT_INFO_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_ACCOUNT_INFO_H_ - -#include - -namespace nearby { - -// Describes a Nearby account. The account class will have more properties -// and methods in the future based on the new feature added. -struct AccountInfo { - std::string id; // The unique identify of the account. - std::string display_name; - std::string family_name; - std::string given_name; - std::string picture_url; - std::string email; -}; - -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_ACCOUNT_INFO_H_ diff --git a/internal/platform/implementation/account_manager.h b/internal/platform/implementation/account_manager.h deleted file mode 100644 index 3ab62731..00000000 --- a/internal/platform/implementation/account_manager.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2022 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 PLATFORM_API_ACCOUNT_MANAGER_H_ -#define PLATFORM_API_ACCOUNT_MANAGER_H_ - -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/account_info.h" -#include "internal/platform/implementation/signin_attempt.h" - -namespace nearby { - -// AccountManager manages the accounts are used to access Nearby backend. -// In current design, AccountManager only support one active account. -class AccountManager { - public: - using Account = AccountInfo; - - // Observes the activity of the account manager. - class Observer { - public: - virtual ~Observer() = default; - - virtual void OnLoginSucceeded(absl::string_view account_id) = 0; - // |credential_error| is true if the logout is due to critical auth error. - virtual void OnLogoutSucceeded(absl::string_view account_id, - bool credential_error) = 0; - }; - - virtual ~AccountManager() = default; - - // Gets current active account. If no login user, return std::nullopt. - virtual std::optional GetCurrentAccount() = 0; - - // Initializes the login process for a Google account from an oauth client. - // |client_id| GCP client_id of the client - // |client_secret| GCP client_secret of the client - // Returns a SigninAttempt object that can be used to complete the login - // process. - virtual std::unique_ptr Login( - absl::string_view client_id, absl::string_view client_secret) = 0; - - // Logs out current active account. |logout_callback| is called when logout is - // completed. - virtual void Logout( - absl::AnyInvocable logout_callback) = 0; - - // Gets access token for the active account. - // |callback| is called with the access token or error status. - // - // Returns false if callback is null. - virtual bool GetAccessToken( - absl::AnyInvocable)> callback) = 0; - - // Returns a pair containing the client id and client secret used in the most - // recent Login request. - // If no current user is logged in, returns empty string for both. - virtual std::pair GetOAuthClientCredential() = 0; - - virtual void AddObserver(Observer* observer) = 0; - virtual void RemoveObserver(Observer* observer) = 0; - - virtual void SaveAccountPrefs(absl::string_view user_id, - absl::string_view client_id, - absl::string_view client_secret) = 0; -}; - -} // namespace nearby - -#endif // PLATFORM_API_ACCOUNT_MANAGER_H_ diff --git a/internal/platform/implementation/auth_status.h b/internal/platform/implementation/auth_status.h deleted file mode 100644 index 00227836..00000000 --- a/internal/platform/implementation/auth_status.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2024 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_AUTH_STATUS_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_AUTH_STATUS_H_ - -namespace nearby { - -enum AuthStatus { - AUTH_STATUS_UNSPECIFIED = 0, - // Request completed successfully, the results should be in the correct order - // up to the given count. - SUCCESS = 1, - - // Request encountered a generic error. - GENERIC_ERROR = 2, - - // Request as specified is not supported. - UNSUPPORTED = 3, - - // Request failed and should be retried soon. - TEMPORARILY_UNAVAILABLE = 4, - - // Request failed due to an unavailable resource. - UNAVAILABLE_RESOURCE = 5, - - // The request failed due to an invalid argument. - INVALID_ARGUMENT = 6, - - // In case the status could not be retrieved. - UNKNOWN_STATUS = 7, - - // Currently used as a way to signal an ETag mismatch. - PRECONDITION_FAILED = 8, - - // Exclusively used to report when user did not consent to required scopes. - // Do NOT use this for another other scenarios. - PERMISSION_DENIED = 9, - - // The resource exists, but the requested attribute of it does not. - MISSING_ATTRIBUTE = 10, - - // The method was interrupted and the caller should exit the current unit of - // work immediately. - INTERRUPTED = 11, - - // User signed in with an unexpected account. - SIGNED_IN_WITH_WRONG_ACCOUNT = 12, - - // Used when data cannot be parsed properly. - PARSE_ERROR = 13, - - // Used to report that the local HTTP server for receiving the authorization - // code cannot be created. - CANT_CREATE_AUTH_SERVER = 14, - - // Used to report that the system browser for authenticating the user cannot - // be open. - CANT_OPEN_BROWSER_FOR_AUTH = 15, - - // Used to report that the authorization code cannot be received. - CANT_RECEIVE_AUTH_CODE = 16, - - // Used to report that the account is blocked (e.g. CAA). - ACCOUNT_BLOCKED = 17, - - // Receiving the authorization code failed because it took longer than the - // timeout. - AUTH_CODE_TIMEOUT_EXCEEDED = 18, - - // Used to report when user presses the cancel button during login process. - USER_CANCELED = 19, -}; - -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_AUTH_STATUS_H_ diff --git a/internal/platform/implementation/signin_attempt.h b/internal/platform/implementation/signin_attempt.h deleted file mode 100644 index aa631a54..00000000 --- a/internal/platform/implementation/signin_attempt.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024 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_SIGNIN_ATTEMPT_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_SIGNIN_ATTEMPT_H_ - -#include - -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/account_info.h" -#include "internal/platform/implementation/auth_status.h" - -namespace nearby { - -class SigninAttempt { - public: - SigninAttempt() = default; - virtual ~SigninAttempt() = default; - - // Starts a new sign-in attempt. - // `callback` is called with the status of the request, client_id, - // client_secret, and account_info if the request is successful. Returns the - // auth url if the request is successful. - virtual std::string Start( - absl::AnyInvocable - callback) = 0; - - // Tears down the machinery set up to request auth tokens, including the HTTP - // server. - virtual void Close() = 0; -}; - -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_SIGNIN_ATTEMPT_H_ diff --git a/internal/platform/tachyon_express_signaling_messenger.cc b/internal/platform/tachyon_express_signaling_messenger.cc index fc93df70..6b07190a 100644 --- a/internal/platform/tachyon_express_signaling_messenger.cc +++ b/internal/platform/tachyon_express_signaling_messenger.cc @@ -35,7 +35,6 @@ #include "internal/account/account_manager_impl.h" #include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/implementation/webrtc.h" #include "internal/platform/logging.h" #include "internal/proto/messaging.grpc.pb.h" diff --git a/internal/platform/tachyon_express_signaling_messenger.h b/internal/platform/tachyon_express_signaling_messenger.h index 872f95b9..8f01bddd 100644 --- a/internal/platform/tachyon_express_signaling_messenger.h +++ b/internal/platform/tachyon_express_signaling_messenger.h @@ -22,6 +22,7 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" #include "absl/base/thread_annotations.h" #include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" @@ -30,7 +31,6 @@ #include "third_party/grpc/include/grpcpp/support/client_callback.h" #include "third_party/grpc/include/grpcpp/support/status.h" #include "internal/platform/byte_array.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/implementation/webrtc.h" #include "internal/proto/messaging.grpc.pb.h" @@ -94,7 +94,7 @@ class TachyonExpressSignalingMessenger : public api::WebRtcSignalingMessenger { std::unique_ptr messaging_stub_; - AccountManager* const account_manager_; + nearby::sharing::AccountManager* const account_manager_; std::shared_ptr reader_ = nullptr; }; diff --git a/internal/test/BUILD b/internal/test/BUILD index da7d9bcf..589e9f35 100644 --- a/internal/test/BUILD +++ b/internal/test/BUILD @@ -17,36 +17,15 @@ load("@rules_cc//cc:cc_test.bzl", "cc_test") licenses(["notice"]) -cc_library( - name = "mocks", - testonly = 1, - hdrs = [ - "mock_account_manager.h", - "mock_account_observer.h", - ], - visibility = ["//visibility:public"], - deps = [ - "//internal/platform/implementation:account_manager", - "//internal/platform/implementation:signin_attempt", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings:string_view", - "@com_google_googletest//:gtest_for_library_testonly", - ], -) - cc_library( name = "test", srcs = [ - "fake_account_manager.cc", "fake_clock.cc", "fake_single_thread_executor.cc", "fake_task_runner.cc", "fake_timer.cc", ], hdrs = [ - "fake_account_manager.h", "fake_clock.h", "fake_device_info.h", "fake_http_client.h", @@ -60,20 +39,16 @@ cc_library( ], visibility = ["//visibility:public"], deps = [ - "//internal/base", "//internal/base:file_path", "//internal/base:files", "//internal/network:types", "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:types", - "//internal/platform/implementation:account_manager", - "//internal/platform/implementation:signin_attempt", "//internal/platform/implementation:types", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/log", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", diff --git a/internal/test/fake_account_manager.cc b/internal/test/fake_account_manager.cc deleted file mode 100644 index c6e919f8..00000000 --- a/internal/test/fake_account_manager.cc +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2022 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. - -#include "internal/test/fake_account_manager.h" - -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/account_manager.h" -#include "internal/platform/implementation/signin_attempt.h" - -namespace nearby { - -std::optional FakeAccountManager::GetCurrentAccount() { - return account_; -} - -std::unique_ptr FakeAccountManager::Login( - absl::string_view client_id, absl::string_view client_secret) { - return nullptr; -} - -void FakeAccountManager::Logout( - absl::AnyInvocable logout_callback) { - if (is_logout_success_) { - std::string account_id = account_->id; - SetAccount(std::nullopt); - NotifyLogout(account_id, /*credential_error=*/false); - // Invoke callback after all operations have been performed since test cases - // may rely on the callback for synchronization. - logout_callback(absl::OkStatus()); - return; - } - - logout_callback(absl::NotFoundError("No account login.")); -} - -bool FakeAccountManager::GetAccessToken( - absl::AnyInvocable)> callback) { - if (!callback) { - return false; - } - if (!account_.has_value()) { - callback(absl::UnavailableError("No current user.")); - return true; - } - callback("FAKE_ACCESS_TOKEN"); - return true; -} - -std::pair -FakeAccountManager::GetOAuthClientCredential() { - return {"", ""}; -} - -void FakeAccountManager::SetAccount(std::optional account) { - account_ = account; -} - -void FakeAccountManager::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void FakeAccountManager::RemoveObserver(Observer* observer) { - if (!observers_.HasObserver(observer)) { - return; - } - observers_.RemoveObserver(observer); -} - -void FakeAccountManager::NotifyLogin(absl::string_view account_id) { - for (const auto& observer : observers_.GetObservers()) { - observer->OnLoginSucceeded(account_id); - } -} - -void FakeAccountManager::NotifyLogout(absl::string_view account_id, - bool credential_error) { - for (const auto& observer : observers_.GetObservers()) { - observer->OnLogoutSucceeded(account_id, credential_error); - } -} - -} // namespace nearby diff --git a/internal/test/fake_account_manager.h b/internal/test/fake_account_manager.h deleted file mode 100644 index 346663cf..00000000 --- a/internal/test/fake_account_manager.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2022 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_TEST_FAKE_ACCOUNT_MANAGER_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_ACCOUNT_MANAGER_H_ - -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/base/observer_list.h" -#include "internal/platform/implementation/account_manager.h" -#include "internal/platform/implementation/signin_attempt.h" - -namespace nearby { - -// A fake implementation of FakeAccountManager, along with a fake -// factory, to be used in tests. -class FakeAccountManager : public AccountManager { - public: - FakeAccountManager() = default; - ~FakeAccountManager() override = default; - - std::optional GetCurrentAccount() override; - - std::unique_ptr Login( - absl::string_view client_id, absl::string_view client_secret) override; - - void Logout(absl::AnyInvocable logout_callback) override; - - bool GetAccessToken( - absl::AnyInvocable)> callback) override; - std::pair GetOAuthClientCredential() override; - void AddObserver(Observer* observer) override; - void RemoveObserver(Observer* observer) override; - - void SaveAccountPrefs(absl::string_view user_id, absl::string_view client_id, - absl::string_view client_secret) override {} - - // Methods to set API response. - void SetAccount(std::optional account); - - void SetLogoutSuccess(bool is_logout_success) { - is_logout_success_ = is_logout_success; - } - - void NotifyCredentialError() { - NotifyLogout(account_->id, /*credential_error=*/true); - } - - void NotifyLogin(absl::string_view account_id); - void NotifyLogout(absl::string_view account_id, bool credential_error); - - private: - // Login will fail when account_ is empty. - std::optional account_; - - // Logout will fail when is_logout_success_ is false; - bool is_logout_success_ = true; - nearby::ObserverList observers_; -}; - -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_ACCOUNT_MANAGER_H_ diff --git a/internal/test/mock_account_manager.h b/internal/test/mock_account_manager.h deleted file mode 100644 index 778aa7aa..00000000 --- a/internal/test/mock_account_manager.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2024 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_TEST_MOCK_ACCOUNT_MANAGER_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_TEST_MOCK_ACCOUNT_MANAGER_H_ - -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/account_manager.h" -#include "internal/platform/implementation/signin_attempt.h" - -namespace nearby { - -class MockAccountManager : public AccountManager { - public: - MOCK_METHOD(std::optional, GetCurrentAccount, (), (override)); - MOCK_METHOD(std::unique_ptr, Login, - (absl::string_view client_id, absl::string_view client_secret), - (override)); - MOCK_METHOD(void, Logout, - (absl::AnyInvocable logout_callback), - (override)); - MOCK_METHOD(bool, GetAccessToken, - (absl::AnyInvocable)> callback), - (override)); - MOCK_METHOD((std::pair), GetOAuthClientCredential, - (), (override)); - MOCK_METHOD(void, AddObserver, (Observer * observer), (override)); - MOCK_METHOD(void, RemoveObserver, (Observer * observer), (override)); - MOCK_METHOD(void, SaveAccountPrefs, - (absl::string_view user_id, absl::string_view client_id, - absl::string_view client_secret), - (override)); -}; - -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_MOCK_ACCOUNT_MANAGER_H_ diff --git a/internal/test/mock_account_observer.h b/internal/test/mock_account_observer.h deleted file mode 100644 index bf4da0e6..00000000 --- a/internal/test/mock_account_observer.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2024 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_TEST_MOCK_ACCOUNT_OBSERVER_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_TEST_MOCK_ACCOUNT_OBSERVER_H_ - -#include "gmock/gmock.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/account_manager.h" - -namespace nearby { - -class MockAccountObserver : public AccountManager::Observer { - public: - ~MockAccountObserver() override = default; - - MOCK_METHOD(void, OnLoginSucceeded, (absl::string_view account_id), - (override)); - - MOCK_METHOD(void, OnLogoutSucceeded, - (absl::string_view account_id, bool credential_error), - (override)); -}; - -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_MOCK_ACCOUNT_OBSERVER_H_ diff --git a/sharing/BUILD b/sharing/BUILD index 6aadfd1e..567b9948 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -382,8 +382,8 @@ cc_library( "//internal/platform:logging", "//internal/platform:mac_address", "//internal/platform:types", - "//internal/platform/implementation:account_manager", "//internal/platform/implementation:types", + "//location/nearby/sharing/lib/account:account_manager", "//location/nearby/sharing/lib/rpc:grpc_async_client_factory", "//location/nearby/sharing/lib/rpc:sharing_rpc_client", "//location/nearby/sharing/lib/sync:sync_manager", @@ -631,9 +631,10 @@ cc_test( "//internal/base:files", "//internal/flags:nearby_flags", "//internal/platform/implementation:platform_impl", - "//internal/platform/implementation:signin_attempt", "//internal/test", - "//internal/test:mocks", + "//location/nearby/sharing/lib/account:fake_account_manager", + "//location/nearby/sharing/lib/account:mock_account_manager", + "//location/nearby/sharing/lib/account:signin_attempt", "//location/nearby/sharing/lib/rpc:fake_nearby_share_client", "//sharing/analytics", "//sharing/certificates", diff --git a/sharing/certificates/BUILD b/sharing/certificates/BUILD index f18cfbd8..0b2a6f1f 100644 --- a/sharing/certificates/BUILD +++ b/sharing/certificates/BUILD @@ -50,7 +50,7 @@ cc_library( "//internal/crypto_cros", "//internal/platform:mac_address", "//internal/platform:types", - "//internal/platform/implementation:account_manager", + "//location/nearby/sharing/lib/account:account_manager", "//location/nearby/sharing/lib/rpc:sharing_rpc_client", "//sharing/internal/api:platform", "//sharing/internal/base", @@ -127,9 +127,9 @@ cc_test( "//google/nearby/identity/v1:resources_cc_proto", "//google/nearby/identity/v1:rpcs_cc_proto", "//internal/platform:mac_address", - "//internal/platform/implementation:account_manager", "//internal/platform/implementation:platform_impl", - "//internal/test", + "//location/nearby/sharing/lib/account:account_manager", + "//location/nearby/sharing/lib/account:fake_account_manager", "//location/nearby/sharing/lib/rpc:fake_nearby_share_client", "//sharing/common:enum", "//sharing/internal/api:mock_sharing_platform", diff --git a/sharing/certificates/nearby_share_certificate_manager_impl.cc b/sharing/certificates/nearby_share_certificate_manager_impl.cc index fe33848a..2fe80bb4 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl.cc +++ b/sharing/certificates/nearby_share_certificate_manager_impl.cc @@ -31,6 +31,7 @@ #include "google/nearby/identity/v1/resources.pb.h" #include "google/nearby/identity/v1/rpcs.pb.h" #include "google/protobuf/timestamp.pb.h" +#include "location/nearby/sharing/lib/account/account_manager.h" #include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" #include "absl/algorithm/algorithm.h" #include "absl/base/nullability.h" @@ -44,7 +45,6 @@ #include "absl/time/time.h" #include "absl/types/span.h" #include "internal/base/file_path.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/mac_address.h" #include "sharing/certificates/common.h" #include "sharing/certificates/constants.h" @@ -72,11 +72,9 @@ #include "sharing/scheduling/nearby_share_scheduler_factory.h" #include "util/hash/highway_fingerprint.h" -namespace nearby { -namespace sharing { +namespace nearby::sharing { namespace { -using ::google::nearby::identity::v1::AccountInfo; using ::google::nearby::identity::v1::GetAccountInfoRequest; using ::google::nearby::identity::v1::GetAccountInfoResponse; using ::google::nearby::identity::v1::PerVisibilitySharedCredentials; @@ -889,8 +887,8 @@ bool NearbyShareCertificateManagerImpl::UpdateAccountInfoInExecutor() { const auto& capabilities = response->account_info().capabilities(); bool has_titanium_capability = (std::find(capabilities.begin(), capabilities.end(), - AccountInfo::CAPABILITY_TITANIUM) != - capabilities.end()); + google::nearby::identity::v1::AccountInfo:: + CAPABILITY_TITANIUM) != capabilities.end()); preference_manager_.SetBoolean(PrefNames::kAdvancedProtectionEnabled, has_titanium_capability); LOG(INFO) << "GetAccountInfo succeeded, advanced protection enabled: " @@ -904,5 +902,4 @@ bool NearbyShareCertificateManagerImpl::UpdateAccountInfoInExecutor() { return get_account_info_succeeded; } -} // namespace sharing -} // namespace nearby +} // namespace nearby::sharing diff --git a/sharing/certificates/nearby_share_certificate_manager_impl.h b/sharing/certificates/nearby_share_certificate_manager_impl.h index 20ad389d..f3ca9a58 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl.h +++ b/sharing/certificates/nearby_share_certificate_manager_impl.h @@ -23,13 +23,13 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" #include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" #include "absl/base/nullability.h" #include "absl/functional/any_invocable.h" #include "absl/status/statusor.h" #include "absl/time/time.h" #include "internal/base/file_path.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/task_runner.h" #include "sharing/certificates/nearby_share_certificate_manager.h" #include "sharing/certificates/nearby_share_certificate_storage.h" @@ -43,8 +43,7 @@ #include "sharing/proto/enums.pb.h" #include "sharing/proto/rpc_resources.pb.h" -namespace nearby { -namespace sharing { +namespace nearby::sharing { class NearbyShareScheduler; @@ -221,7 +220,6 @@ class NearbyShareCertificateManagerImpl std::unique_ptr executor_; }; -} // namespace sharing -} // namespace nearby +} // namespace nearby::sharing #endif // THIRD_PARTY_NEARBY_SHARING_CERTIFICATES_NEARBY_SHARE_CERTIFICATE_MANAGER_IMPL_H_ diff --git a/sharing/certificates/nearby_share_certificate_manager_impl_test.cc b/sharing/certificates/nearby_share_certificate_manager_impl_test.cc index 796c91e0..5db57f16 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl_test.cc +++ b/sharing/certificates/nearby_share_certificate_manager_impl_test.cc @@ -27,6 +27,8 @@ #include "google/nearby/identity/v1/resources.pb.h" #include "google/nearby/identity/v1/rpcs.pb.h" +#include "location/nearby/sharing/lib/account/account_manager.h" +#include "location/nearby/sharing/lib/account/fake_account_manager.h" #include "location/nearby/sharing/lib/rpc/fake_nearby_share_client.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" @@ -37,9 +39,7 @@ #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "absl/types/span.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/mac_address.h" -#include "internal/test/fake_account_manager.h" #include "sharing/certificates/constants.h" #include "sharing/certificates/fake_nearby_share_certificate_storage.h" #include "sharing/certificates/nearby_share_certificate_manager.h" @@ -62,10 +62,8 @@ #include "sharing/scheduling/fake_nearby_share_scheduler_factory.h" #include "sharing/scheduling/nearby_share_scheduler_factory.h" -namespace nearby { -namespace sharing { +namespace nearby::sharing { namespace { -using ::google::nearby::identity::v1::AccountInfo; using ::google::nearby::identity::v1::Device; using ::google::nearby::identity::v1::GetAccountInfoResponse; using ::google::nearby::identity::v1::PublishDeviceRequest; @@ -958,7 +956,7 @@ TEST_F(NearbyShareCertificateManagerImplTest, Initialize(); GetAccountInfoResponse response; response.mutable_account_info()->mutable_capabilities()->Add( - AccountInfo::CAPABILITY_TITANIUM); + google::nearby::identity::v1::AccountInfo::CAPABILITY_TITANIUM); identity_client_.SetGetAccountInfoResponse(response); account_info_update_scheduler_->InvokeRequestCallback(); @@ -990,7 +988,7 @@ TEST_F(NearbyShareCertificateManagerImplTest, preference_manager_.SetBoolean(PrefNames::kAdvancedProtectionEnabled, true); GetAccountInfoResponse response; response.mutable_account_info()->mutable_capabilities()->Add( - AccountInfo::CAPABILITY_UNSPECIFIED); + google::nearby::identity::v1::AccountInfo::CAPABILITY_UNSPECIFIED); identity_client_.SetGetAccountInfoResponse(response); account_info_update_scheduler_->InvokeRequestCallback(); @@ -1015,5 +1013,4 @@ TEST_F(NearbyShareCertificateManagerImplTest, PrefNames::kAdvancedProtectionEnabled, /*default_value=*/false)); } -} // namespace sharing -} // namespace nearby +} // namespace nearby::sharing diff --git a/sharing/contacts/BUILD b/sharing/contacts/BUILD index 61b4807b..0d489e88 100644 --- a/sharing/contacts/BUILD +++ b/sharing/contacts/BUILD @@ -42,7 +42,7 @@ cc_library( deps = [ ":contacts_interface", "//internal/platform:types", - "//internal/platform/implementation:account_manager", + "//location/nearby/sharing/lib/account:account_manager", "//location/nearby/sharing/lib/rpc:sharing_rpc_client", "//sharing/internal/public:logging", "//sharing/internal/public:types", @@ -70,9 +70,9 @@ cc_test( ], deps = [ ":contacts", - "//internal/platform/implementation:account_manager", "//internal/platform/implementation:platform_impl", - "//internal/test", + "//location/nearby/sharing/lib/account:account_manager", + "//location/nearby/sharing/lib/account:fake_account_manager", "//location/nearby/sharing/lib/rpc:fake_nearby_share_client", "//sharing/internal/test:nearby_test", "//sharing/local_device_data:test_support", diff --git a/sharing/contacts/nearby_share_contact_manager_impl.cc b/sharing/contacts/nearby_share_contact_manager_impl.cc index 37c9df39..b0f7834e 100644 --- a/sharing/contacts/nearby_share_contact_manager_impl.cc +++ b/sharing/contacts/nearby_share_contact_manager_impl.cc @@ -23,19 +23,18 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" #include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" #include "absl/base/nullability.h" #include "absl/status/statusor.h" #include "absl/synchronization/notification.h" -#include "internal/platform/implementation/account_manager.h" #include "sharing/contacts/nearby_share_contact_manager.h" #include "sharing/internal/public/context.h" #include "sharing/internal/public/logging.h" #include "sharing/proto/contact_rpc.pb.h" #include "sharing/proto/rpc_resources.pb.h" -namespace nearby { -namespace sharing { +namespace nearby::sharing { namespace { using ::nearby::sharing::proto::ContactRecord; @@ -148,5 +147,4 @@ void NearbyShareContactManagerImpl::GetContacts(ContactsCallback callback) { }); } -} // namespace sharing -} // namespace nearby +} // namespace nearby::sharing diff --git a/sharing/contacts/nearby_share_contact_manager_impl.h b/sharing/contacts/nearby_share_contact_manager_impl.h index 43e23592..16d38f87 100644 --- a/sharing/contacts/nearby_share_contact_manager_impl.h +++ b/sharing/contacts/nearby_share_contact_manager_impl.h @@ -17,15 +17,14 @@ #include +#include "location/nearby/sharing/lib/account/account_manager.h" #include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" #include "absl/base/nullability.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/task_runner.h" #include "sharing/contacts/nearby_share_contact_manager.h" #include "sharing/internal/public/context.h" -namespace nearby { -namespace sharing { +namespace nearby::sharing { class NearbyShareContactManagerImpl : public NearbyShareContactManager { public: @@ -45,7 +44,6 @@ class NearbyShareContactManagerImpl : public NearbyShareContactManager { std::unique_ptr executor_ = nullptr; }; -} // namespace sharing -} // namespace nearby +} // namespace nearby::sharing #endif // THIRD_PARTY_NEARBY_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_IMPL_H_ diff --git a/sharing/contacts/nearby_share_contact_manager_impl_test.cc b/sharing/contacts/nearby_share_contact_manager_impl_test.cc index b2c7da8f..837ceca3 100644 --- a/sharing/contacts/nearby_share_contact_manager_impl_test.cc +++ b/sharing/contacts/nearby_share_contact_manager_impl_test.cc @@ -21,11 +21,11 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" +#include "location/nearby/sharing/lib/account/fake_account_manager.h" #include "location/nearby/sharing/lib/rpc/fake_nearby_share_client.h" #include "gtest/gtest.h" #include "absl/time/time.h" -#include "internal/platform/implementation/account_manager.h" -#include "internal/test/fake_account_manager.h" #include "sharing/internal/test/fake_context.h" #include "sharing/local_device_data/fake_nearby_share_local_device_data_manager.h" #include "sharing/proto/contact_rpc.pb.h" diff --git a/sharing/internal/api/BUILD b/sharing/internal/api/BUILD index 9fb16437..cbb62511 100644 --- a/sharing/internal/api/BUILD +++ b/sharing/internal/api/BUILD @@ -41,7 +41,7 @@ cc_library( "//internal/base:file_path", "//internal/platform:mac_address", "//internal/platform:types", - "//internal/platform/implementation:account_manager", + "//location/nearby/sharing/lib/account:account_manager", "//location/nearby/sharing/lib/sync:sync_binding_prefs_cc_proto", "//location/nearby/sharing/lib/sync:sync_config_prefs_cc_proto", "//sharing/proto:share_cc_proto", @@ -71,7 +71,7 @@ cc_library( "//internal/base:file_path", "//internal/platform:mac_address", "//internal/platform:types", - "//internal/platform/implementation:account_manager", + "//location/nearby/sharing/lib/account:account_manager", "//sharing/analytics", "//sharing/internal/public:logging", "//sharing/proto:share_cc_proto", diff --git a/sharing/internal/api/mock_sharing_platform.h b/sharing/internal/api/mock_sharing_platform.h index b5b64e18..d9e5df2a 100644 --- a/sharing/internal/api/mock_sharing_platform.h +++ b/sharing/internal/api/mock_sharing_platform.h @@ -19,11 +19,11 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" #include "gmock/gmock.h" #include "absl/strings/string_view.h" #include "internal/base/file_path.h" #include "internal/platform/device_info.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/task_runner.h" #include "sharing/internal/api/app_info.h" #include "sharing/internal/api/bluetooth_adapter.h" diff --git a/sharing/internal/api/sharing_platform.h b/sharing/internal/api/sharing_platform.h index d5bab76a..a65ac38f 100644 --- a/sharing/internal/api/sharing_platform.h +++ b/sharing/internal/api/sharing_platform.h @@ -19,10 +19,10 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" #include "absl/strings/string_view.h" #include "internal/base/file_path.h" #include "internal/platform/device_info.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/task_runner.h" #include "sharing/internal/api/app_info.h" #include "sharing/internal/api/bluetooth_adapter.h" diff --git a/sharing/local_device_data/BUILD b/sharing/local_device_data/BUILD index 030085b3..3dbd73cb 100644 --- a/sharing/local_device_data/BUILD +++ b/sharing/local_device_data/BUILD @@ -31,8 +31,8 @@ cc_library( deps = [ "//internal/base", "//internal/platform:types", - "//internal/platform/implementation:account_manager", "//internal/platform/implementation:types", + "//location/nearby/sharing/lib/account:account_manager", "//sharing/common:enum", "//sharing/internal/api:platform", "//sharing/internal/base:utf_utils", @@ -68,9 +68,10 @@ cc_test( ], deps = [ ":local_device_data", - "//internal/platform/implementation:account_manager", "//internal/platform/implementation:platform_impl", "//internal/test", + "//location/nearby/sharing/lib/account:account_manager", + "//location/nearby/sharing/lib/account:fake_account_manager", "//sharing/common", "//sharing/common:enum", "//sharing/internal/test:nearby_test", diff --git a/sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc b/sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc index 80f2ffbb..ad53f866 100644 --- a/sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc +++ b/sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc @@ -21,11 +21,11 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" #include "absl/memory/memory.h" #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" #include "internal/platform/device_info.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/implementation/device_info.h" #include "sharing/common/nearby_share_enums.h" #include "sharing/internal/api/preference_manager.h" @@ -37,8 +37,7 @@ #include "sharing/proto/rpc_resources.pb.h" #include "sharing/proto/timestamp.pb.h" -namespace nearby { -namespace sharing { +namespace nearby::sharing { namespace { using ::nearby::api::DeviceInfo; using ::nearby::sharing::api::PreferenceManager; @@ -164,5 +163,4 @@ std::string NearbyShareLocalDeviceDataManagerImpl::GetDefaultDeviceName() return absl::Substitute(kDefaultDeviceName, truncated_name, device_type); } -} // namespace sharing -} // namespace nearby +} // namespace nearby::sharing diff --git a/sharing/local_device_data/nearby_share_local_device_data_manager_impl.h b/sharing/local_device_data/nearby_share_local_device_data_manager_impl.h index 176b3b94..5231babb 100644 --- a/sharing/local_device_data/nearby_share_local_device_data_manager_impl.h +++ b/sharing/local_device_data/nearby_share_local_device_data_manager_impl.h @@ -18,9 +18,9 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" #include "absl/strings/string_view.h" #include "internal/platform/device_info.h" -#include "internal/platform/implementation/account_manager.h" #include "sharing/common/nearby_share_enums.h" #include "sharing/internal/api/preference_manager.h" #include "sharing/local_device_data/nearby_share_local_device_data_manager.h" diff --git a/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc b/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc index ca3fcdad..047f7182 100644 --- a/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc +++ b/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc @@ -21,11 +21,11 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" +#include "location/nearby/sharing/lib/account/fake_account_manager.h" #include "gtest/gtest.h" #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" -#include "internal/platform/implementation/account_manager.h" -#include "internal/test/fake_account_manager.h" #include "internal/test/fake_device_info.h" #include "sharing/common/nearby_share_enums.h" #include "sharing/common/nearby_share_prefs.h" @@ -118,7 +118,7 @@ class NearbyShareLocalDeviceDataManagerImplTest protected: nearby::FakePreferenceManager preference_manager_; - nearby::FakeAccountManager fake_account_manager_; + FakeAccountManager fake_account_manager_; nearby::FakeDeviceInfo fake_device_info_; std::vector notifications_; std::unique_ptr manager_; diff --git a/sharing/nearby_sharing_service.h b/sharing/nearby_sharing_service.h index 8d1f8a1a..f664367c 100644 --- a/sharing/nearby_sharing_service.h +++ b/sharing/nearby_sharing_service.h @@ -31,12 +31,9 @@ #include "sharing/share_target_discovered_callback.h" #include "sharing/transfer_update_callback.h" -namespace nearby { +namespace nearby::sharing { class AccountManager; - -namespace sharing { - class NearbyNotificationDelegate; class NearbyShareContactManager; @@ -227,7 +224,6 @@ class NearbySharingService { uint16_t alternate_service_uuid) = 0; }; -} // namespace sharing -} // namespace nearby +} // namespace nearby::sharing #endif // THIRD_PARTY_NEARBY_SHARING_NEARBY_SHARING_SERVICE_H_ diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 7749dfda..2ceb0496 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -31,6 +31,7 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" #include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" #include "absl/base/nullability.h" #include "absl/container/flat_hash_map.h" @@ -48,7 +49,6 @@ #include "internal/network/url.h" #include "internal/platform/clock.h" #include "internal/platform/device_info.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/implementation/device_info.h" #include "internal/platform/task_runner.h" #include "proto/sharing_enums.pb.h" diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index 7b17c0e8..d93bc24e 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -27,6 +27,7 @@ #include #include +#include "location/nearby/sharing/lib/account/account_manager.h" #include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" #include "location/nearby/sharing/lib/sync/sync_manager.h" #include "absl/base/nullability.h" @@ -38,7 +39,6 @@ #include "absl/types/span.h" #include "internal/platform/clock.h" #include "internal/platform/device_info.h" -#include "internal/platform/implementation/account_manager.h" #include "internal/platform/task_runner.h" #include "proto/sharing_enums.pb.h" #include "sharing/advertisement.h" @@ -90,7 +90,7 @@ class NearbySharingServiceImpl : public NearbySharingService, public NearbyShareSettings::Observer, public NearbyShareCertificateManager::Observer, - public ::nearby::AccountManager::Observer, + public AccountManager::Observer, public NearbyFastInitiation::Observer, public sharing::api::BluetoothAdapter::Observer, public NearbyConnectionsManager::IncomingConnectionListener, diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index a009f000..aaf1624c 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -30,6 +30,9 @@ #include #include +#include "location/nearby/sharing/lib/account/signin_attempt.h" +#include "location/nearby/sharing/lib/account/fake_account_manager.h" +#include "location/nearby/sharing/lib/account/mock_account_observer.h" #include "location/nearby/sharing/lib/rpc/fake_nearby_share_client.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" @@ -48,11 +51,8 @@ #include "internal/base/file_path.h" #include "internal/base/files.h" #include "internal/flags/nearby_flags.h" -#include "internal/platform/implementation/signin_attempt.h" -#include "internal/test/fake_account_manager.h" #include "internal/test/fake_device_info.h" #include "internal/test/fake_task_runner.h" -#include "internal/test/mock_account_observer.h" #include "sharing/advertisement.h" #include "sharing/advertisement_capabilities.h" #include "sharing/analytics/analytics_recorder.h" @@ -1705,7 +1705,7 @@ TEST_F(NearbySharingServiceImplTest, ForegroundRegisterReceiveSurfaceIsAdvertisingAllContacts) { SetLanConnected(true); SetVisibility(DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS); - ::nearby::AccountManager::Account account; + AccountManager::Account account; account.id = kTestAccountId; account_manager().SetAccount(account); local_device_data_manager()->SetDeviceName(kDeviceName); @@ -1759,7 +1759,7 @@ TEST_F(NearbySharingServiceImplTest, BackgroundRegisterReceiveSurfaceIsAdvertisingSelectedContacts) { SetLanConnected(true); SetVisibility(DeviceVisibility::DEVICE_VISIBILITY_SELECTED_CONTACTS); - ::nearby::AccountManager::Account account; + AccountManager::Account account; account.id = kTestAccountId; account_manager().SetAccount(account); SetVisibility(DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS); @@ -4883,7 +4883,7 @@ TEST_F(NearbySharingServiceImplTest, RemoveIncomingPayloads) { TEST_F(NearbySharingServiceImplTest, NotifyLogoutSucceededWithCredentialError) { TestObserver observer(service_.get()); - ::nearby::AccountManager::Account account; + AccountManager::Account account; account.id = kTestAccountId; account_manager().SetAccount(account); From 3a761eaa68338d4ce071c8f3dab344e519623396 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 6 Mar 2026 16:46:02 -0800 Subject: [PATCH 003/151] internal changes PiperOrigin-RevId: 879877961 --- sharing/nearby_sharing_service_factory.cc | 1 - sharing/nearby_sharing_service_impl.cc | 4 +--- sharing/nearby_sharing_service_impl.h | 5 ++--- sharing/nearby_sharing_service_impl_test.cc | 3 +-- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/sharing/nearby_sharing_service_factory.cc b/sharing/nearby_sharing_service_factory.cc index 63d1ea50..11e595ef 100644 --- a/sharing/nearby_sharing_service_factory.cc +++ b/sharing/nearby_sharing_service_factory.cc @@ -70,7 +70,6 @@ NearbySharingService* NearbySharingServiceFactory::CreateSharingService( nearby_sharing_service_ = std::make_unique( std::move(service_thread), context_.get(), sharing_platform, nearby_identity_client_.get(), - nearby_share_client_.get(), std::move(nearby_connections_manager), std::move(nearby_share_contact_manager), analytics_recorder, supports_file_sync); diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 2ceb0496..cef76c23 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -114,7 +114,6 @@ using ::location::nearby::proto::sharing::OSType; using ::location::nearby::proto::sharing::ResponseToIntroduction; using ::location::nearby::proto::sharing::SessionStatus; using ::nearby::sharing::api::SharingPlatform; -using ::nearby::sharing::api::SharingRpcClient; using ::nearby::sharing::api::IdentityRpcClient; using ::nearby::sharing::proto::DataUsage; using ::nearby::sharing::proto::DeviceVisibility; @@ -238,7 +237,6 @@ NearbySharingServiceImpl::NearbySharingServiceImpl( SharingPlatform& sharing_platform, nearby::sharing::api::IdentityRpcClient* absl_nonnull nearby_identity_client, - nearby::sharing::api::SharingRpcClient* absl_nonnull nearby_share_client, std::unique_ptr nearby_connections_manager, std::unique_ptr contact_manager, analytics::AnalyticsRecorder* analytics_recorder, bool supports_file_sync) @@ -250,7 +248,7 @@ NearbySharingServiceImpl::NearbySharingServiceImpl( analytics_recorder_(*analytics_recorder), supports_file_sync_(supports_file_sync), nearby_connections_manager_(std::move(nearby_connections_manager)), - nearby_share_client_(nearby_share_client), + nearby_identity_client_(nearby_identity_client), local_device_data_manager_( NearbyShareLocalDeviceDataManagerImpl::Factory::Create( preference_manager_, account_manager_, device_info_)), diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index d93bc24e..fc3eeae8 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -106,7 +106,6 @@ class NearbySharingServiceImpl nearby::sharing::api::SharingPlatform& sharing_platform, nearby::sharing::api::IdentityRpcClient* absl_nonnull nearby_identity_client, - nearby::sharing::api::SharingRpcClient* absl_nonnull nearby_share_client, std::unique_ptr nearby_connections_manager, std::unique_ptr contact_manager, analytics::AnalyticsRecorder* analytics_recorder, @@ -418,8 +417,8 @@ class NearbySharingServiceImpl const bool supports_file_sync_; std::unique_ptr nearby_connections_manager_; - nearby::sharing::api::SharingRpcClient* absl_nonnull const - nearby_share_client_; + nearby::sharing::api::IdentityRpcClient* absl_nonnull const + nearby_identity_client_; std::unique_ptr local_device_data_manager_; std::unique_ptr contact_manager_; std::unique_ptr certificate_manager_; diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index aaf1624c..4a12ad4b 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -484,7 +484,7 @@ class NearbySharingServiceImplTest : public testing::Test { std::unique_ptr task_runner) { return std::make_unique( std::move(task_runner), &fake_context_, mock_sharing_platform_, - &nearby_identity_client_, &nearby_share_client_, + &nearby_identity_client_, absl::WrapUnique(fake_nearby_connections_manager_), absl::WrapUnique(contact_manager_), analytics_recorder_.get(), /*supports_file_sync=*/false); @@ -1280,7 +1280,6 @@ class NearbySharingServiceImplTest : public testing::Test { std::queue written_payloads_ ABSL_GUARDED_BY(connection_output_mutex_); FakeNearbyIdentityClient nearby_identity_client_; - FakeNearbyShareClient nearby_share_client_; }; struct ValidSendSurfaceTestData { From 36a84d48a2f520225ce1fb804e8e271a0f06fd2c Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 6 Mar 2026 18:07:53 -0800 Subject: [PATCH 004/151] Add BW upgrade try count and more error codes. PiperOrigin-RevId: 879903045 --- internal/proto/analytics/connections_log.proto | 3 +++ proto/connections_enums.proto | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/internal/proto/analytics/connections_log.proto b/internal/proto/analytics/connections_log.proto index 6dea3e48..1e10edad 100644 --- a/internal/proto/analytics/connections_log.proto +++ b/internal/proto/analytics/connections_log.proto @@ -580,6 +580,9 @@ message ConnectionsLog { // 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; + // The number of times the upgrade attempt is tried. + // This count is reset to 0 when the upgrade is successful. + optional int32 try_count = 14; } // Next Id: 22 diff --git a/proto/connections_enums.proto b/proto/connections_enums.proto index db519643..4c46ce5b 100644 --- a/proto/connections_enums.proto +++ b/proto/connections_enums.proto @@ -1447,6 +1447,11 @@ enum OperationResultCode { DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_HOST_NETWORK_NOT_AVAILABLE = 5058; // Failed to upgrade to high speed medium because no incoming HTTP connection DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_NO_INCOMING_HTTP_CONNECTION = 5059; + // Failed to upgrade to high speed medium because there is no USB device + // connected + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NO_CONNECTED_DEVICE = 5060; + // Failed to upgrade to high speed medium because the upgrade is interrupted + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_INTERRUPTED = 5061; } enum StopAdvertisingReason { From 7381c589c30e09dc785c4ce1f7de3893d7cb228d Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 9 Mar 2026 16:16:52 -0700 Subject: [PATCH 005/151] internal PiperOrigin-RevId: 881087668 --- internal/platform/BUILD | 33 ++++++++++++++++- internal/platform/implementation/apple/BUILD | 1 + .../platform/implementation/windows/BUILD | 37 +++++++++++++++++-- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 88e62b1f..f2a62bf3 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -288,6 +288,38 @@ cc_library( ], ) +cc_library( + name = "tachyon_express_signaling_messenger", + srcs = ["tachyon_express_signaling_messenger.cc"], + hdrs = ["tachyon_express_signaling_messenger.h"], + visibility = [ + "//connections:__subpackages__", + "//internal/platform/implementation:__subpackages__", + "//internal/test:__subpackages__", + "//presence:__subpackages__", + ], + deps = [ + ":base", + ":logging", + ":types", + "//internal/account", + "//internal/platform/implementation:comm", + "//internal/proto:messaging_cc_grpc_proto", + "//internal/proto:tachyon_cc_proto", + "//internal/rpc:utils", + "//location/nearby/sharing/lib/account:account_manager", + "//third_party/grpc:gpr", + "//third_party/grpc:grpc++", + "//util/random:mt_random", + "//util/random:util", + "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/time", + ], +) + cc_library( name = "comm", srcs = [ @@ -343,7 +375,6 @@ cc_library( "@com_google_absl//absl/status", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", - "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", "@com_google_absl//absl/types:optional", ], diff --git a/internal/platform/implementation/apple/BUILD b/internal/platform/implementation/apple/BUILD index 5a292734..141c6ea0 100644 --- a/internal/platform/implementation/apple/BUILD +++ b/internal/platform/implementation/apple/BUILD @@ -107,6 +107,7 @@ objc_library( "//internal/crypto_cros", "//internal/platform:comm", "//internal/platform:logging", + "//internal/platform:tachyon_express_signaling_messenger", "//internal/platform:types", "//internal/proto:tachyon_cc_proto", "//third_party/webrtc/files/stable/webrtc/api/task_queue:default_task_queue_factory", diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index a8357302..e8322555 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -243,6 +243,24 @@ cc_library( ], ) +cc_library( + name = "webrtc", + srcs = ["webrtc.cc"], + hdrs = ["webrtc.h"], + tags = ["windows"], + deps = [ + "//internal/platform:logging", + "//internal/platform:tachyon_express_signaling_messenger", + "//internal/platform/implementation:comm", + "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", + "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/files/stable/webrtc/api:rtc_error", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", + "@com_google_absl//absl/strings", + ], +) + cc_library( name = "windows", srcs = [ @@ -268,7 +286,6 @@ cc_library( "preferences_manager.cc", "preferences_repository.cc", "system_clock.cc", - "webrtc.cc", "wifi_direct_medium.cc", "wifi_direct_server_socket.cc", "wifi_direct_socket.cc", @@ -301,7 +318,6 @@ cc_library( "nearby_server_socket.h", "preferences_manager.h", "preferences_repository.h", - "webrtc.h", "wifi.h", "wifi_direct.h", "wifi_hotspot.h", @@ -436,6 +452,22 @@ cc_proto_library( deps = [":preferences_manager_test_proto"], ) +cc_test( + name = "webrtc_test", + size = "small", + srcs = ["webrtc_test.cc"], + deps = [ + ":webrtc", + "//internal/platform/implementation:comm", + "//internal/platform/implementation:platform_impl", + "//third_party/webrtc/files/stable/webrtc/api:jsep", + "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "impl_test", size = "small", @@ -460,7 +492,6 @@ cc_test( "thread_pool_test.cc", "timer_test.cc", "utils_test.cc", - "webrtc_test.cc", "wifi_direct_test.cc", "wifi_hotspot_test.cc", "wifi_medium_test.cc", From e7da55b383eca852cc2f3cf444e725cba315f25a Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 10 Mar 2026 10:55:56 -0700 Subject: [PATCH 006/151] internal PiperOrigin-RevId: 881520802 --- sharing/internal/api/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/sharing/internal/api/BUILD b/sharing/internal/api/BUILD index cbb62511..f643fd2f 100644 --- a/sharing/internal/api/BUILD +++ b/sharing/internal/api/BUILD @@ -31,6 +31,7 @@ cc_library( "system_info.h", ], visibility = [ + "//internal/account:__pkg__", "//location/nearby/analytics/cpp/logging:__pkg__", "//location/nearby/cpp/sharing:__subpackages__", "//location/nearby/sharing/lib:__subpackages__", From a2249dc07a1382cfafb228f2148efe0cd1a20891 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Tue, 10 Mar 2026 17:54:49 -0700 Subject: [PATCH 007/151] Unpublish existing L2CAP channel before starting a new server. PiperOrigin-RevId: 881707142 --- .../implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.m b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.m index e33f458a..1c53b894 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.m +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.m @@ -86,6 +86,10 @@ static char *const kGNCBLEL2CAPServerQueueLabel = "com.google.nearby.GNCBLEL2CAP _peripheralManager.peripheralDelegate = self; } + if (_PSM > 0) { + GNCLoggerInfo((@"[NEARBY] Unpublish L2CAP channel with PSM: %@"), @(_PSM)); + [_peripheralManager unpublishL2CAPChannel:_PSM]; + } if (_peripheralManager.state == CBManagerStatePoweredOn) { // Bluetooth link is already encrypted, however encryption is not required here to avoid getting // insufficient authentication errors due to initialization order. From c00d7ae4855220a7d6a5b20447d8e46e7048dbab Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Tue, 10 Mar 2026 17:55:16 -0700 Subject: [PATCH 008/151] Implement GNCPeripheralManagerMultiplexer. PiperOrigin-RevId: 881707256 --- .../implementation/apple/Mediums/BLE/BUILD | 2 + .../BLE/GNCPeripheralManagerMultiplexer.h | 49 ++ .../BLE/GNCPeripheralManagerMultiplexer.m | 194 +++++++ .../apple/Mediums/BLE/Tests/BUILD | 1 + .../GNCPeripheralManagerMultiplexerTest.m | 495 ++++++++++++++++++ 5 files changed, 741 insertions(+) create mode 100644 internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.h create mode 100644 internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.m create mode 100644 internal/platform/implementation/apple/Mediums/BLE/Tests/GNCPeripheralManagerMultiplexerTest.m diff --git a/internal/platform/implementation/apple/Mediums/BLE/BUILD b/internal/platform/implementation/apple/Mediums/BLE/BUILD index 2a7a19f8..8f43a4e3 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/BUILD +++ b/internal/platform/implementation/apple/Mediums/BLE/BUILD @@ -39,6 +39,7 @@ objc_library( "GNCMConnection.m", "GNCPeripheral.m", "GNCPeripheralManager.m", + "GNCPeripheralManagerMultiplexer.m", "NSData+GNCBase85.mm", "NSData+GNCWebSafeBase64.m", ], @@ -59,6 +60,7 @@ objc_library( "GNCMConnection.h", "GNCPeripheral.h", "GNCPeripheralManager.h", + "GNCPeripheralManagerMultiplexer.h", "NSData+GNCBase85.h", "NSData+GNCWebSafeBase64.h", ], diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.h b/internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.h new file mode 100644 index 00000000..74129d02 --- /dev/null +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.h @@ -0,0 +1,49 @@ +// Copyright 2026 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. + +#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManager.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * A multiplexer that forwards @c CBPeripheralManagerDelegate and @c GNCPeripheralManagerDelegate + */ +@interface GNCPeripheralManagerMultiplexer : NSObject + +/** + * Initializes the multiplexer. + * + * @param callbackQueue The queue to use for forwarding delegate callbacks. + */ +- (instancetype)initWithCallbackQueue:(dispatch_queue_t)callbackQueue NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Adds a listener to the multiplexer. Listeners are held weakly. + * + * @param listener The listener to add. + */ +- (void)addListener:(id)listener; + +/** + * Removes a listener from the multiplexer. + * + * @param listener The listener to remove. + */ +- (void)removeListener:(id)listener; + +@end + +NS_ASSUME_NONNULL_END diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.m b/internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.m new file mode 100644 index 00000000..56d69774 --- /dev/null +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.m @@ -0,0 +1,194 @@ +// Copyright 2026 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. + +#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.h" + +#import +#import + +#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManager.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation GNCPeripheralManagerMultiplexer { + NSHashTable> *_listeners; + dispatch_queue_t _callbackQueue; + dispatch_queue_t _syncQueue; +} + +- (instancetype)initWithCallbackQueue:(dispatch_queue_t)callbackQueue { + self = [super init]; + if (self) { + _listeners = [NSHashTable weakObjectsHashTable]; + _callbackQueue = callbackQueue; + _syncQueue = dispatch_queue_create("com.google.nearby.GNCPeripheralManagerMultiplexerSync", + DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (instancetype)init { + return [self initWithCallbackQueue:dispatch_get_main_queue()]; +} + +- (void)addListener:(id)listener { + dispatch_async(_syncQueue, ^{ + [self->_listeners addObject:listener]; + }); +} + +- (void)removeListener:(id)listener { + dispatch_async(_syncQueue, ^{ + [self->_listeners removeObject:listener]; + }); +} + +- (NSArray> *)allListeners { + __block NSArray> *listeners; + dispatch_sync(_syncQueue, ^{ + listeners = [self->_listeners allObjects]; + }); + return listeners; +} + +#pragma mark - GNCPeripheralManagerDelegate + +- (void)gnc_peripheralManagerDidUpdateState:(id)peripheral { + NSArray> *listeners = [self allListeners]; + dispatch_async(_callbackQueue, ^{ + for (id listener in listeners) { + [listener gnc_peripheralManagerDidUpdateState:peripheral]; + } + }); +} + +- (void)gnc_peripheralManagerDidStartAdvertising:(id)peripheral + error:(nullable NSError *)error { + NSArray> *listeners = [self allListeners]; + dispatch_async(_callbackQueue, ^{ + for (id listener in listeners) { + if ([listener respondsToSelector:@selector(gnc_peripheralManagerDidStartAdvertising:error:)]) { + [listener gnc_peripheralManagerDidStartAdvertising:peripheral error:error]; + } + } + }); +} + +- (void)gnc_peripheralManager:(id)peripheral + didAddService:(CBService *)service + error:(nullable NSError *)error { + NSArray> *listeners = [self allListeners]; + dispatch_async(_callbackQueue, ^{ + for (id listener in listeners) { + if ([listener respondsToSelector:@selector(gnc_peripheralManager:didAddService:error:)]) { + [listener gnc_peripheralManager:peripheral didAddService:service error:error]; + } + } + }); +} + +- (void)gnc_peripheralManager:(id)peripheral + didReceiveReadRequest:(CBATTRequest *)request { + NSArray> *listeners = [self allListeners]; + dispatch_async(_callbackQueue, ^{ + for (id listener in listeners) { + if ([listener respondsToSelector:@selector(gnc_peripheralManager:didReceiveReadRequest:)]) { + [listener gnc_peripheralManager:peripheral didReceiveReadRequest:request]; + } + } + }); +} + +- (void)gnc_peripheralManager:(id)peripheral + didPublishL2CAPChannel:(CBL2CAPPSM)PSM + error:(nullable NSError *)error { + NSArray> *listeners = [self allListeners]; + dispatch_async(_callbackQueue, ^{ + for (id listener in listeners) { + if ([listener respondsToSelector:@selector(gnc_peripheralManager:didPublishL2CAPChannel:error:)]) { + [listener gnc_peripheralManager:peripheral didPublishL2CAPChannel:PSM error:error]; + } + } + }); +} + +- (void)gnc_peripheralManager:(id)peripheral + didUnpublishL2CAPChannel:(CBL2CAPPSM)PSM + error:(NSError *)error { + NSArray> *listeners = [self allListeners]; + dispatch_async(_callbackQueue, ^{ + for (id listener in listeners) { + if ([listener respondsToSelector:@selector(gnc_peripheralManager:didUnpublishL2CAPChannel:error:)]) { + [listener gnc_peripheralManager:peripheral didUnpublishL2CAPChannel:PSM error:error]; + } + } + }); +} + +- (void)gnc_peripheralManager:(id)peripheral + didOpenL2CAPChannel:(nullable CBL2CAPChannel *)channel + error:(nullable NSError *)error { + NSArray> *listeners = [self allListeners]; + dispatch_async(_callbackQueue, ^{ + for (id listener in listeners) { + if ([listener respondsToSelector:@selector(gnc_peripheralManager:didOpenL2CAPChannel:error:)]) { + [listener gnc_peripheralManager:peripheral didOpenL2CAPChannel:channel error:error]; + } + } + }); +} + +#pragma mark - CBPeripheralManagerDelegate + +- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { + [self gnc_peripheralManagerDidUpdateState:peripheral]; +} + +- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral + error:(nullable NSError *)error { + [self gnc_peripheralManagerDidStartAdvertising:peripheral error:error]; +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + didAddService:(CBService *)service + error:(nullable NSError *)error { + [self gnc_peripheralManager:peripheral didAddService:service error:error]; +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + didReceiveReadRequest:(CBATTRequest *)request { + [self gnc_peripheralManager:peripheral didReceiveReadRequest:request]; +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + didPublishL2CAPChannel:(CBL2CAPPSM)PSM + error:(nullable NSError *)error { + [self gnc_peripheralManager:peripheral didPublishL2CAPChannel:PSM error:error]; +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + didUnpublishL2CAPChannel:(CBL2CAPPSM)PSM + error:(nullable NSError *)error { + [self gnc_peripheralManager:peripheral didUnpublishL2CAPChannel:PSM error:error]; +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + didOpenL2CAPChannel:(nullable CBL2CAPChannel *)channel + error:(nullable NSError *)error { + [self gnc_peripheralManager:peripheral didOpenL2CAPChannel:channel error:error]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD b/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD index 86e1be56..245bf027 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD @@ -44,6 +44,7 @@ objc_library( "GNCMBleUtilsTest.m", "GNCMConnectionsTest.m", "GNCMFakeConnection.mm", + "GNCPeripheralManagerMultiplexerTest.m", "GNCPeripheralManagerTest.m", "GNCPeripheralTest.m", "NSData+GNCBase85Test.m", diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCPeripheralManagerMultiplexerTest.m b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCPeripheralManagerMultiplexerTest.m new file mode 100644 index 00000000..394eb4cc --- /dev/null +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCPeripheralManagerMultiplexerTest.m @@ -0,0 +1,495 @@ +// Copyright 2026 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. + +#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.h" + +#import +#import +#import + +#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManager.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h" + +@interface GNCPeripheralManagerMultiplexerTest : XCTestCase +@end + +@interface FakePeripheralManagerDelegate : NSObject +@property(nonatomic) XCTestExpectation *expectation; +@property(nonatomic) BOOL didUpdateStateCalled; +@property(nonatomic) CBManagerState state; + +@property(nonatomic) BOOL didStartAdvertisingCalled; +@property(nonatomic) NSError *startAdvertisingError; + +@property(nonatomic) BOOL didAddServiceCalled; +@property(nonatomic) CBService *addedService; +@property(nonatomic) NSError *addServiceError; + +@property(nonatomic) BOOL didReceiveReadRequestCalled; +@property(nonatomic) CBATTRequest *readRequest; + +@property(nonatomic) BOOL didPublishL2CAPChannelCalled; +@property(nonatomic) CBL2CAPPSM publishedPSM; +@property(nonatomic) NSError *publishL2CAPChannelError; + +@property(nonatomic) BOOL didUnpublishL2CAPChannelCalled; +@property(nonatomic) CBL2CAPPSM unpublishedPSM; +@property(nonatomic) NSError *unpublishL2CAPChannelError; + +@property(nonatomic) BOOL didOpenL2CAPChannelCalled; +@property(nonatomic) CBL2CAPChannel *openedChannel; +@property(nonatomic) NSError *openL2CAPChannelError; + +@end + +@implementation FakePeripheralManagerDelegate + +- (void)gnc_peripheralManagerDidUpdateState:(id)peripheral { + _didUpdateStateCalled = YES; + _state = peripheral.state; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)gnc_peripheralManagerDidStartAdvertising:(id)peripheral + error:(nullable NSError *)error { + _didStartAdvertisingCalled = YES; + _startAdvertisingError = error; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)gnc_peripheralManager:(id)peripheral + didAddService:(CBService *)service + error:(nullable NSError *)error { + _didAddServiceCalled = YES; + _addedService = service; + _addServiceError = error; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)gnc_peripheralManager:(id)peripheral + didReceiveReadRequest:(CBATTRequest *)request { + _didReceiveReadRequestCalled = YES; + _readRequest = request; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)gnc_peripheralManager:(id)peripheral + didPublishL2CAPChannel:(CBL2CAPPSM)PSM + error:(nullable NSError *)error { + _didPublishL2CAPChannelCalled = YES; + _publishedPSM = PSM; + _publishL2CAPChannelError = error; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)gnc_peripheralManager:(id)peripheral + didUnpublishL2CAPChannel:(CBL2CAPPSM)PSM + error:(NSError *)error { + _didUnpublishL2CAPChannelCalled = YES; + _unpublishedPSM = PSM; + _unpublishL2CAPChannelError = error; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)gnc_peripheralManager:(id)peripheral + didOpenL2CAPChannel:(nullable CBL2CAPChannel *)channel + error:(nullable NSError *)error { + _didOpenL2CAPChannelCalled = YES; + _openedChannel = channel; + _openL2CAPChannelError = error; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)peripheralManagerDidUpdateState:(nonnull CBPeripheralManager *)peripheral { + _didUpdateStateCalled = YES; + _state = peripheral.state; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral + error:(nullable NSError *)error { + _didStartAdvertisingCalled = YES; + _startAdvertisingError = error; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + didAddService:(CBService *)service + error:(nullable NSError *)error { + _didAddServiceCalled = YES; + _addedService = service; + _addServiceError = error; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + didReceiveReadRequest:(CBATTRequest *)request { + _didReceiveReadRequestCalled = YES; + _readRequest = request; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + didPublishL2CAPChannel:(CBL2CAPPSM)PSM + error:(nullable NSError *)error { + _didPublishL2CAPChannelCalled = YES; + _publishedPSM = PSM; + _publishL2CAPChannelError = error; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + didUnpublishL2CAPChannel:(CBL2CAPPSM)PSM + error:(nullable NSError *)error { + _didUnpublishL2CAPChannelCalled = YES; + _unpublishedPSM = PSM; + _unpublishL2CAPChannelError = error; + if (_expectation) { + [_expectation fulfill]; + } +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + didOpenL2CAPChannel:(nullable CBL2CAPChannel *)channel + error:(nullable NSError *)error { + _didOpenL2CAPChannelCalled = YES; + _openedChannel = channel; + _openL2CAPChannelError = error; + if (_expectation) { + [_expectation fulfill]; + } +} + +@end + +@implementation GNCPeripheralManagerMultiplexerTest + +- (void)testMultiplexerForwardsCallbacks { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate1 = [[FakePeripheralManagerDelegate alloc] init]; + FakePeripheralManagerDelegate *delegate2 = [[FakePeripheralManagerDelegate alloc] init]; + + delegate1.expectation = [self expectationWithDescription:@"Delegate 1 called"]; + delegate2.expectation = [self expectationWithDescription:@"Delegate 2 called"]; + + [multiplexer addListener:delegate1]; + [multiplexer addListener:delegate2]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + fakeManager.state = CBManagerStatePoweredOn; + + [multiplexer gnc_peripheralManagerDidUpdateState:fakeManager]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + + XCTAssertTrue(delegate1.didUpdateStateCalled); + XCTAssertTrue(delegate2.didUpdateStateCalled); + XCTAssertEqual(delegate1.state, CBManagerStatePoweredOn); + XCTAssertEqual(delegate2.state, CBManagerStatePoweredOn); +} + +- (void)testMultiplexerRemovesListener { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate1 = [[FakePeripheralManagerDelegate alloc] init]; + + delegate1.expectation = [self expectationWithDescription:@"Delegate 1 called"]; + + [multiplexer addListener:delegate1]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + fakeManager.state = CBManagerStatePoweredOn; + + [multiplexer removeListener:delegate1]; + [multiplexer gnc_peripheralManagerDidUpdateState:fakeManager]; + + // We expect delegate1 NOT to be called. + // Since removals are async, we wait a bit to ensure it had a chance (or didn't). + XCTWaiterResult result = [XCTWaiter waitForExpectations:@[ delegate1.expectation ] timeout:0.5]; + XCTAssertEqual(result, XCTWaiterResultTimedOut); + XCTAssertFalse(delegate1.didUpdateStateCalled); +} + +- (void)testMultiplexerForwardsDidStartAdvertising { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + NSError *error = [NSError errorWithDomain:@"test" code:1 userInfo:nil]; + + [multiplexer gnc_peripheralManagerDidStartAdvertising:fakeManager error:error]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didStartAdvertisingCalled); + XCTAssertEqualObjects(delegate.startAdvertisingError, error); +} + +- (void)testMultiplexerForwardsDidAddService { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + CBMutableService *service = + [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:@"180D"] primary:YES]; + NSError *error = [NSError errorWithDomain:@"test" code:2 userInfo:nil]; + + [multiplexer gnc_peripheralManager:fakeManager didAddService:service error:error]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didAddServiceCalled); + XCTAssertEqualObjects(delegate.addedService, service); + XCTAssertEqualObjects(delegate.addServiceError, error); +} + +- (void)testMultiplexerForwardsDidReceiveReadRequest { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + id request = [NSNull null]; // Use NSNull or any object as placeholder since we can't create + // CBATTRequest + + [multiplexer gnc_peripheralManager:fakeManager didReceiveReadRequest:request]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didReceiveReadRequestCalled); + XCTAssertEqual(delegate.readRequest, request); +} + +- (void)testMultiplexerForwardsDidPublishL2CAPChannel { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + CBL2CAPPSM psm = 42; + NSError *error = [NSError errorWithDomain:@"test" code:3 userInfo:nil]; + + [multiplexer gnc_peripheralManager:fakeManager didPublishL2CAPChannel:psm error:error]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didPublishL2CAPChannelCalled); + XCTAssertEqual(delegate.publishedPSM, psm); + XCTAssertEqualObjects(delegate.publishL2CAPChannelError, error); +} + +- (void)testMultiplexerForwardsDidUnpublishL2CAPChannel { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + CBL2CAPPSM psm = 42; + NSError *error = [NSError errorWithDomain:@"test" code:4 userInfo:nil]; + + [multiplexer gnc_peripheralManager:fakeManager didUnpublishL2CAPChannel:psm error:error]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didUnpublishL2CAPChannelCalled); + XCTAssertEqual(delegate.unpublishedPSM, psm); + XCTAssertEqualObjects(delegate.unpublishL2CAPChannelError, error); +} + +- (void)testMultiplexerForwardsDidOpenL2CAPChannel { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + id channel = [NSNull null]; // Placeholder + NSError *error = [NSError errorWithDomain:@"test" code:5 userInfo:nil]; + + [multiplexer gnc_peripheralManager:fakeManager didOpenL2CAPChannel:channel error:error]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didOpenL2CAPChannelCalled); + XCTAssertEqual(delegate.openedChannel, channel); + XCTAssertEqualObjects(delegate.openL2CAPChannelError, error); +} + +- (void)testCBPeripheralManagerDelegateDidUpdateState { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + fakeManager.state = CBManagerStatePoweredOn; + + [multiplexer peripheralManagerDidUpdateState:(CBPeripheralManager *)fakeManager]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didUpdateStateCalled); + XCTAssertEqual(delegate.state, CBManagerStatePoweredOn); +} + +- (void)testCBPeripheralManagerDelegateDidStartAdvertising { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + NSError *error = [NSError errorWithDomain:@"test" code:10 userInfo:nil]; + + [multiplexer peripheralManagerDidStartAdvertising:(CBPeripheralManager *)fakeManager error:error]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didStartAdvertisingCalled); + XCTAssertEqualObjects(delegate.startAdvertisingError, error); +} + +- (void)testCBPeripheralManagerDelegateDidAddService { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + CBMutableService *service = + [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:@"180F"] primary:YES]; + NSError *error = [NSError errorWithDomain:@"test" code:11 userInfo:nil]; + + [multiplexer peripheralManager:(CBPeripheralManager *)fakeManager didAddService:service error:error]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didAddServiceCalled); + XCTAssertEqualObjects(delegate.addedService, service); + XCTAssertEqualObjects(delegate.addServiceError, error); +} + +- (void)testCBPeripheralManagerDelegateDidReceiveReadRequest { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + id request = [NSNull null]; + + [multiplexer peripheralManager:(CBPeripheralManager *)fakeManager didReceiveReadRequest:request]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didReceiveReadRequestCalled); + XCTAssertEqual(delegate.readRequest, request); +} + +- (void)testCBPeripheralManagerDelegateDidPublishL2CAPChannel { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + CBL2CAPPSM psm = 100; + NSError *error = [NSError errorWithDomain:@"test" code:13 userInfo:nil]; + + [multiplexer peripheralManager:(CBPeripheralManager *)fakeManager + didPublishL2CAPChannel:psm + error:error]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didPublishL2CAPChannelCalled); + XCTAssertEqual(delegate.publishedPSM, psm); + XCTAssertEqualObjects(delegate.publishL2CAPChannelError, error); +} + +- (void)testCBPeripheralManagerDelegateDidUnpublishL2CAPChannel { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + CBL2CAPPSM psm = 101; + NSError *error = [NSError errorWithDomain:@"test" code:14 userInfo:nil]; + + [multiplexer peripheralManager:(CBPeripheralManager *)fakeManager + didUnpublishL2CAPChannel:psm + error:error]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didUnpublishL2CAPChannelCalled); + XCTAssertEqual(delegate.unpublishedPSM, psm); + XCTAssertEqualObjects(delegate.unpublishL2CAPChannelError, error); +} + +- (void)testCBPeripheralManagerDelegateDidOpenL2CAPChannel { + GNCPeripheralManagerMultiplexer *multiplexer = + [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:dispatch_get_main_queue()]; + FakePeripheralManagerDelegate *delegate = [[FakePeripheralManagerDelegate alloc] init]; + delegate.expectation = [self expectationWithDescription:@"Delegate called"]; + [multiplexer addListener:delegate]; + + GNCFakePeripheralManager *fakeManager = [[GNCFakePeripheralManager alloc] init]; + id channel = [NSNull null]; + NSError *error = [NSError errorWithDomain:@"test" code:15 userInfo:nil]; + + [multiplexer peripheralManager:(CBPeripheralManager *)fakeManager + didOpenL2CAPChannel:channel + error:error]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; + XCTAssertTrue(delegate.didOpenL2CAPChannelCalled); + XCTAssertEqual(delegate.openedChannel, channel); + XCTAssertEqualObjects(delegate.openL2CAPChannelError, error); +} + +@end From 7191468a015cee22a48c186f5519dce771b835f3 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 10 Mar 2026 17:59:07 -0700 Subject: [PATCH 009/151] internal changes PiperOrigin-RevId: 881708212 --- sharing/nearby_sharing_service_impl.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index cef76c23..7b215bd8 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -1508,17 +1508,12 @@ NearbySharingServiceImpl::CreateEndpointInfo( ShareTargetType device_type = static_cast(device_info_.GetDeviceType()); - AdvertisementCapabilities capabilities{}; - if (supports_file_sync_ && NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_sharing_feature::kEnableFileSync)) { - capabilities.Add(AdvertisementCapabilities::Capability::kFileSync); - } std::unique_ptr advertisement = Advertisement::NewInstance( std::move(salt), std::move(encrypted_key), device_type, device_name, visibility == DeviceVisibility::DEVICE_VISIBILITY_EVERYONE ? static_cast(GetReceivingVendorId()) : static_cast(BlockedVendorId::kNone), - std::move(capabilities)); + /*capabilities=*/{}); if (advertisement) { return advertisement->ToEndpointInfo(); } else { From dcb69188897b04ea708731ac96bc270752f99aec Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Wed, 11 Mar 2026 08:21:50 -0700 Subject: [PATCH 010/151] Refactor GATT/L2CAP servers to support shared peripheral manager PiperOrigin-RevId: 882024313 --- .../flags/nearby_connections_feature_flags.h | 4 + .../apple/Flags/GNCFeatureFlags.h | 3 + .../apple/Flags/GNCFeatureFlags.mm | 6 + .../apple/Flags/Tests/GNCFeatureFlagsTest.mm | 37 ++ .../apple/Mediums/BLE/GNCBLEGATTServer.h | 15 +- .../apple/Mediums/BLE/GNCBLEGATTServer.m | 51 +- .../apple/Mediums/BLE/GNCBLEL2CAPServer.h | 6 +- .../apple/Mediums/BLE/GNCBLEL2CAPServer.m | 65 ++- .../apple/Mediums/BLE/GNCBLEMedium.m | 42 +- .../apple/Mediums/BLE/Tests/BUILD | 6 +- ...TTServerTest.m => GNCBLEGATTServerTest.mm} | 466 +++++++++++++---- .../Mediums/BLE/Tests/GNCBLEL2CAPServerTest.m | 329 ------------ .../BLE/Tests/GNCBLEL2CAPServerTest.mm | 485 ++++++++++++++++++ .../apple/Tests/ble_medium_test.mm | 4 +- 14 files changed, 1024 insertions(+), 495 deletions(-) rename internal/platform/implementation/apple/Mediums/BLE/Tests/{GNCBLEGATTServerTest.m => GNCBLEGATTServerTest.mm} (60%) delete mode 100644 internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServerTest.m create mode 100644 internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServerTest.mm diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h index 8dbe6dbc..f241106d 100644 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -104,6 +104,10 @@ constexpr auto kMediumMaxAllowedReadBytes = // Disable/Enable refactor of BLE/L2CAP in Nearby Connections SDK. constexpr auto kRefactorBleL2cap = flags::Flag(kConfigPackage, "45737079", false); +// Enable/Disable usage of shared CBPeripheralManager for GATT and L2CAP +// servers. +constexpr auto kEnableSharedPeripheralManager = + flags::Flag(kConfigPackage, "45770787", false); // Set the safe-to-disconnect version. // 0. Disabled all. 1. safe-to-disconnect 2. reserved 3. auto-reconnect // 4. auto-resume 5. non-distance-constraint-recovery 6. payload_ack diff --git a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h index 7d75da5d..e31a9b94 100644 --- a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h +++ b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h @@ -29,4 +29,7 @@ /** Checks whether BLE L2CAP refactor is enabled in the Nearby Connections SDK. */ @property(nonatomic, class, readonly) BOOL refactorBleL2capEnabled; +/** Checks whether shared peripheral manager is enabled in the Nearby Connections SDK. */ +@property(nonatomic, class, readonly) BOOL sharedPeripheralManagerEnabled; + @end diff --git a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm index 548518e8..1955a263 100644 --- a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm +++ b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm @@ -42,4 +42,10 @@ kRefactorBleL2cap); } ++ (BOOL)sharedPeripheralManagerEnabled { + return nearby::NearbyFlags::GetInstance().GetBoolFlag( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager); +} + @end diff --git a/internal/platform/implementation/apple/Flags/Tests/GNCFeatureFlagsTest.mm b/internal/platform/implementation/apple/Flags/Tests/GNCFeatureFlagsTest.mm index 767eebfb..59784339 100644 --- a/internal/platform/implementation/apple/Flags/Tests/GNCFeatureFlagsTest.mm +++ b/internal/platform/implementation/apple/Flags/Tests/GNCFeatureFlagsTest.mm @@ -34,6 +34,13 @@ nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( nearby::connections::config_package_nearby::nearby_connections_feature::kEnableBleL2cap, false); + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature::kRefactorBleL2cap, + false); + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + false); [super tearDown]; } @@ -78,4 +85,34 @@ XCTAssertFalse([GNCFeatureFlags bleL2capEnabled]); } +- (void)testRefactorBleL2capEnabled_WhenFlagIsTrue { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature::kRefactorBleL2cap, + YES); + XCTAssertTrue([GNCFeatureFlags refactorBleL2capEnabled]); +} + +- (void)testRefactorBleL2capEnabled_WhenFlagIsFalse { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature::kRefactorBleL2cap, + NO); + XCTAssertFalse([GNCFeatureFlags refactorBleL2capEnabled]); +} + +- (void)testSharedPeripheralManagerEnabled_WhenFlagIsTrue { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + YES); + XCTAssertTrue([GNCFeatureFlags sharedPeripheralManagerEnabled]); +} + +- (void)testSharedPeripheralManagerEnabled_WhenFlagIsFalse { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + NO); + XCTAssertFalse([GNCFeatureFlags sharedPeripheralManagerEnabled]); +} + @end diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.h b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.h index 1b94731a..5ee0cad3 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.h +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.h @@ -15,6 +15,8 @@ #import #import +#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManager.h" + @class GNCBLEGATTCharacteristic; NS_ASSUME_NONNULL_BEGIN @@ -57,7 +59,18 @@ typedef void (^GNCStopAdvertisingCompletionHandler)(NSError *_Nullable error); * * @note The public APIs of this class are thread safe. */ -@interface GNCBLEGATTServer : NSObject +@interface GNCBLEGATTServer : NSObject + +/** + * Initializes the GATT server. + * + * @param peripheralManager The peripheral manager to use. + * @param queue The queue to use for delegate callbacks and internal operations. + */ +- (instancetype)initWithPeripheralManager:(nullable id)peripheralManager + queue:(nullable dispatch_queue_t)queue; + +- (instancetype)init NS_UNAVAILABLE; /** * Creates a characteristic and adds it to the GATT server. diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.m b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.m index 6193a7ad..1b9035ad 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.m +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.m @@ -59,30 +59,33 @@ static const int kMaxAdvertisementLengthOnIOS = 23; NSDictionary *_advertisementData; } -- (instancetype)init { +- (instancetype)initWithPeripheralManager:(nullable id)peripheralManager + queue:(nullable dispatch_queue_t)queue { self = [super init]; if (self) { - _queue = dispatch_queue_create(kGNCBLEGATTServerQueueLabel, DISPATCH_QUEUE_SERIAL); - _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:nil queue:_queue]; - // Set for @c GNCPeripheralManager to be able to forward callbacks. - _peripheralManager.peripheralDelegate = self; - _services = [[NSMutableDictionary alloc] init]; - _pendingCharacteristics = [[NSMutableDictionary alloc] init]; - _characteristicValues = [[NSMutableDictionary alloc] init]; - _advertisementData = nil; - } - return self; -} + _queue = queue ?: dispatch_queue_create(kGNCBLEGATTServerQueueLabel, DISPATCH_QUEUE_SERIAL); + if (GNCFeatureFlags.sharedPeripheralManagerEnabled) { + if (!peripheralManager) { + // In shared mode, the peripheral manager must be injected. + [NSException raise:NSInvalidArgumentException + format:@"Peripheral manager cannot be nil when shared manager is enabled."]; + } + _peripheralManager = peripheralManager; + // In shared mode, do NOT set the delegate. The Multiplexer handles callbacks. + } else { + // Legacy mode: Create a new manager if one isn't provided. + if (!peripheralManager) { + peripheralManager = [[CBPeripheralManager alloc] + initWithDelegate:self + queue:_queue + options:@{CBPeripheralManagerOptionShowPowerAlertKey : @NO}]; + } + _peripheralManager = peripheralManager; + // In legacy mode, we own the manager (or use the injected one as if we own it) and set the + // delegate. + _peripheralManager.peripheralDelegate = self; + } -// This is private and should only be used for tests. The provided peripheral manager must call -// delegate methods on the main queue. -- (instancetype)initWithPeripheralManager:(nullable id)peripheralManager { - self = [super init]; - if (self) { - _queue = dispatch_get_main_queue(); - _peripheralManager = peripheralManager; - // Set for @c GNCPeripheralManager to be able to forward callbacks. - _peripheralManager.peripheralDelegate = self; _services = [[NSMutableDictionary alloc] init]; _pendingCharacteristics = [[NSMutableDictionary alloc] init]; _characteristicValues = [[NSMutableDictionary alloc] init]; @@ -342,6 +345,12 @@ static const int kMaxAdvertisementLengthOnIOS = 23; - (void)gnc_peripheralManager:(id)peripheral didReceiveReadRequest:(CBATTRequest *)request { dispatch_assert_queue(_queue); + if (!_services[request.characteristic.service.UUID]) { + // This server does not own the requested service. Ignore the request to allow other listeners + // (or future listeners) to handle it. + return; + } + NSData *value = _characteristicValues[request.characteristic.service.UUID][request.characteristic.UUID]; if (!value) { diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.h b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.h index be602889..285bb0ce 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.h +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.h @@ -15,6 +15,8 @@ #import #import +#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManager.h" + @class GNCBLEL2CAPStream; @protocol GNCPeripheralManager; @@ -42,7 +44,7 @@ typedef void (^GNCOpenL2CAPServerChannelOpendCompletionHandler)(GNCBLEL2CAPStrea * * @note The public APIs of this class are thread safe. */ -@interface GNCBLEL2CAPServer : NSObject +@interface GNCBLEL2CAPServer : NSObject // Represents a PSM (Protocol/Service Multiplexer) value for an L2CAP channel. @property(atomic, readonly) CBL2CAPPSM PSM; @@ -57,6 +59,8 @@ typedef void (^GNCOpenL2CAPServerChannelOpendCompletionHandler)(GNCBLEL2CAPStrea - (instancetype)initWithPeripheralManager:(nullable id)peripheralManager queue:(nullable dispatch_queue_t)queue; +- (instancetype)init NS_UNAVAILABLE; + /** * Starts listening for an L2CAP channel. * diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.m b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.m index 1c53b894..31065d9f 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.m +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.m @@ -17,6 +17,7 @@ #import #import +#import "internal/platform/implementation/apple/Flags/GNCFeatureFlags.h" #import "internal/platform/implementation/apple/Log/GNCLogger.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEError.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPStream.h" @@ -43,21 +44,25 @@ static char *const kGNCBLEL2CAPServerQueueLabel = "com.google.nearby.GNCBLEL2CAP BOOL _alreadyStartedWhenPeripheralPoweredOff; } -- (instancetype)init { - return [self initWithPeripheralManager:nil queue:nil]; -} - -// This is private and should only be used for tests. The provided peripheral manager must call -// delegate methods on the main queue. - (instancetype)initWithPeripheralManager:(nullable id)peripheralManager queue:(nullable dispatch_queue_t)queue { self = [super init]; if (self) { _queue = queue ?: dispatch_queue_create(kGNCBLEL2CAPServerQueueLabel, DISPATCH_QUEUE_SERIAL); - if (peripheralManager) { + if (GNCFeatureFlags.sharedPeripheralManagerEnabled) { + if (!peripheralManager) { + // In shared mode, the peripheral manager must be injected. + [NSException raise:NSInvalidArgumentException + format:@"Peripheral manager cannot be nil when shared manager is enabled."]; + } _peripheralManager = peripheralManager; - // Set for @c GNCPeripheralManager to be able to forward callbacks. - _peripheralManager.peripheralDelegate = self; + // In shared mode, do NOT set the delegate. The Multiplexer handles callbacks. + } else { + if (peripheralManager) { + _peripheralManager = peripheralManager; + // Set for @c GNCPeripheralManager to be able to forward callbacks. + _peripheralManager.peripheralDelegate = self; + } } } return self; @@ -70,20 +75,36 @@ static char *const kGNCBLEL2CAPServerQueueLabel = "com.google.nearby.GNCBLEL2CAP channelOpenedCompletionHandler { _psmPublishedCompletionHandler = [psmPublishedCompletionHandler copy]; _channelOpenedCompletionHandler = [channelOpenedCompletionHandler copy]; - if (!_queue) { - _psmPublishedCompletionHandler(0, [NSError errorWithDomain:GNCBLEErrorDomain - code:GNCBLEErrorL2CAPListeningOnQueueNil - userInfo:nil]); - return; - } - if (!_peripheralManager) { - // Lazy initialization to avoid system dialog on app startup before pairing. - _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:nil - queue:_queue - options:nil]; + if (GNCFeatureFlags.sharedPeripheralManagerEnabled) { + if (!_queue) { + if (_psmPublishedCompletionHandler) { + _psmPublishedCompletionHandler(0, + [NSError errorWithDomain:GNCBLEErrorDomain + code:GNCBLEErrorL2CAPListeningOnQueueNil + userInfo:nil]); + } + return; + } + if (!_peripheralManager) { + GNCLoggerError(@"[NEARBY] Peripheral manager must not be nil."); + return; + } + } else { + if (!_queue) { + _psmPublishedCompletionHandler(0, [NSError errorWithDomain:GNCBLEErrorDomain + code:GNCBLEErrorL2CAPListeningOnQueueNil + userInfo:nil]); + return; + } + if (!_peripheralManager) { + // Lazy initialization to avoid system dialog on app startup before pairing. + _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:nil + queue:_queue + options:nil]; - // Set for @c GNCPeripheralManager to be able to forward callbacks. - _peripheralManager.peripheralDelegate = self; + // Set for @c GNCPeripheralManager to be able to forward callbacks. + _peripheralManager.peripheralDelegate = self; + } } if (_PSM > 0) { diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m index a6276c3c..b4ab5364 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m @@ -40,16 +40,6 @@ static NSError *AlreadyScanningError() { return [NSError errorWithDomain:GNCBLEErrorDomain code:GNCBLEErrorAlreadyScanning userInfo:nil]; } -static GNCBLEL2CAPServer *_Nonnull CreateL2CapServer( - id _Nullable peripheralManager) { - if (!peripheralManager) { - return [[GNCBLEL2CAPServer alloc] init]; - } else { - return [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:peripheralManager - queue:dispatch_get_main_queue()]; - } -} - @interface GNCBLEMedium () @end @@ -164,7 +154,16 @@ static GNCBLEL2CAPServer *_Nonnull CreateL2CapServer( completionHandler:(nullable GNCStartAdvertisingCompletionHandler)completionHandler { dispatch_async(_queue, ^{ if (!_server) { - _server = [[GNCBLEGATTServer alloc] init]; + if (GNCFeatureFlags.sharedPeripheralManagerEnabled) { + // TODO (edwinwu): Implement shared peripheral manager. + // For now, raise an exception. + [NSException raise:NSInvalidArgumentException + format:@"Not implemented for shared manager is enabled."]; + } else { + // In legacy mode, we pass nil (or a separate manager) and do NOT add to multiplexer. + // GNCBLEGATTServer will create its own internal manager. + _server = [[GNCBLEGATTServer alloc] initWithPeripheralManager:nil queue:nil]; + } } [_server startAdvertisingData:serviceData completionHandler:completionHandler]; }); @@ -238,7 +237,14 @@ static GNCBLEL2CAPServer *_Nonnull CreateL2CapServer( (nullable GNCGATTServerCompletionHandler)completionHandler { dispatch_async(_queue, ^{ if (!_server) { - _server = [[GNCBLEGATTServer alloc] init]; + if (GNCFeatureFlags.sharedPeripheralManagerEnabled) { + // TODO (edwinwu): Implement shared peripheral manager. + // For now, raise an exception. + [NSException raise:NSInvalidArgumentException + format:@"Not implemented for shared manager is enabled."]; + } else { + _server = [[GNCBLEGATTServer alloc] initWithPeripheralManager:nil queue:nil]; + } } if (completionHandler) { completionHandler(_server, nil); @@ -284,7 +290,17 @@ static GNCBLEL2CAPServer *_Nonnull CreateL2CapServer( (nullable id)peripheralManager { dispatch_async(_queue, ^{ if (!_l2capServer) { - _l2capServer = CreateL2CapServer(peripheralManager); + if (GNCFeatureFlags.sharedPeripheralManagerEnabled) { + // TODO (edwinwu): Implement shared peripheral manager. + // For now, raise an exception. + [NSException raise:NSInvalidArgumentException + format:@"Not implemented for shared manager is enabled."]; + } else { + // Legacy mode + _l2capServer = [[GNCBLEL2CAPServer alloc] + initWithPeripheralManager:peripheralManager // Likely nil, so Server creates new one + queue:peripheralManager ? dispatch_get_main_queue() : nil]; + } } [_l2capServer startListeningChannelWithPSMPublishedCompletionHandler:psmPublishedCompletionHandler diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD b/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD index 245bf027..2f6066a3 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD @@ -26,11 +26,11 @@ objc_library( srcs = [ "GNCBLEGATTCharacteristicTest.mm", "GNCBLEGATTClientTest.m", - "GNCBLEGATTServerTest.m", + "GNCBLEGATTServerTest.mm", "GNCBLEL2CAPClientTest.m", "GNCBLEL2CAPConnectionTest.m", "GNCBLEL2CAPFakeInputOutputStream.m", - "GNCBLEL2CAPServerTest.m", + "GNCBLEL2CAPServerTest.mm", "GNCBLEL2CAPStreamTest.m", "GNCBLEMediumTest.m", "GNCFakeBLEGATTServer.m", @@ -67,6 +67,8 @@ objc_library( "GNCMFakeConnection.h", ], deps = [ + "//connections/implementation/flags:connections_flags", + "//internal/flags:nearby_flags", "//internal/platform/implementation/apple", # buildcleaner: keep "//internal/platform/implementation/apple/Mediums/BLE", "//internal/platform/implementation/apple/Mediums/BLE/Sockets:Shared", diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEGATTServerTest.m b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEGATTServerTest.mm similarity index 60% rename from internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEGATTServerTest.m rename to internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEGATTServerTest.mm index f6bfac51..8e4882fd 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEGATTServerTest.m +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEGATTServerTest.mm @@ -22,6 +22,9 @@ #import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEGATTServer+Testing.h" #import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h" +#include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "internal/flags/nearby_flags.h" + static NSString *const kServiceUUID1 = @"0000FEF3-0000-1000-8000-00805F9B34FB"; static NSString *const kServiceUUID2 = @"0000FEF4-0000-1000-8000-00805F9B34FB"; static NSString *const kCharacteristicUUID1 = @"00000000-0000-3000-8000-000000000000"; @@ -34,11 +37,60 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 #pragma mark - Create Characteristic -- (void)testCreateCharacteristic { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; +- (void)tearDown { + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); + [super tearDown]; +} - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; +- (void)testInit_setsDelegateCorrectlyBasedOnFlag { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEGATTServer *server = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + + if (enabled.boolValue) { + // In shared mode, functionality is delegated to the multiplexer, so the server should NOT + // self-assign as delegate. + XCTAssertNil(fakePeripheralManager.peripheralDelegate); + } else { + // In legacy mode, the server owns the manager and sets itself as delegate. + XCTAssertEqual(fakePeripheralManager.peripheralDelegate, server); + } + } +} + +- (void)testInit_throwsWithNilManagerWhenFlagEnabled { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + true); + + XCTAssertThrowsSpecificNamed( + [[GNCBLEGATTServer alloc] initWithPeripheralManager:(id)nil + queue:dispatch_get_main_queue()], + NSException, NSInvalidArgumentException); +} + +- (void)testCreateCharacteristic { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -62,13 +114,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testCreateMultipleCharacteristicsForOneService { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -105,13 +167,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 [self waitForExpectations:@[ expectation1, expectation2 ] timeout:3]; XCTAssertEqual(fakePeripheralManager.services.count, 1); XCTAssertEqual(fakePeripheralManager.services[0].characteristics.count, 2); + } } - (void)testCreateDuplicateCharacteristics { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -140,13 +212,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 [self waitForExpectations:@[ expectation ] timeout:3]; XCTAssertEqual(fakePeripheralManager.services.count, 1); XCTAssertEqual(fakePeripheralManager.services[0].characteristics.count, 1); + } } - (void)testCreateDuplicatePendingCharacteristics { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"Create characteristic."]; @@ -171,13 +253,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testCreateCharacteristicNotPoweredOn { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"Create characteristic."]; @@ -198,13 +290,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testCreateCharacteristicServiceFailure { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } fakePeripheralManager.didAddServiceError = [NSError errorWithDomain:@"fake" code:0 userInfo:nil]; [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -228,15 +330,25 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } #pragma mark - Read Request - (void)testReadRequest { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -265,14 +377,24 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 characteristic:characteristicUUID]; [self waitForExpectations:@[ fakePeripheralManager.respondToRequestSuccessExpectation ] - timeout:0]; + timeout:3]; + } } -- (void)testReadRequestInvalidService { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; +- (void)testReadRequestInvalidCharacteristic { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -296,73 +418,106 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 [self waitForExpectations:@[ expectation ] timeout:3]; + CBUUID *invalidCharacteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID2]; + + [fakePeripheralManager + simulatePeripheralManagerDidReceiveReadRequestForService:serviceUUID + characteristic:invalidCharacteristicUUID]; + + [self waitForExpectations:@[ fakePeripheralManager.respondToRequestErrorExpectation ] timeout:3]; + } +} + +- (void)testReadRequestInvalidService { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } + + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; + + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"Create characteristic."]; + + CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1]; + CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1]; + [gattServer createCharacteristicWithServiceID:serviceUUID + characteristicUUID:characteristicUUID + permissions:CBAttributePermissionsReadable + properties:CBCharacteristicPropertyRead + completionHandler:^(GNCBLEGATTCharacteristic *characteristic, + NSError *error) { + [expectation fulfill]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:3]; + CBUUID *invalidServiceUUID = [CBUUID UUIDWithString:kServiceUUID2]; + // Expectation that we *should not* receive a response. + fakePeripheralManager.respondToRequestSuccessExpectation.inverted = YES; + fakePeripheralManager.respondToRequestErrorExpectation.inverted = YES; + [fakePeripheralManager simulatePeripheralManagerDidReceiveReadRequestForService:invalidServiceUUID characteristic:characteristicUUID]; - [self waitForExpectations:@[ fakePeripheralManager.respondToRequestErrorExpectation ] timeout:0]; -} - -- (void)testReadRequestInvalidCharacteristic { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; - - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; - - XCTestExpectation *expectation = - [[XCTestExpectation alloc] initWithDescription:@"Create and update characteristic."]; - - CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1]; - CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1]; - [gattServer createCharacteristicWithServiceID:serviceUUID - characteristicUUID:characteristicUUID - permissions:CBAttributePermissionsReadable - properties:CBCharacteristicPropertyRead - completionHandler:^(GNCBLEGATTCharacteristic *characteristic, - NSError *error) { - [gattServer updateCharacteristic:characteristic - value:[NSData data] - completionHandler:^(NSError *error) { - [expectation fulfill]; - }]; - }]; - - [self waitForExpectations:@[ expectation ] timeout:3]; - - CBUUID *invalidCharacteristicUUID = - [CBUUID UUIDWithString:kCharacteristicUUID2]; - - [fakePeripheralManager - simulatePeripheralManagerDidReceiveReadRequestForService:serviceUUID - characteristic:invalidCharacteristicUUID]; - - [self waitForExpectations:@[ fakePeripheralManager.respondToRequestErrorExpectation ] timeout:0]; + [self waitForExpectations:@[ + fakePeripheralManager.respondToRequestSuccessExpectation, + fakePeripheralManager.respondToRequestErrorExpectation + ] + timeout:3]; + } } #pragma mark - Stop - (void)testStop { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } - [gattServer stop]; + [gattServer stop]; - XCTAssertEqual(fakePeripheralManager.services.count, 0); + XCTAssertEqual(fakePeripheralManager.services.count, 0); + } } #pragma mark - Start Advertising - (void)testStartAdvertisingNoServiceData { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -377,13 +532,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testStartAdvertisingEmptyServiceData { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -402,13 +567,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testStartAdvertisingShortServiceData { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -429,13 +604,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testStartAdvertising20ByteServiceData { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -457,13 +642,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testStartAdvertisingLongServiceData { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -482,13 +677,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testStartAdvertisingWithEmojiServiceData { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -510,13 +715,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testStartAdvertisingMultipleServices { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -536,13 +751,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testStartAdvertisingNotPoweredOn { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"Start advertising."]; @@ -556,13 +781,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testStartAdvertisingStartFailure { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } fakePeripheralManager.didStartAdvertisingError = [NSError errorWithDomain:@"fake" code:0 @@ -581,13 +816,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testStartAdvertisingAlreadyAdvertising { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } fakePeripheralManager.didStartAdvertisingError = [NSError errorWithDomain:@"fake" code:0 @@ -608,13 +853,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } - (void)testStartStopStartAdvertising { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEGATTServer *gattServer = - [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager]; + GNCBLEGATTServer *gattServer = + [[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = gattServer; + } [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; @@ -648,6 +903,9 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000 }]; [self waitForExpectations:@[ expectation ] timeout:3]; + } } @end + + diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServerTest.m b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServerTest.m deleted file mode 100644 index 2380d287..00000000 --- a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServerTest.m +++ /dev/null @@ -1,329 +0,0 @@ -// 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. - -#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.h" - -#import -#import -#import - -#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServer+Testing.h" -#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h" - -static const NSTimeInterval kTestTimeout = 1.0; - -@interface GNCBLEL2CAPServerTest : XCTestCase -@end - -@implementation GNCBLEL2CAPServerTest - -#pragma mark Tests - -- (void)testInit { - GNCBLEL2CAPServer *l2capServer = [[GNCBLEL2CAPServer alloc] init]; - XCTAssertNotNil(l2capServer); - XCTAssertNil([l2capServer valueForKey:@"_peripheralManager"]); -} - -- (void)testPublishL2CAPChannelAndOpenChannelWhenStartListeningChannel { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - XCTestExpectation *psmPublishedExpectation = - [[XCTestExpectation alloc] initWithDescription:@"PSM published."]; - XCTestExpectation *channelOpenedexpectation = - [[XCTestExpectation alloc] initWithDescription:@"Channel opened."]; - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; - - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - XCTAssertEqual(error, nil); - XCTAssertEqual(PSM, fakePeripheralManager.PSM); - [psmPublishedExpectation fulfill]; - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error) { - XCTAssertNil(error); - XCTAssertNotNil(stream); - [channelOpenedexpectation fulfill]; - }]; - [self waitForExpectations:@[ psmPublishedExpectation, channelOpenedexpectation ] - timeout:kTestTimeout]; - XCTAssertNotNil([l2capServer valueForKey:@"l2CAPChannel"]); - XCTAssertNotNil([l2capServer valueForKey:@"l2CAPStream"]); -} - -- (void)testFailedToPublishL2CAPChannel { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - fakePeripheralManager.didPublishL2CAPChannelError = [NSError errorWithDomain:@"fake" - code:0 - userInfo:nil]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - XCTestExpectation *psmPublishedExpectation = - [[XCTestExpectation alloc] initWithDescription:@"PSM published with error."]; - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; - - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - XCTAssertEqual(error, fakePeripheralManager.didPublishL2CAPChannelError); - XCTAssertEqual(PSM, 0); - [psmPublishedExpectation fulfill]; - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error){ - }]; - [self waitForExpectations:@[ psmPublishedExpectation ] timeout:kTestTimeout]; -} - -- (void)testPoweredOffUnpublishesChannel { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; - - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - XCTAssertEqual(error, nil); - XCTAssertEqual(PSM, fakePeripheralManager.PSM); - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error){ - }]; - - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOff]; - - [self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout]; -} - -- (void)testPeripheralManagerDidUpdateStatePoweredOffUnpublishesChannel { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - fakePeripheralManager.state = CBManagerStatePoweredOn; - [(id)l2capServer - peripheralManagerDidUpdateState:(CBPeripheralManager *)fakePeripheralManager]; - - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - XCTAssertEqual(error, nil); - XCTAssertEqual(PSM, fakePeripheralManager.PSM); - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error){ - }]; - - fakePeripheralManager.state = CBManagerStatePoweredOff; - [(id)l2capServer - peripheralManagerDidUpdateState:(CBPeripheralManager *)fakePeripheralManager]; - - [self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout]; -} - -- (void)testStartPeripheralManagerInitiallyOff { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - XCTestExpectation *psmPublishedExpectation = - [[XCTestExpectation alloc] initWithDescription:@"PSM published."]; - XCTestExpectation *channelOpenedexpectation = - [[XCTestExpectation alloc] initWithDescription:@"Channel opened."]; - - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - XCTAssertEqual(error, nil); - XCTAssertEqual(PSM, fakePeripheralManager.PSM); - [psmPublishedExpectation fulfill]; - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error) { - [channelOpenedexpectation fulfill]; - }]; - - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; - [self waitForExpectations:@[ psmPublishedExpectation, channelOpenedexpectation ] - timeout:kTestTimeout]; -} - -- (void)testClose { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; - - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - XCTAssertEqual(error, nil); - XCTAssertEqual(PSM, fakePeripheralManager.PSM); - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error){ - }]; - - [l2capServer close]; - - XCTAssertEqual([l2capServer PSM], 0); -} - -- (void)testCloseDoesNotUnpublishesChannelIfNotConnected { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - fakePeripheralManager.unpublishExpectation.inverted = YES; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - - [l2capServer close]; - - [self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout]; -} - -- (void)testFailedToOpenL2CAPChannel { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - fakePeripheralManager.didOpenL2CAPChannelError = [NSError errorWithDomain:@"fake" - code:0 - userInfo:nil]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - XCTestExpectation *channelOpenedexpectation = - [[XCTestExpectation alloc] initWithDescription:@"Channel opened."]; - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; - - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - XCTAssertEqual(error, nil); - XCTAssertEqual(PSM, fakePeripheralManager.PSM); - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error) { - XCTAssertNil(stream); - XCTAssertEqual(error, fakePeripheralManager.didOpenL2CAPChannelError); - [channelOpenedexpectation fulfill]; - }]; - [self waitForExpectations:@[ channelOpenedexpectation ] timeout:kTestTimeout]; - XCTAssertNil([l2capServer valueForKey:@"l2CAPChannel"]); - XCTAssertNil([l2capServer valueForKey:@"l2CAPStream"]); -} - -- (void)testPeripheralManagerDidUnpublishL2CAPChannel { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error){ - }]; - - [(id)l2capServer - peripheralManager:(CBPeripheralManager *)fakePeripheralManager - didUnpublishL2CAPChannel:l2capServer.PSM - error:[NSError errorWithDomain:@"fake" code:0 userInfo:nil]]; - - XCTAssertEqual(l2capServer.PSM, 0); -} - -- (void)testCloseL2CAPChannel { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - XCTestExpectation *channelOpenedexpectation = - [[XCTestExpectation alloc] initWithDescription:@"Channel opened."]; - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error) { - [channelOpenedexpectation fulfill]; - }]; - [self waitForExpectations:@[ channelOpenedexpectation ] timeout:kTestTimeout]; - - [l2capServer closeL2CAPChannel]; - - XCTAssertNil([l2capServer valueForKey:@"l2CAPChannel"]); - XCTAssertNil([l2capServer valueForKey:@"l2CAPStream"]); -} - -- (void)testPeripheralManagerDidPublishL2CAPChannel { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - XCTestExpectation *expectation = - [[XCTestExpectation alloc] initWithDescription:@"completion called"]; - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - XCTAssertEqual(PSM, 1); - XCTAssertNil(error); - [expectation fulfill]; - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error){ - }]; - [(id)l2capServer - peripheralManager:(CBPeripheralManager *)fakePeripheralManager - didPublishL2CAPChannel:1 - error:nil]; - [self waitForExpectations:@[ expectation ] timeout:kTestTimeout]; - XCTAssertEqual(l2capServer.PSM, 1); -} - -- (void)testPeripheralManagerDidPublishL2CAPChannelWithError { - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEL2CAPServer *l2capServer = - [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; - XCTestExpectation *expectation = - [[XCTestExpectation alloc] initWithDescription:@"completion called"]; - NSError *publishError = [NSError errorWithDomain:@"test" code:0 userInfo:nil]; - [l2capServer - startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, - NSError *_Nullable error) { - XCTAssertEqual(PSM, 0); - XCTAssertEqualObjects(error, publishError); - [expectation fulfill]; - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, - NSError *_Nullable error){ - }]; - [(id)l2capServer - peripheralManager:(CBPeripheralManager *)fakePeripheralManager - didPublishL2CAPChannel:0 - error:publishError]; - [self waitForExpectations:@[ expectation ] timeout:kTestTimeout]; - XCTAssertEqual(l2capServer.PSM, 0); -} - -@end diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServerTest.mm b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServerTest.mm new file mode 100644 index 00000000..2d2fabda --- /dev/null +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServerTest.mm @@ -0,0 +1,485 @@ +// 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. + +#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.h" + +#import +#import +#import + +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServer+Testing.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h" + +#include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "internal/flags/nearby_flags.h" + +static const NSTimeInterval kTestTimeout = 1.0; + +@interface GNCBLEL2CAPServerTest : XCTestCase +@end + +@implementation GNCBLEL2CAPServerTest + +#pragma mark Tests + +- (void)tearDown { + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); + [super tearDown]; +} + +- (void)testInit_setsDelegateCorrectlyBasedOnFlag { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEL2CAPServer *server = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + + if (enabled.boolValue) { + // In shared mode, functionality is delegated to the multiplexer, so the server should NOT + // self-assign as delegate. + XCTAssertNil(fakePeripheralManager.peripheralDelegate); + } else { + // In legacy mode, the server owns the manager and sets itself as delegate. + XCTAssertEqual(fakePeripheralManager.peripheralDelegate, server); + } + } +} + +- (void)testInit_throwsWithNilManagerWhenFlagEnabled { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + true); + + XCTAssertThrowsSpecificNamed( + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:(id)nil + queue:dispatch_get_main_queue()], + NSException, NSInvalidArgumentException); +} + +- (void)testPublishL2CAPChannelAndOpenChannelWhenStartListeningChannel { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + XCTestExpectation *psmPublishedExpectation = + [[XCTestExpectation alloc] initWithDescription:@"PSM published."]; + XCTestExpectation *channelOpenedexpectation = + [[XCTestExpectation alloc] initWithDescription:@"Channel opened."]; + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; + + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + XCTAssertEqual(error, nil); + XCTAssertEqual(PSM, fakePeripheralManager.PSM); + [psmPublishedExpectation fulfill]; + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error) { + XCTAssertNil(error); + XCTAssertNotNil(stream); + [channelOpenedexpectation fulfill]; + }]; + [self waitForExpectations:@[ psmPublishedExpectation, channelOpenedexpectation ] + timeout:kTestTimeout]; + XCTAssertNotNil([l2capServer valueForKey:@"l2CAPChannel"]); + XCTAssertNotNil([l2capServer valueForKey:@"l2CAPStream"]); + } +} + +- (void)testFailedToPublishL2CAPChannel { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + fakePeripheralManager.didPublishL2CAPChannelError = [NSError errorWithDomain:@"fake" + code:0 + userInfo:nil]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + XCTestExpectation *psmPublishedExpectation = + [[XCTestExpectation alloc] initWithDescription:@"PSM published with error."]; + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; + + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + XCTAssertEqual(error, fakePeripheralManager.didPublishL2CAPChannelError); + XCTAssertEqual(PSM, 0); + [psmPublishedExpectation fulfill]; + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error){ + }]; + [self waitForExpectations:@[ psmPublishedExpectation ] timeout:kTestTimeout]; + } +} + +- (void)testPoweredOffUnpublishesChannel { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; + + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + XCTAssertEqual(error, nil); + XCTAssertEqual(PSM, fakePeripheralManager.PSM); + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error){ + }]; + + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOff]; + + [self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout]; + } +} + +- (void)testPeripheralManagerDidUpdateStatePoweredOffUnpublishesChannel { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + fakePeripheralManager.state = CBManagerStatePoweredOn; + [(id)l2capServer + peripheralManagerDidUpdateState:(CBPeripheralManager *)fakePeripheralManager]; + + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + XCTAssertEqual(error, nil); + XCTAssertEqual(PSM, fakePeripheralManager.PSM); + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error){ + }]; + + fakePeripheralManager.state = CBManagerStatePoweredOff; + [(id)l2capServer + peripheralManagerDidUpdateState:(CBPeripheralManager *)fakePeripheralManager]; + + [self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout]; + } +} + +- (void)testStartPeripheralManagerInitiallyOff { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + XCTestExpectation *psmPublishedExpectation = + [[XCTestExpectation alloc] initWithDescription:@"PSM published."]; + XCTestExpectation *channelOpenedexpectation = + [[XCTestExpectation alloc] initWithDescription:@"Channel opened."]; + + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + XCTAssertEqual(error, nil); + XCTAssertEqual(PSM, fakePeripheralManager.PSM); + [psmPublishedExpectation fulfill]; + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error) { + [channelOpenedexpectation fulfill]; + }]; + + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; + [self waitForExpectations:@[ psmPublishedExpectation, channelOpenedexpectation ] + timeout:kTestTimeout]; + } +} + +- (void)testClose { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; + + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + XCTAssertEqual(error, nil); + XCTAssertEqual(PSM, fakePeripheralManager.PSM); + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error){ + }]; + + [l2capServer close]; + + XCTAssertEqual([l2capServer PSM], 0); + } +} + +- (void)testCloseDoesNotUnpublishesChannelIfNotConnected { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + fakePeripheralManager.unpublishExpectation.inverted = YES; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + [l2capServer close]; + + [self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout]; + } +} + +- (void)testFailedToOpenL2CAPChannel { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + fakePeripheralManager.didOpenL2CAPChannelError = [NSError errorWithDomain:@"fake" + code:0 + userInfo:nil]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + XCTestExpectation *channelOpenedexpectation = + [[XCTestExpectation alloc] initWithDescription:@"Channel opened."]; + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; + + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + XCTAssertEqual(error, nil); + XCTAssertEqual(PSM, fakePeripheralManager.PSM); + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error) { + XCTAssertNil(stream); + XCTAssertEqual(error, fakePeripheralManager.didOpenL2CAPChannelError); + [channelOpenedexpectation fulfill]; + }]; + [self waitForExpectations:@[ channelOpenedexpectation ] timeout:kTestTimeout]; + XCTAssertNil([l2capServer valueForKey:@"l2CAPChannel"]); + XCTAssertNil([l2capServer valueForKey:@"l2CAPStream"]); + } +} + +- (void)testPeripheralManagerDidUnpublishL2CAPChannel { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error){ + }]; + + [(id)l2capServer + peripheralManager:(CBPeripheralManager *)fakePeripheralManager + didUnpublishL2CAPChannel:l2capServer.PSM + error:[NSError errorWithDomain:@"fake" code:0 userInfo:nil]]; + + XCTAssertEqual(l2capServer.PSM, 0); + } +} + +- (void)testCloseL2CAPChannel { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + XCTestExpectation *channelOpenedexpectation = + [[XCTestExpectation alloc] initWithDescription:@"Channel opened."]; + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error) { + [channelOpenedexpectation fulfill]; + }]; + [self waitForExpectations:@[ channelOpenedexpectation ] timeout:kTestTimeout]; + + [l2capServer closeL2CAPChannel]; + + XCTAssertNil([l2capServer valueForKey:@"l2CAPChannel"]); + XCTAssertNil([l2capServer valueForKey:@"l2CAPStream"]); + } +} + +- (void)testPeripheralManagerDidPublishL2CAPChannel { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"completion called"]; + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + XCTAssertEqual(PSM, 1); + XCTAssertNil(error); + [expectation fulfill]; + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error){ + }]; + [(id)l2capServer + peripheralManager:(CBPeripheralManager *)fakePeripheralManager + didPublishL2CAPChannel:1 + error:nil]; + [self waitForExpectations:@[ expectation ] timeout:kTestTimeout]; + XCTAssertEqual(l2capServer.PSM, 1); + } +} + +- (void)testPeripheralManagerDidPublishL2CAPChannelWithError { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEL2CAPServer *l2capServer = + [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + if (enabled.boolValue) { + fakePeripheralManager.peripheralDelegate = l2capServer; + } + + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"completion called"]; + NSError *publishError = [NSError errorWithDomain:@"test" code:0 userInfo:nil]; + [l2capServer + startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM, + NSError *_Nullable error) { + XCTAssertEqual(PSM, 0); + XCTAssertEqualObjects(error, publishError); + [expectation fulfill]; + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, + NSError *_Nullable error){ + }]; + [(id)l2capServer + peripheralManager:(CBPeripheralManager *)fakePeripheralManager + didPublishL2CAPChannel:0 + error:publishError]; + [self waitForExpectations:@[ expectation ] timeout:kTestTimeout]; + XCTAssertEqual(l2capServer.PSM, 0); + } +} + +@end + diff --git a/internal/platform/implementation/apple/Tests/ble_medium_test.mm b/internal/platform/implementation/apple/Tests/ble_medium_test.mm index b628c3f3..23a79dd9 100644 --- a/internal/platform/implementation/apple/Tests/ble_medium_test.mm +++ b/internal/platform/implementation/apple/Tests/ble_medium_test.mm @@ -225,8 +225,8 @@ static const char *const kTestServiceID = "TestServiceID"; #pragma mark - GATT Server Tests - (void)testStartGattServer_Success { - _fakeGNCBLEMedium.fakeGATTServer = [[GNCFakeBLEGATTServer alloc] init]; - + _fakeGNCBLEMedium.fakeGATTServer = + [[GNCFakeBLEGATTServer alloc] initWithPeripheralManager:nil queue:nil]; auto gatt_server = _medium->StartGattServer({}); XCTAssertNotEqual(gatt_server.get(), nullptr); From 54ef43eb83977a1f10d417c8a0a5d5dcbdb920eb Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Wed, 11 Mar 2026 08:41:45 -0700 Subject: [PATCH 011/151] Refactor GNCBLEMedium to support shared PeripheralManager injection. PiperOrigin-RevId: 882032712 --- .../apple/Mediums/BLE/GNCBLEMedium.h | 9 - .../apple/Mediums/BLE/GNCBLEMedium.m | 107 ++- .../apple/Mediums/BLE/GNCCentralManager.m | 6 +- .../apple/Mediums/BLE/Tests/BUILD | 2 +- .../Mediums/BLE/Tests/GNCBLEMedium+Testing.h | 11 +- .../Mediums/BLE/Tests/GNCBLEMediumTest.m | 404 ------------ .../Mediums/BLE/Tests/GNCBLEMediumTest.mm | 621 ++++++++++++++++++ .../Mediums/BLE/Tests/GNCFakeCBL2CAPChannel.h | 2 +- .../BLE/Tests/GNCFakePeripheralManager.m | 1 + .../apple/Tests/ble_medium_test.mm | 12 +- 10 files changed, 719 insertions(+), 456 deletions(-) delete mode 100644 internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMediumTest.m create mode 100644 internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMediumTest.mm diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.h b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.h index 893fd32f..8e0df1fe 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.h +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.h @@ -106,15 +106,6 @@ typedef void (^GNCGATTConnectionCompletionHandler)(GNCBLEGATTClient *_Nullable c */ - (instancetype)init; -/** - * Initializes the BLE medium with a custom central manager. - * - * @param centralManager The central manager to use for BLE operations. - * @param queue The queue to use for all internal operations. - */ -- (instancetype)initWithCentralManager:(id)centralManager - queue:(nullable dispatch_queue_t)queue; - /** The hardware supports BOTH advertising extensions and extended scans. */ @property(nonatomic, readonly) BOOL supportsExtendedAdvertisements; diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m index b4ab5364..e2d3defc 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m @@ -22,10 +22,10 @@ #import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEError.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTClient.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.h" -#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPClient.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCCentralManager.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheral.h" +#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManagerMultiplexer.h" #import "internal/platform/implementation/apple/Mediums/BLE/NSData+GNCBase85.h" #import "internal/platform/implementation/apple/Mediums/BLE/NSData+GNCWebSafeBase64.h" @@ -41,11 +41,16 @@ static NSError *AlreadyScanningError() { } @interface GNCBLEMedium () +- (instancetype)initWithCentralManager:(id)centralManager + peripheralManager:(nullable id)peripheralManager + queue:(dispatch_queue_t)queue; @end @implementation GNCBLEMedium { dispatch_queue_t _queue; id _centralManager; + id _peripheralManager; + GNCPeripheralManagerMultiplexer *_multiplexer; // The active GATT server, or @nil if one hasn't been started yet. GNCBLEGATTServer *_server; @@ -84,31 +89,45 @@ static NSError *AlreadyScanningError() { // The block to call when the BLE connection times out. dispatch_block_t _connectionTimeoutBlock; + + // The set of connected peripherals. + NSMutableSet *_connectedPeripherals; } - (instancetype)init { dispatch_queue_t queue = dispatch_queue_create(kBLEMediumQueueLabel, DISPATCH_QUEUE_SERIAL); CBCentralManager *centralManager = - [[CBCentralManager alloc] initWithDelegate:self + [[CBCentralManager alloc] initWithDelegate:nil queue:queue options:@{CBCentralManagerOptionShowPowerAlertKey : @NO}]; - return [self initWithCentralManager:centralManager queue:queue]; + CBPeripheralManager *peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:nil + queue:queue]; + return [self initWithCentralManager:centralManager + peripheralManager:peripheralManager + queue:queue]; } // This is private and should only be used for tests. The provided central manager must call // delegate methods on the main queue. - (instancetype)initWithCentralManager:(id)centralManager - queue:(nullable dispatch_queue_t)queue { + peripheralManager:(nullable id)peripheralManager + queue:(dispatch_queue_t)queue { self = [super init]; if (self) { - _queue = queue ?: dispatch_get_main_queue(); + _queue = queue; _centralManager = centralManager; _centralManager.centralDelegate = self; + _peripheralManager = peripheralManager; + if (GNCFeatureFlags.sharedPeripheralManagerEnabled && _peripheralManager) { + _multiplexer = [[GNCPeripheralManagerMultiplexer alloc] initWithCallbackQueue:_queue]; + _peripheralManager.peripheralDelegate = _multiplexer; + } _gattConnectionCompletionHandlers = [NSMutableDictionary dictionary]; _gattDisconnectionHandlers = [NSMutableDictionary dictionary]; _scanningServiceUUIDs = [NSMutableArray array]; _l2capStreamCompletionHandlers = [NSMutableDictionary dictionary]; _l2capPSM = 0; + _connectedPeripherals = [NSMutableSet set]; } return self; } @@ -150,15 +169,22 @@ static NSError *AlreadyScanningError() { return NO; } +- (void)dealloc { + [_centralManager stopScan]; + _centralManager.centralDelegate = nil; + + [_peripheralManager stopAdvertising]; + _peripheralManager.peripheralDelegate = nil; +} + - (void)startAdvertisingData:(NSDictionary *)serviceData completionHandler:(nullable GNCStartAdvertisingCompletionHandler)completionHandler { dispatch_async(_queue, ^{ if (!_server) { if (GNCFeatureFlags.sharedPeripheralManagerEnabled) { - // TODO (edwinwu): Implement shared peripheral manager. - // For now, raise an exception. - [NSException raise:NSInvalidArgumentException - format:@"Not implemented for shared manager is enabled."]; + _server = [[GNCBLEGATTServer alloc] initWithPeripheralManager:_peripheralManager + queue:_queue]; + [_multiplexer addListener:_server]; } else { // In legacy mode, we pass nil (or a separate manager) and do NOT add to multiplexer. // GNCBLEGATTServer will create its own internal manager. @@ -205,7 +231,7 @@ static NSError *AlreadyScanningError() { [_scanningServiceUUIDs addObjectsFromArray:serviceUUIDs]; _advertisementFoundHandler = advertisementFoundHandler; - [self internalStartScanningIfPoweredOn]; + [self updateScanningState]; if (completionHandler) { completionHandler(nil); } @@ -226,7 +252,7 @@ static NSError *AlreadyScanningError() { - (void)resumeMediumScanning:(nullable GNCStartScanningCompletionHandler)completionHandler { dispatch_async(_queue, ^{ - [self internalStartScanningIfPoweredOn]; + [self updateScanningState]; if (completionHandler) { completionHandler(nil); } @@ -238,10 +264,9 @@ static NSError *AlreadyScanningError() { dispatch_async(_queue, ^{ if (!_server) { if (GNCFeatureFlags.sharedPeripheralManagerEnabled) { - // TODO (edwinwu): Implement shared peripheral manager. - // For now, raise an exception. - [NSException raise:NSInvalidArgumentException - format:@"Not implemented for shared manager is enabled."]; + _server = [[GNCBLEGATTServer alloc] initWithPeripheralManager:_peripheralManager + queue:_queue]; + [_multiplexer addListener:_server]; } else { _server = [[GNCBLEGATTServer alloc] initWithPeripheralManager:nil queue:nil]; } @@ -291,10 +316,15 @@ static NSError *AlreadyScanningError() { dispatch_async(_queue, ^{ if (!_l2capServer) { if (GNCFeatureFlags.sharedPeripheralManagerEnabled) { - // TODO (edwinwu): Implement shared peripheral manager. - // For now, raise an exception. - [NSException raise:NSInvalidArgumentException - format:@"Not implemented for shared manager is enabled."]; + _l2capServer = [[GNCBLEL2CAPServer alloc] + initWithPeripheralManager:peripheralManager ?: _peripheralManager + queue:peripheralManager ? dispatch_get_main_queue() : _queue]; + // Only add to multiplexer if we are using the internal shared manager. + // If a specific manager was passed in (e.g. for testing?), we might still need logic here. + // But typically `peripheralManager` is nil in prod. + if (peripheralManager == nil || peripheralManager == _peripheralManager) { + [_multiplexer addListener:_l2capServer]; + } } else { // Legacy mode _l2capServer = [[GNCBLEL2CAPServer alloc] @@ -351,23 +381,32 @@ static NSError *AlreadyScanningError() { #pragma mark - Internal -- (void)internalStartScanningIfPoweredOn { +- (void)updateScanningState { dispatch_assert_queue(_queue); // Scanning can only be done when powered on and must be restarted if bluetooth is turned off // then back on. This will be called anytime the central manager's state changes, so // @c scanForPeripheralsWithServices:options: will be called anytime state transitions back to // powered on. - if (_centralManager.state == CBManagerStatePoweredOn && _scanningServiceUUIDs.count > 0) { - // Stop scanning just in case something outside of this class is already scanning. - [_centralManager stopScan]; - [_centralManager - scanForPeripheralsWithServices:_scanningServiceUUIDs - // Nearby relies on the existence of an advertisement for endpoint - // discovery/lost events, so we must set this key to keep the stream - // of duplicate delegate events flowing. This has adverse effect on - // battery life, but currently necessary. - options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES}]; + if (_centralManager.state != CBManagerStatePoweredOn) { + return; } + + // If there are any connected peripherals, stop scanning to avoid high interrupt load on the + // Bluetooth controller, which can cause system-level crashes (XPC connection invalid). + if (_connectedPeripherals.count > 0 || _scanningServiceUUIDs.count == 0) { + [_centralManager stopScan]; + return; + } + + // Stop scanning just in case something outside of this class is already scanning. + [_centralManager stopScan]; + [_centralManager + scanForPeripheralsWithServices:_scanningServiceUUIDs + // Nearby relies on the existence of an advertisement for endpoint + // discovery/lost events, so we must set this key to keep the stream + // of duplicate delegate events flowing. This has adverse effect on + // battery life, but currently necessary. + options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES}]; } - (NSDictionary *)decodeAdvertisementData: @@ -479,7 +518,7 @@ static NSError *AlreadyScanningError() { return; } dispatch_assert_queue(_queue); - [self internalStartScanningIfPoweredOn]; + [self updateScanningState]; } - (void)gnc_centralManager:(id)central @@ -496,6 +535,9 @@ static NSError *AlreadyScanningError() { didConnectPeripheral:(id)peripheral { dispatch_assert_queue(_queue); [self cancelConnectionTimeout]; + [_connectedPeripherals addObject:peripheral.identifier]; + [self updateScanningState]; + if (_l2capPSM > 0) { [self internalOpenL2CAPChannel:peripheral]; return; @@ -541,6 +583,9 @@ static NSError *AlreadyScanningError() { didDisconnectPeripheral:(id)peripheral error:(nullable NSError *)error { dispatch_assert_queue(_queue); + [_connectedPeripherals removeObject:peripheral.identifier]; + [self updateScanningState]; + GNCGATTDisconnectionHandler handler = _gattDisconnectionHandlers[peripheral.identifier]; _gattDisconnectionHandlers[peripheral.identifier] = nil; if (handler) { diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCCentralManager.m b/internal/platform/implementation/apple/Mediums/BLE/GNCCentralManager.m index a86bfee6..7b642fce 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCCentralManager.m +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCCentralManager.m @@ -22,8 +22,10 @@ NS_ASSUME_NONNULL_BEGIN @implementation CBCentralManager (GNCCentralManagerAdditions) - (void)setCentralDelegate:(nullable id)centralDelegate { - NSAssert([centralDelegate conformsToProtocol:@protocol(CBCentralManagerDelegate)], - @"centralDelegate must conform to protocol CBCentralManagerDelegate"); + if (centralDelegate) { + NSAssert([centralDelegate conformsToProtocol:@protocol(CBCentralManagerDelegate)], + @"centralDelegate must conform to protocol CBCentralManagerDelegate"); + } self.delegate = (id)centralDelegate; } diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD b/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD index 2f6066a3..520b9014 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/BUILD @@ -32,7 +32,7 @@ objc_library( "GNCBLEL2CAPFakeInputOutputStream.m", "GNCBLEL2CAPServerTest.mm", "GNCBLEL2CAPStreamTest.m", - "GNCBLEMediumTest.m", + "GNCBLEMediumTest.mm", "GNCFakeBLEGATTServer.m", "GNCFakeBLEMedium.m", "GNCFakeCBL2CAPChannel.m", diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMedium+Testing.h b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMedium+Testing.h index 5da28b57..9761a796 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMedium+Testing.h +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMedium+Testing.h @@ -24,16 +24,19 @@ NS_ASSUME_NONNULL_BEGIN @interface GNCBLEMedium (Testing) /** - * Creates a BLE Medium with a provided central manager. + * Creates a BLE Medium with a provided central manager and peripheral manager. * - * This is only exposed for testing and can be used to inject a fake central manager. + * This is only exposed for tests and can be used to inject a fake central manager and + * peripheral manager. * * @param centralManager The central manager instance. + * @param peripheralManager The peripheral manager instance. * @param queue The queue to run on, this must match the queue that the central manager's delegate - * is running on. Defaults to the main queue when @c nil. + * is running on. */ - (instancetype)initWithCentralManager:(id)centralManager - queue:(nullable dispatch_queue_t)queue; + peripheralManager:(nullable id)peripheralManager + queue:(dispatch_queue_t)queue; - (NSDictionary *)decodeAdvertisementData: (NSDictionary *)advertisementData; diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMediumTest.m b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMediumTest.m deleted file mode 100644 index 10b623d9..00000000 --- a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMediumTest.m +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright 2023 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. - -#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.h" - -#import -#import -#import - -#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTClient.h" -#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.h" -#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheral.h" -#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPClient+Testing.h" -#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMedium+Testing.h" -#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeCentralManager.h" -#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheral.h" -#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h" - -static NSString *const kServiceUUID = @"0000FEF3-0000-1000-8000-00805F9B34FB"; - -@interface GNCBLEMediumTest : XCTestCase -@end - -@implementation GNCBLEMediumTest - -#pragma mark - Supports Extended Advertisements - -- (void)testSupportsExtendedAdvertisements { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - - XCTAssertFalse([medium supportsExtendedAdvertisements]); -} - -#pragma mark - Start Scanning - -- (void)testStartScanning { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *startScanningExpectation = - [[XCTestExpectation alloc] initWithDescription:@"Start scanning."]; - XCTestExpectation *advertisementFoundExpectation = - [[XCTestExpectation alloc] initWithDescription:@"Advertisement found."]; - CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; - - [fakeCentralManager simulateCentralManagerDidUpdateState:CBManagerStatePoweredOn]; - - [medium startScanningForService:serviceUUID - advertisementFoundHandler:^(id peripheral, - NSDictionary *data) { - NSDictionary *expected = @{ - serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], - }; - XCTAssertEqualObjects(expected, data); - [advertisementFoundExpectation fulfill]; - } - completionHandler:^(NSError *error) { - XCTAssertNil(error); - [startScanningExpectation fulfill]; - }]; - - [self waitForExpectations:@[ startScanningExpectation ] timeout:3]; - - XCTAssertEqualObjects(@[ serviceUUID ], fakeCentralManager.serviceUUIDs); - - [fakeCentralManager - simulateCentralManagerDidDiscoverPeripheral:[[GNCFakePeripheral alloc] init] - advertisementData:@{ - CBAdvertisementDataLocalNameKey : @"dGVzdA", - CBAdvertisementDataServiceUUIDsKey : @[ serviceUUID ], - }]; - - [self waitForExpectations:@[ advertisementFoundExpectation ] timeout:3]; -} - -- (void)testAlreadyScanning { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *expectation = - [[XCTestExpectation alloc] initWithDescription:@"Start scanning."]; - - [medium startScanningForService:[CBUUID UUIDWithString:kServiceUUID] - advertisementFoundHandler:^(id peripheral, - NSDictionary *data) { - } - completionHandler:nil]; - - [medium startScanningForService:[CBUUID UUIDWithString:kServiceUUID] - advertisementFoundHandler:^(id peripheral, - NSDictionary *data) { - } - completionHandler:^(NSError *error) { - XCTAssertNotNil(error); - [expectation fulfill]; - }]; - - [self waitForExpectations:@[ expectation ] timeout:3]; -} - -- (void)testStartStopStartScanning { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *expectation = - [[XCTestExpectation alloc] initWithDescription:@"Start scanning."]; - - CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; - - [medium startScanningForService:serviceUUID - advertisementFoundHandler:^(id peripheral, - NSDictionary *data) { - } - completionHandler:^(NSError *error) { - XCTAssertNil(error); - [medium stopScanningWithCompletionHandler:^(NSError *error) { - XCTAssertNil(error); - [medium startScanningForService:serviceUUID - advertisementFoundHandler:^(id peripheral, - NSDictionary *data) { - } - completionHandler:^(NSError *error) { - XCTAssertNil(error); - [expectation fulfill]; - }]; - }]; - }]; - - [self waitForExpectations:@[ expectation ] timeout:3]; -} - -#pragma mark - Decode Advertisement Data - -- (void)testDecodeAndroidStyleAdvertisementData { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; - - NSDictionary *expected = @{ - serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], - }; - - NSDictionary *data = @{ - CBAdvertisementDataServiceDataKey : @{ - serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], - }, - }; - NSDictionary *actual = [medium decodeAdvertisementData:data]; - - XCTAssertEqualObjects(expected, actual); -} - -- (void)testDecodeAndroidStyleAdvertisementDataWithLocalName { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; - - NSDictionary *expected = @{ - serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], - }; - - NSDictionary *data = @{ - CBAdvertisementDataLocalNameKey : @"Nearby", // Just happens to be base64 decodable. - CBAdvertisementDataServiceUUIDsKey : @[ serviceUUID ], - CBAdvertisementDataServiceDataKey : @{ - serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], - }, - }; - NSDictionary *actual = [medium decodeAdvertisementData:data]; - - XCTAssertEqualObjects(expected, actual); -} - -- (void)testDecodeAppleStyleAdvertisementData { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; - - NSDictionary *expected = @{ - serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], - }; - - NSDictionary *data = @{ - CBAdvertisementDataLocalNameKey : @"dGVzdA", - CBAdvertisementDataServiceUUIDsKey : @[ serviceUUID ], - }; - NSDictionary *actual = [medium decodeAdvertisementData:data]; - - XCTAssertEqualObjects(expected, actual); -} - -- (void)testDecodeInvalidAdvertisementData { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; - - NSDictionary *data = @{ - CBAdvertisementDataLocalNameKey : @"!@#$", - CBAdvertisementDataServiceUUIDsKey : @[ serviceUUID ], - }; - NSDictionary *actual = [medium decodeAdvertisementData:data]; - - XCTAssertEqualObjects(@{}, actual); -} - -- (void)testDecodeEmptyAdvertisementData { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - - NSDictionary *actual = [medium decodeAdvertisementData:@{}]; - - XCTAssertEqualObjects(@{}, actual); -} - -#pragma mark - Start GATT Server - -- (void)testStartGATTServer { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *expectation = - [[XCTestExpectation alloc] initWithDescription:@"Start GATT server."]; - - [medium startGATTServerWithCompletionHandler:^(GNCBLEGATTServer *server, NSError *error) { - XCTAssertNotNil(server); - XCTAssertNil(error); - [expectation fulfill]; - }]; - - [self waitForExpectations:@[ expectation ] timeout:3]; -} - -#pragma mark - Start Advertising - -- (void)testStartAdvertising { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *expectation = - [[XCTestExpectation alloc] initWithDescription:@"Start advertising."]; - - // Start advertising is fully covered with @c GNCBLEGATTServer tests. We are passing invalid - // advertising data here so we can test code paths relevant to @c GNCBLEMedium, but bail early - // enough to avoid making actual CoreBluetooth calls. - [medium startAdvertisingData:@{} - completionHandler:^(NSError *error) { - XCTAssertNotNil(error); - [expectation fulfill]; - }]; - - [self waitForExpectations:@[ expectation ] timeout:3]; -} - -- (void)testStopAdvertising { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *expectation = - [[XCTestExpectation alloc] initWithDescription:@"Stop advertising."]; - - // Stop advertising is fully covered with @c GNCBLEGATTServer tests. We are only testing stopping - // without having started which tests the code paths relevant to @c GNCBLEMedium. - [medium stopAdvertisingWithCompletionHandler:^(NSError *error) { - XCTAssertNil(error); - [expectation fulfill]; - }]; - - [self waitForExpectations:@[ expectation ] timeout:3]; -} - -#pragma mark - Open L2CAP Channel - -- (void)testOpenL2CAPServerSocket { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *psmPublishedexpectation = - [[XCTestExpectation alloc] initWithDescription:@"PSM published."]; - XCTestExpectation *channelOpenedexpectation = - [[XCTestExpectation alloc] initWithDescription:@"Channel opened."]; - - [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; - - // Open L2CAP server is fully covered with @c GNCBLEL2CAPServer tests. - [medium - openL2CAPServerWithPSMPublishedCompletionHandler:^(uint16_t PSM, NSError *error) { - XCTAssertEqual(PSM, fakePeripheralManager.PSM); - XCTAssertNil(error); - [psmPublishedexpectation fulfill]; - } - channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *stream, NSError *error) { - XCTAssertNil(error); - [channelOpenedexpectation fulfill]; - } - peripheralManager:fakePeripheralManager]; - - [self waitForExpectations:@[ psmPublishedexpectation ] timeout:0.1]; - [self waitForExpectations:@[ channelOpenedexpectation ] timeout:0.5]; -} - -- (void)testSuccessfulOpenL2CAPChannel { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *expectation = - [[XCTestExpectation alloc] initWithDescription:@"Open L2CAP channel."]; - - GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init]; - GNCBLEL2CAPClient *l2capClient = - [[GNCBLEL2CAPClient alloc] initWithQueue:nil - requestDisconnectionHandler:^(id _Nonnull peripheral){ - }]; - [medium setL2CAPClient:l2capClient]; - [medium openL2CAPChannelWithPSM:123 - peripheral:fakePeripheral - completionHandler:^(GNCBLEL2CAPStream *_Nullable stream, NSError *_Nullable error) { - [expectation fulfill]; - }]; - - [self waitForExpectations:@[ expectation ] timeout:3]; -} - -#pragma mark - Connect - -- (void)testSuccessfulConnect { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"Connect."]; - - [medium connectToGATTServerForPeripheral:[[GNCFakePeripheral alloc] init] - disconnectionHandler:nil - completionHandler:^(GNCBLEGATTClient *client, NSError *error) { - XCTAssertNotNil(client); - XCTAssertNil(error); - [expectation fulfill]; - }]; - - [self waitForExpectations:@[ expectation ] timeout:3]; -} - -- (void)testFailedConnect { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"Connect."]; - - fakeCentralManager.didFailToConnectPeripheralError = [NSError errorWithDomain:@"fake" - code:0 - userInfo:nil]; - - [medium connectToGATTServerForPeripheral:[[GNCFakePeripheral alloc] init] - disconnectionHandler:nil - completionHandler:^(GNCBLEGATTClient *client, NSError *error) { - XCTAssertNil(client); - XCTAssertNotNil(error); - [expectation fulfill]; - }]; - - [self waitForExpectations:@[ expectation ] timeout:3]; -} - -- (void)testDisconnect { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTestExpectation *disconnectExpectation = - [[XCTestExpectation alloc] initWithDescription:@"Disconnect."]; - - GNCFakePeripheral *peripheral = [[GNCFakePeripheral alloc] init]; - - [medium connectToGATTServerForPeripheral:peripheral - disconnectionHandler:^() { - [disconnectExpectation fulfill]; - } - completionHandler:^(GNCBLEGATTClient *client, NSError *error) { - XCTAssertNotNil(client); - XCTAssertNil(error); - [client disconnect]; - }]; - - [self waitForExpectations:@[ disconnectExpectation ] timeout:3]; -} - -- (void)testRetrievePeripheralWithIdentifier_exists { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTAssertNotNil( - [medium retrievePeripheralWithIdentifier: - [[NSUUID alloc] initWithUUIDString:@"11111111-1111-1111-1111-111111111111"]]); -} - -- (void)testRetrievePeripheralWithIdentifier_doesNotExist { - GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; - GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil]; - XCTAssertNil( - [medium retrievePeripheralWithIdentifier: - [[NSUUID alloc] initWithUUIDString:@"11111111-1111-1111-1111-111111111112"]]); -} - -@end diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMediumTest.mm b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMediumTest.mm new file mode 100644 index 00000000..49e0a462 --- /dev/null +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMediumTest.mm @@ -0,0 +1,621 @@ +// Copyright 2023 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. + +#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.h" + +#import +#import +#import + +#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTClient.h" +#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.h" +#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheral.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPClient+Testing.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMedium+Testing.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeCentralManager.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheral.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h" + +#include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "internal/flags/nearby_flags.h" + +static NSString *const kServiceUUID = @"0000FEF3-0000-1000-8000-00805F9B34FB"; + +@interface GNCBLEMediumTest : XCTestCase +@end + +@implementation GNCBLEMediumTest + +- (void)tearDown { + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); + [super tearDown]; +} + +- (void)testInit_allocatesMultiplexerWhenFlagEnabled { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + + id multiplexer = [medium valueForKey:@"_multiplexer"]; + if (enabled.boolValue) { + XCTAssertNotNil(multiplexer); + XCTAssertEqual(fakePeripheralManager.peripheralDelegate, multiplexer); + } else { + XCTAssertNil(multiplexer); + XCTAssertNil(fakePeripheralManager.peripheralDelegate); + } + } +} + +#pragma mark - Supports Extended Advertisements + +- (void)testSupportsExtendedAdvertisements { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + + XCTAssertFalse([medium supportsExtendedAdvertisements]); + } +} + +#pragma mark - Start Scanning + +- (void)testStartScanning { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *startScanningExpectation = + [[XCTestExpectation alloc] initWithDescription:@"Start scanning."]; + XCTestExpectation *advertisementFoundExpectation = + [[XCTestExpectation alloc] initWithDescription:@"Advertisement found."]; + CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; + + [fakeCentralManager simulateCentralManagerDidUpdateState:CBManagerStatePoweredOn]; + + [medium startScanningForService:serviceUUID + advertisementFoundHandler:^(id peripheral, + NSDictionary *data) { + NSDictionary *expected = @{ + serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], + }; + XCTAssertEqualObjects(expected, data); + [advertisementFoundExpectation fulfill]; + } + completionHandler:^(NSError *error) { + XCTAssertNil(error); + [startScanningExpectation fulfill]; + }]; + + [self waitForExpectations:@[ startScanningExpectation ] timeout:3]; + + XCTAssertEqualObjects(@[ serviceUUID ], fakeCentralManager.serviceUUIDs); + + [fakeCentralManager + simulateCentralManagerDidDiscoverPeripheral:[[GNCFakePeripheral alloc] init] + advertisementData:@{ + CBAdvertisementDataLocalNameKey : @"dGVzdA", + CBAdvertisementDataServiceUUIDsKey : @[ serviceUUID ], + }]; + + [self waitForExpectations:@[ advertisementFoundExpectation ] timeout:3]; + } +} + +- (void)testAlreadyScanning { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"Start scanning."]; + + [medium startScanningForService:[CBUUID UUIDWithString:kServiceUUID] + advertisementFoundHandler:^(id peripheral, + NSDictionary *data) { + } + completionHandler:nil]; + + [medium startScanningForService:[CBUUID UUIDWithString:kServiceUUID] + advertisementFoundHandler:^(id peripheral, + NSDictionary *data) { + } + completionHandler:^(NSError *error) { + XCTAssertNotNil(error); + [expectation fulfill]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:3]; + } +} + +- (void)testStartStopStartScanning { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"Start scanning."]; + + CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; + + [medium startScanningForService:serviceUUID + advertisementFoundHandler:^(id peripheral, + NSDictionary *data) { + } + completionHandler:^(NSError *error) { + XCTAssertNil(error); + [medium stopScanningWithCompletionHandler:^(NSError *error) { + XCTAssertNil(error); + [medium startScanningForService:serviceUUID + advertisementFoundHandler:^(id peripheral, + NSDictionary *data) { + } + completionHandler:^(NSError *error) { + XCTAssertNil(error); + [expectation fulfill]; + }]; + }]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:3]; + } +} + +#pragma mark - Decode Advertisement Data + +- (void)testDecodeAndroidStyleAdvertisementData { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; + + NSDictionary *expected = @{ + serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], + }; + + NSDictionary *data = @{ + CBAdvertisementDataServiceDataKey : @{ + serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], + }, + }; + NSDictionary *actual = [medium decodeAdvertisementData:data]; + + XCTAssertEqualObjects(expected, actual); + } +} + +- (void)testDecodeAndroidStyleAdvertisementDataWithLocalName { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; + + NSDictionary *expected = @{ + serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], + }; + + NSDictionary *data = @{ + CBAdvertisementDataLocalNameKey : @"Nearby", // Just happens to be base64 decodable. + CBAdvertisementDataServiceUUIDsKey : @[ serviceUUID ], + CBAdvertisementDataServiceDataKey : @{ + serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], + }, + }; + NSDictionary *actual = [medium decodeAdvertisementData:data]; + + XCTAssertEqualObjects(expected, actual); + } +} + +- (void)testDecodeAppleStyleAdvertisementData { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; + + NSDictionary *expected = @{ + serviceUUID : [@"test" dataUsingEncoding:NSUTF8StringEncoding], + }; + + NSDictionary *data = @{ + CBAdvertisementDataLocalNameKey : @"dGVzdA", + CBAdvertisementDataServiceUUIDsKey : @[ serviceUUID ], + }; + NSDictionary *actual = [medium decodeAdvertisementData:data]; + + XCTAssertEqualObjects(expected, actual); + } +} + +- (void)testDecodeInvalidAdvertisementData { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; + + NSDictionary *data = @{ + CBAdvertisementDataLocalNameKey : @"!@#$", + CBAdvertisementDataServiceUUIDsKey : @[ serviceUUID ], + }; + NSDictionary *actual = [medium decodeAdvertisementData:data]; + + XCTAssertEqualObjects(@{}, actual); + } +} + +- (void)testDecodeEmptyAdvertisementData { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + + NSDictionary *actual = [medium decodeAdvertisementData:@{}]; + + XCTAssertEqualObjects(@{}, actual); + } +} + +#pragma mark - Start GATT Server + +- (void)testStartGATTServer { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"Start GATT server."]; + + [medium startGATTServerWithCompletionHandler:^(GNCBLEGATTServer *server, NSError *error) { + XCTAssertNotNil(server); + XCTAssertNil(error); + + // Verify internal structure based on flag + id mediumManager = [medium valueForKey:@"_peripheralManager"]; + id serverManager = [server valueForKey:@"_peripheralManager"]; + + if (enabled.boolValue) { + XCTAssertEqual(mediumManager, serverManager); + id multiplexer = [medium valueForKey:@"_multiplexer"]; + XCTAssertEqual([mediumManager peripheralDelegate], multiplexer); + } else { + XCTAssertNotEqual(mediumManager, serverManager); + id manager = [server valueForKey:@"_peripheralManager"]; + XCTAssertEqual([manager peripheralDelegate], server); + } + + [expectation fulfill]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:3]; + } +} + +#pragma mark - Start Advertising + +- (void)testStartAdvertising { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"Start advertising."]; + + // Start advertising is fully covered with @c GNCBLEGATTServer tests. We are passing invalid + // advertising data here so we can test code paths relevant to @c GNCBLEMedium, but bail early + // enough to avoid making actual CoreBluetooth calls. + [medium startAdvertisingData:@{} + completionHandler:^(NSError *error) { + XCTAssertNotNil(error); + [expectation fulfill]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:3]; + } +} + +- (void)testStopAdvertising { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"Stop advertising."]; + + // Stop advertising is fully covered with @c GNCBLEGATTServer tests. We are only testing stopping + // without having started which tests the code paths relevant to @c GNCBLEMedium. + [medium stopAdvertisingWithCompletionHandler:^(NSError *error) { + XCTAssertNil(error); + [expectation fulfill]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:3]; + } +} + +#pragma mark - Open L2CAP Channel + +- (void)testOpenL2CAPServerSocket { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *psmPublishedexpectation = + [[XCTestExpectation alloc] initWithDescription:@"PSM published."]; + XCTestExpectation *channelOpenedexpectation = + [[XCTestExpectation alloc] initWithDescription:@"Channel opened."]; + + [fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn]; + + // Open L2CAP server is fully covered with @c GNCBLEL2CAPServer tests. + [medium + openL2CAPServerWithPSMPublishedCompletionHandler:^(uint16_t PSM, NSError *error) { + XCTAssertEqual(PSM, fakePeripheralManager.PSM); + XCTAssertNil(error); + [psmPublishedexpectation fulfill]; + } + channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *stream, NSError *error) { + XCTAssertNil(error); + [channelOpenedexpectation fulfill]; + } + peripheralManager:fakePeripheralManager]; + + [self waitForExpectations:@[ psmPublishedexpectation ] timeout:0.1]; + [self waitForExpectations:@[ channelOpenedexpectation ] timeout:0.5]; + } +} + +- (void)testSuccessfulOpenL2CAPChannel { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"Open L2CAP channel."]; + + GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init]; + GNCBLEL2CAPClient *l2capClient = + [[GNCBLEL2CAPClient alloc] initWithQueue:nil + requestDisconnectionHandler:^(id _Nonnull peripheral){ + }]; + [medium setL2CAPClient:l2capClient]; + [medium openL2CAPChannelWithPSM:123 + peripheral:fakePeripheral + completionHandler:^(GNCBLEL2CAPStream *_Nullable stream, NSError *_Nullable error) { + [expectation fulfill]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:3]; + } +} + +#pragma mark - Connect + +- (void)testSuccessfulConnect { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"Connect."]; + + [medium connectToGATTServerForPeripheral:[[GNCFakePeripheral alloc] init] + disconnectionHandler:nil + completionHandler:^(GNCBLEGATTClient *client, NSError *error) { + XCTAssertNotNil(client); + XCTAssertNil(error); + [expectation fulfill]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:3]; + } +} + +- (void)testFailedConnect { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"Connect."]; + + fakeCentralManager.didFailToConnectPeripheralError = [NSError errorWithDomain:@"fake" + code:0 + userInfo:nil]; + + [medium connectToGATTServerForPeripheral:[[GNCFakePeripheral alloc] init] + disconnectionHandler:nil + completionHandler:^(GNCBLEGATTClient *client, NSError *error) { + XCTAssertNil(client); + XCTAssertNotNil(error); + [expectation fulfill]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:3]; + } +} + +- (void)testDisconnect { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTestExpectation *disconnectExpectation = + [[XCTestExpectation alloc] initWithDescription:@"Disconnect."]; + + GNCFakePeripheral *peripheral = [[GNCFakePeripheral alloc] init]; + + [medium connectToGATTServerForPeripheral:peripheral + disconnectionHandler:^() { + [disconnectExpectation fulfill]; + } + completionHandler:^(GNCBLEGATTClient *client, NSError *error) { + XCTAssertNotNil(client); + XCTAssertNil(error); + [client disconnect]; + }]; + + [self waitForExpectations:@[ disconnectExpectation ] timeout:3]; + } +} + +- (void)testRetrievePeripheralWithIdentifier_exists { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTAssertNotNil( + [medium retrievePeripheralWithIdentifier: + [[NSUUID alloc] initWithUUIDString:@"11111111-1111-1111-1111-111111111111"]]); + } +} + +- (void)testRetrievePeripheralWithIdentifier_doesNotExist { + for (NSNumber *enabled in @[ @NO, @YES ]) { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kEnableSharedPeripheralManager, + enabled.boolValue); + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; + XCTAssertNil( + [medium retrievePeripheralWithIdentifier: + [[NSUUID alloc] initWithUUIDString:@"11111111-1111-1111-1111-111111111112"]]); + } +} + +@end diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeCBL2CAPChannel.h b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeCBL2CAPChannel.h index 69a1b791..465b3120 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeCBL2CAPChannel.h +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeCBL2CAPChannel.h @@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN /** The socket file descriptor for the L2CAP channel. */ @property(nonatomic, readonly) int socketFD; /** The PSM (Protocol/Service Multiplexer) of the L2CAP channel. */ -@property(nonatomic, readonly) CBL2CAPPSM PSM; +@property(nonatomic, readwrite) CBL2CAPPSM PSM; @end diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.m b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.m index 912974df..3f18bf6a 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.m +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.m @@ -140,6 +140,7 @@ static const uint16_t kPSM = 192; GNCFakeCBL2CAPChannel *fakeChannel = [[GNCFakeCBL2CAPChannel alloc] init]; fakeChannel.inputStream = fakeStream.inputStream; fakeChannel.outputStream = fakeStream.outputStream; + fakeChannel.PSM = _PSM; [_peripheralDelegate gnc_peripheralManager:self didOpenL2CAPChannel:(CBL2CAPChannel *)fakeChannel error:_didOpenL2CAPChannelError]; diff --git a/internal/platform/implementation/apple/Tests/ble_medium_test.mm b/internal/platform/implementation/apple/Tests/ble_medium_test.mm index 23a79dd9..ff4f688a 100644 --- a/internal/platform/implementation/apple/Tests/ble_medium_test.mm +++ b/internal/platform/implementation/apple/Tests/ble_medium_test.mm @@ -23,9 +23,6 @@ #include #include -#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTClient.h" -#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.h" -#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPClient.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheral.h" #import "internal/platform/implementation/apple/Mediums/BLE/Sockets/Source/Central/GNSCentralManager.h" @@ -33,7 +30,10 @@ #import "internal/platform/implementation/apple/Mediums/BLE/Sockets/Source/Peripheral/GNSPeripheralManager.h" #import "internal/platform/implementation/apple/Mediums/BLE/Sockets/Source/Peripheral/GNSPeripheralServiceManager.h" #import "internal/platform/implementation/apple/Mediums/BLE/Sockets/Source/Shared/GNSSocket.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMedium+Testing.h" #import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeBLEGATTServer.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeCentralManager.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h" #import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeBLEMedium.h" #import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheral.h" #include "internal/platform/implementation/apple/ble_utils.h" @@ -71,7 +71,11 @@ static const char *const kTestServiceID = "TestServiceID"; - (void)setUp { [super setUp]; - _fakeGNCBLEMedium = [[GNCFakeBLEMedium alloc] init]; + GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; + GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; + _fakeGNCBLEMedium = [[GNCFakeBLEMedium alloc] initWithCentralManager:fakeCentralManager + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; _medium = std::make_unique((GNCBLEMedium *)_fakeGNCBLEMedium); } From 59b283f94f8059a81e8b23f529f97b4e914bebb3 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 11 Mar 2026 10:30:26 -0700 Subject: [PATCH 012/151] internal changes PiperOrigin-RevId: 882086054 --- sharing/nearby_sharing_service_impl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 7b215bd8..5a59f2e8 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -272,7 +272,7 @@ NearbySharingServiceImpl::NearbySharingServiceImpl( this), absl::bind_front(&NearbySharingServiceImpl::OnOutgoingTransferUpdate, this)), - sync_manager_(&preference_manager_) { + sync_manager_(nearby_identity_client_, &preference_manager_) { CHECK(nearby_connections_manager_); CHECK(analytics_recorder); From def9f089866669be9cc5626d8ccf1a9fe9ea27db Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 11 Mar 2026 10:30:52 -0700 Subject: [PATCH 013/151] Fix flaky test InitializeUpgradedMediumForEndpoint_Success. PiperOrigin-RevId: 882086351 --- .../implementation/awdl_bwu_handler_test.cc | 219 +++++++++++------- 1 file changed, 133 insertions(+), 86 deletions(-) diff --git a/connections/implementation/awdl_bwu_handler_test.cc b/connections/implementation/awdl_bwu_handler_test.cc index a2ef2417..627a7af6 100644 --- a/connections/implementation/awdl_bwu_handler_test.cc +++ b/connections/implementation/awdl_bwu_handler_test.cc @@ -105,6 +105,7 @@ 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; @@ -219,103 +220,149 @@ TEST_F(AwdlBwuHandlerTest, TEST_F(AwdlBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { 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::AWDL, - location::nearby::proto::connections::ConnectionAttemptDirection:: - OUTGOING, - /*connection_token=*/""); - client.AddCancellationFlag(std::string(kEndpointId)); + // The reason for putting ClientProxy inside a C++ { } block so it destructs + // before the simulated clock is restored. Otherwise, the simulated clock + // would stopped before ClientProxy went out of scope, causing its destructor + // to log the session duration using the real system clock. If 1 or more + // real-world milliseconds elapsed between the test start and test end, this + // duration evaluated to something > 0. + { + 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::AWDL, + location::nearby::proto::connections::ConnectionAttemptDirection:: + OUTGOING, + /*connection_token=*/""); + client.AddCancellationFlag(std::string(kEndpointId)); - auto awdl_server_socket = std::make_unique(); + auto awdl_server_socket = std::make_unique(); + auto* awdl_server_socket_ptr = awdl_server_socket.get(); + EXPECT_CALL(*awdl_server_socket_ptr, GetPort()) + .WillRepeatedly(Return(8080)); + EXPECT_CALL(*awdl_server_socket_ptr, Accept()) + .WillOnce(Return(ByMove(nullptr))); + EXPECT_CALL(*awdl_server_socket_ptr, Close()) + .WillRepeatedly(Return(Exception{Exception::kSuccess})); - EXPECT_CALL(*awdl_medium_mock, ListenForService(_, 0)) - .WillOnce(Return(ByMove(std::move(awdl_server_socket)))); - EXPECT_CALL(*awdl_medium_mock, StartAdvertising(_)).WillOnce(Return(true)); + EXPECT_CALL(*awdl_medium_mock, ListenForService(_, 0)) + .WillOnce(Return(ByMove(std::move(awdl_server_socket)))); - ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( - &client, std::string(kServiceId), std::string(kEndpointId)); + std::string captured_service_name; + std::string captured_service_type; + EXPECT_CALL(*awdl_medium_mock, StartAdvertising(_)) + .WillOnce([&](const NsdServiceInfo& nsd_service_info) { + captured_service_name = nsd_service_info.GetServiceName(); + captured_service_type = nsd_service_info.GetServiceType(); + return true; + }); - EXPECT_FALSE(result.Empty()); - OfflineFrame result_frame; - EXPECT_TRUE(result_frame.ParseFromString(std::string(result))); - EXPECT_TRUE(result_frame.has_v1()); - EXPECT_TRUE(result_frame.v1().has_bandwidth_upgrade_negotiation()); - EXPECT_TRUE(result_frame.v1() - .bandwidth_upgrade_negotiation() - .has_upgrade_path_info()); - EXPECT_TRUE(result_frame.v1() - .bandwidth_upgrade_negotiation() - .upgrade_path_info() - .has_awdl_credentials()); + ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( + &client, std::string(kServiceId), std::string(kEndpointId)); - 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 { + EXPECT_FALSE(result.Empty()); + OfflineFrame expected_frame; + expected_frame.set_version(OfflineFrame::V1); + expected_frame.mutable_v1()->set_type( + V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION); + auto* bwu_frame = + expected_frame.mutable_v1()->mutable_bandwidth_upgrade_negotiation(); + bwu_frame->set_event_type( + BandwidthUpgradeNegotiationFrame::UPGRADE_PATH_AVAILABLE); + auto* upgrade_path_info = bwu_frame->mutable_upgrade_path_info(); + upgrade_path_info->set_medium( + BandwidthUpgradeNegotiationFrame::UpgradePathInfo::AWDL); + upgrade_path_info->set_supports_client_introduction_ack(true); + upgrade_path_info->set_supports_disabling_encryption(true); + auto* awdl_credentials = upgrade_path_info->mutable_awdl_credentials(); + awdl_credentials->set_service_name(captured_service_name); + awdl_credentials->set_service_type(captured_service_type); + + // The password is automatically generated and set in the handle start, we + // can obtain it from the credential Since we mock StartAcceptingConnections + // instead of using real awdl, GetPskInfo won't work perfectly. However + // InitializeUpgradedMediumForEndpoint internally calls + // parser::ForBwuAwdlPathAvailable which puts the generated password. We + // will extract it from result directly to build expected frame. + OfflineFrame result_frame; + EXPECT_TRUE(result_frame.ParseFromString(std::string(result))); + awdl_credentials->set_password(result_frame.v1() + .bandwidth_upgrade_negotiation() + .upgrade_path_info() + .awdl_credentials() + .password()); + + 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: P2P_POINT_TO_POINT - role: ADVERTISER - advertising_phase { + strategy_session { duration_millis: 0 - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false + 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 } - stop_reason: FINISH_SESSION_STOP_ADVERTISING - } - upgrade_attempt { - direction: OUTGOING - duration_millis: 0 - from_medium: BLUETOOTH - to_medium: AWDL - 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 + upgrade_attempt { + direction: OUTGOING + duration_millis: 0 + from_medium: BLUETOOTH + to_medium: AWDL + 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 + } } } } - } - 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(); + 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(); + handler_.RevertInitiatorState(); + } + MediumEnvironment::Instance().Stop(); } TEST_F(AwdlBwuHandlerTest, OnIncomingAwdlConnection_Success) { From e0d79e661e863cef7e9a6954c30ce3a08e21205e Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 11 Mar 2026 11:02:43 -0700 Subject: [PATCH 014/151] Use a reverse-DNS prefix for Wi-Fi Direct service names. PiperOrigin-RevId: 882102213 --- .../windows/wifi_direct_medium.cc | 13 ++++++++++++- .../implementation/windows/wifi_direct_test.cc | 18 +++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/internal/platform/implementation/windows/wifi_direct_medium.cc b/internal/platform/implementation/windows/wifi_direct_medium.cc index 1783c3c9..00e390eb 100644 --- a/internal/platform/implementation/windows/wifi_direct_medium.cc +++ b/internal/platform/implementation/windows/wifi_direct_medium.cc @@ -20,6 +20,7 @@ #include #include +#include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" @@ -41,6 +42,15 @@ namespace nearby { namespace windows { namespace { constexpr int kWaitingForConnectionTimeoutSeconds = 90; // seconds +// The prefix of the service name. +// Fully Qualified Service Name (FQSN) must follow reverse-DNS notation to +// ensure uniqueness and cross-platform compatibility. Otherwise, Windows +// prefixes the service name with "org.wi-fi.wfds.", which prevents Android +// devices from discovering the service. +// https://www.wi-fi.org/file-member/wi-fi-peer-to-peer-services-technical-specification-package +// Wi-Fi_Peer-to-Peer_Services_Technical_Specification_v1.2.pdf chapter 3.2 +constexpr absl::string_view kServiceNamePrefix = + "com.google.nearby.connection."; } // namespace WifiDirectMedium::WifiDirectMedium() { @@ -294,7 +304,8 @@ bool WifiDirectMedium::StartWifiDirect( std::string pin = absl::StrFormat("%04x", prng.NextUint32()); credentials_go_->SetPin(pin); - std::string service_name = "NC-" + std::to_string(prng.NextUint32()); + std::string service_name = + absl::StrCat(kServiceNamePrefix, std::to_string(prng.NextUint32())); credentials_go_->SetServiceName(service_name); LOG(INFO) << "service_name:pin " << service_name << ":" << pin; diff --git a/internal/platform/implementation/windows/wifi_direct_test.cc b/internal/platform/implementation/windows/wifi_direct_test.cc index 9be5e148..b6d91c1f 100644 --- a/internal/platform/implementation/windows/wifi_direct_test.cc +++ b/internal/platform/implementation/windows/wifi_direct_test.cc @@ -19,6 +19,8 @@ #include #include "gtest/gtest.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" #include "absl/time/clock.h" #include "absl/time/time.h" #include "internal/platform/implementation/wifi_direct.h" @@ -28,7 +30,13 @@ namespace nearby { namespace windows { namespace { - +constexpr absl::string_view kServiceNamePrefix = + "com.google.nearby.connection."; +// Tests are prefixed with DISABLED_ for several reasons: 1. They require user +// interaction, 2. They have access to Windows APIs and physical WiFi hardware. +// These tests are intended for validation on actual Windows machines, 3. By +// using the DISABLED_ prefix, we can Keep the code in the repo and prevent CI +// failures. TEST(WifiDirectMedium, DISABLED_StartWifiDirect) { int run_test; LOG(INFO) << "Run StartWifiDirect test case? input 0 or 1:"; @@ -72,7 +80,9 @@ TEST(WifiDirectMedium, DISABLED_ConnectWifiDirect) { LOG(INFO) << "Enter pin: "; std::string pin; std::cin >> pin; - credentials.SetServiceName(service_name); + std::string service_name_with_prefix = + absl::StrCat(kServiceNamePrefix, service_name); + credentials.SetServiceName(service_name_with_prefix); credentials.SetPin(pin); EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect(credentials)); @@ -147,7 +157,9 @@ TEST(WifiDirectMedium, DISABLED_WifiDirectConnectToServiceServer) { LOG(INFO) << "Enter pin: "; std::string pin; std::cin >> pin; - credentials.SetServiceName(service_name); + std::string service_name_with_prefix = + absl::StrCat(kServiceNamePrefix, service_name); + credentials.SetServiceName(service_name_with_prefix); credentials.SetPin(pin); EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect(credentials)); From 6518130860927b6437a9ece3fdcb978916d81578 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 11 Mar 2026 18:19:03 -0700 Subject: [PATCH 015/151] Add Binding messages. PiperOrigin-RevId: 882297295 --- sharing/proto/wire_format.proto | 35 ++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/sharing/proto/wire_format.proto b/sharing/proto/wire_format.proto index 2d35c6a7..d20329c3 100644 --- a/sharing/proto/wire_format.proto +++ b/sharing/proto/wire_format.proto @@ -183,7 +183,7 @@ message Frame { optional V1Frame v1 = 2; } -// NEXT_ID=9 +// NEXT_ID=10 message V1Frame { enum FrameType { UNKNOWN_FRAME_TYPE = 0; @@ -197,6 +197,7 @@ message V1Frame { // No longer used. PROGRESS_UPDATE = 7; FILE_SYNC = 8; + BINDINGS = 9; } optional FrameType type = 1; @@ -209,6 +210,7 @@ message V1Frame { optional CertificateInfoFrame certificate_info = 6 [deprecated = true]; optional ProgressUpdateFrame progress_update = 7 [deprecated = true]; optional SyncFrame file_sync = 8; + optional BindingFrame bindings = 9; } // An introduction packet sent by the sending side. Contains a list of files @@ -280,6 +282,37 @@ message SyncFolder { optional int64 max_sequence = 4; } +// Messages used to create pair bindings between devices. +// An initiator device requests a new bindingId from the BE using the +// InitiateBinding rpc. This new bindingId is passed to the peer device using +// a BindingRequest frame. The peer device will use this bindingId to call +// JoinBinding rpc. If successful, the peer device is response with a +// BindingResponse frame with status of SUCCESS. +message BindingFrame { + oneof content { + BindingRequest binding_request = 1; + BindingResponse binding_response = 2; + } +} + +message BindingRequest { + enum Type { + UNKNOWN = 0; + FILESYNC = 1; + } + optional string binding_id = 1; + optional Type type = 2; +} + +message BindingResponse { + enum Status { + UNKNOWN = 0; + SUCCESS = 1; + FAILURE = 2; // TODO: b/485307320 - Add more specific error codes. + } + optional Status status = 1; +} + // A response packet sent by the receiving side. Accepts or rejects the list of // files. // NEXT_ID=4 From 25ac6a21ab5223d55dc03e76dd7697a2cc7d1474 Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 12 Mar 2026 11:31:17 -0700 Subject: [PATCH 016/151] Automated Code Change PiperOrigin-RevId: 882693871 --- .../implementation/windows/scheduled_executor.cc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/internal/platform/implementation/windows/scheduled_executor.cc b/internal/platform/implementation/windows/scheduled_executor.cc index d1bcbf12..87792ff8 100644 --- a/internal/platform/implementation/windows/scheduled_executor.cc +++ b/internal/platform/implementation/windows/scheduled_executor.cc @@ -45,17 +45,7 @@ std::shared_ptr ScheduledExecutor::Schedule( return nullptr; } - if (NearbyFlags::GetInstance().GetBoolFlag( - platform::config_package_nearby::nearby_platform_feature:: - kRunScheduledExecutorCallbackOnExecutorThread)) { - return task_scheduler_.Schedule( - [this, runnable = std::move(runnable)]() mutable { - Execute(std::move(runnable)); - }, - duration); - } else { - return task_scheduler_.Schedule(std::move(runnable), duration); - } + return task_scheduler_.Schedule(std::move(runnable), duration); } void ScheduledExecutor::Execute(Runnable&& runnable) { From 03fe80f0b8764e622b78efc7cf7f99dcfd663a31 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 13 Mar 2026 15:16:25 -0700 Subject: [PATCH 017/151] Create PairingClient. PiperOrigin-RevId: 883360595 --- sharing/BUILD | 22 +++++- sharing/fake_nearby_sharing_service.cc | 87 ++++++++++++++++-------- sharing/fake_nearby_sharing_service.h | 69 ++++++++++++++++--- sharing/nearby_sharing_service.h | 16 +++-- sharing/nearby_sharing_service_impl.cc | 53 +++++++-------- sharing/nearby_sharing_service_impl.h | 15 ++-- sharing/outgoing_targets_manager.cc | 15 ++++ sharing/outgoing_targets_manager.h | 3 + sharing/outgoing_targets_manager_test.cc | 33 +++++++++ 9 files changed, 229 insertions(+), 84 deletions(-) diff --git a/sharing/BUILD b/sharing/BUILD index 567b9948..d03c3f5a 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -50,6 +50,7 @@ cc_library( visibility = [ "//location/nearby/apps/better_together/windows/nearby_share:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", + "//location/nearby/sharing/lib:__subpackages__", "//location/nearby/sharing/sdk/quick_share_server:__pkg__", "//location/nearby/testing/nearby_native:__subpackages__", "//sharing:__subpackages__", @@ -88,6 +89,7 @@ cc_library( visibility = [ "//location/nearby/apps/better_together/windows/nearby_share:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", + "//location/nearby/sharing/lib:__subpackages__", "//location/nearby/sharing/sdk/quick_share_server:__pkg__", "//location/nearby/testing/nearby_native:__subpackages__", "//sharing:__subpackages__", @@ -120,6 +122,7 @@ cc_library( visibility = [ "//location/nearby/apps/better_together/windows/nearby_share:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", + "//location/nearby/sharing/lib:__subpackages__", "//location/nearby/sharing/sdk/quick_share_server:__pkg__", "//location/nearby/testing/nearby_native:__subpackages__", "//sharing:__subpackages__", @@ -270,6 +273,9 @@ cc_library( name = "outgoing_targets_manager", srcs = ["outgoing_targets_manager.cc"], hdrs = ["outgoing_targets_manager.h"], + visibility = [ + "//location/nearby/sharing/lib:__subpackages__", + ], deps = [ ":share_session", ":thread_timer", @@ -353,6 +359,7 @@ cc_library( ], visibility = [ "//location/nearby/cpp/sharing:__subpackages__", + "//location/nearby/sharing/lib:__subpackages__", "//location/nearby/sharing/sdk/quick_share_server:__pkg__", "//location/nearby/testing/nearby_native:__subpackages__", "//sharing:__subpackages__", @@ -440,22 +447,32 @@ cc_library( ":attachments", ":connection_types", ":nearby_sharing_service", + ":outgoing_targets_manager", + ":share_session", ":transfer_metadata", ":types", "//internal/base", "//internal/base:file_path", "//internal/platform:types", + "//internal/test", + "//location/nearby/sharing/lib/rpc:fake_nearby_share_client", + "//location/nearby/sharing/lib/rpc:sharing_rpc_client", + "//location/nearby/sharing/lib/sync:sync_manager", + "//sharing/analytics", + "//sharing/certificates", "//sharing/common:enum", "//sharing/internal/api:platform", "//sharing/internal/public:logging", - "//sharing/local_device_data", + "//sharing/internal/test:nearby_test", "//sharing/proto:enums_cc_proto", "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", + "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/strings", "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/time", ], ) @@ -1001,10 +1018,11 @@ cc_test( ":test_support", ":transfer_metadata", ":types", - "//internal/base:file_path", "//internal/platform/implementation:platform_impl", "//internal/test", "//sharing/analytics", + "//sharing/certificates", + "//sharing/certificates:test_support", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", "@com_google_googletest//:gtest_main", diff --git a/sharing/fake_nearby_sharing_service.cc b/sharing/fake_nearby_sharing_service.cc index 2fcb7932..42538323 100644 --- a/sharing/fake_nearby_sharing_service.cc +++ b/sharing/fake_nearby_sharing_service.cc @@ -19,12 +19,17 @@ #include #include +#include "location/nearby/sharing/lib/sync/sync_manager.h" +#include "absl/functional/any_invocable.h" #include "internal/base/observer_list.h" +#include "internal/platform/clock.h" #include "sharing/advertisement.h" #include "sharing/attachment_container.h" -#include "sharing/local_device_data/nearby_share_local_device_data_manager.h" +#include "sharing/certificates/nearby_share_certificate_manager.h" #include "sharing/nearby_sharing_service.h" #include "sharing/nearby_sharing_settings.h" +#include "sharing/outgoing_share_session.h" +#include "sharing/outgoing_targets_manager.h" #include "sharing/share_target.h" #include "sharing/share_target_discovered_callback.h" #include "sharing/transfer_metadata.h" @@ -34,6 +39,22 @@ namespace nearby { namespace sharing { +FakeNearbySharingService::FakeNearbySharingService() + : service_thread_(&clock_, /*count=*/1), + analytics_recorder_(/*vendor_id=*/0, /*event_logger=*/nullptr), + sync_manager_(std::make_unique(&identity_rpc_client_, + &preference_manager_)), + outgoing_targets_manager_(std::make_unique( + &clock_, &service_thread_, &connections_manager_, + &analytics_recorder_, + [this](const ShareTarget& target) { + FireShareTargetDiscovered(target); + }, + [this](const ShareTarget& target) { FireShareTargetUpdated(target); }, + [this](const ShareTarget& target) { FireShareTargetLost(target); }, + /*transfer_update_callback=*/ + [](OutgoingShareSession&, const TransferMetadata&) {})) {} + void FakeNearbySharingService::AddObserver(Observer* observer) { observers_.AddObserver(observer); } @@ -54,7 +75,7 @@ void FakeNearbySharingService::RegisterSendSurface( TransferUpdateCallback* transfer_callback, ShareTargetDiscoveredCallback* discovery_callback, SendSurfaceState state, Advertisement::BlockedVendorId blocked_vendor_id, bool disable_wifi_hotspot, - std::function status_codes_callback) { + absl::AnyInvocable status_codes_callback) { if (state == SendSurfaceState::kForeground) { foreground_send_surface_map_.insert( {transfer_callback, @@ -73,7 +94,7 @@ void FakeNearbySharingService::RegisterSendSurface( // Unregisters the current send surface. void FakeNearbySharingService::UnregisterSendSurface( TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) { + absl::AnyInvocable status_codes_callback) { foreground_send_surface_map_.erase(transfer_callback); background_send_surface_map_.erase(transfer_callback); @@ -84,7 +105,7 @@ void FakeNearbySharingService::UnregisterSendSurface( void FakeNearbySharingService::RegisterReceiveSurface( TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state, Advertisement::BlockedVendorId vendor_id, - std::function status_codes_callback) { + absl::AnyInvocable status_codes_callback) { if (state == ReceiveSurfaceState::kForeground) { foreground_receive_transfer_callbacks_.AddObserver(transfer_callback); } else { @@ -97,7 +118,7 @@ void FakeNearbySharingService::RegisterReceiveSurface( // Unregisters the current receive surface. void FakeNearbySharingService::UnregisterReceiveSurface( TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) { + absl::AnyInvocable status_codes_callback) { foreground_receive_transfer_callbacks_.RemoveObserver(transfer_callback); background_receive_transfer_callbacks_.RemoveObserver(transfer_callback); status_codes_callback(StatusCodes::kOk); @@ -105,7 +126,7 @@ void FakeNearbySharingService::UnregisterReceiveSurface( // Unregisters all foreground receive surfaces. void FakeNearbySharingService::ClearForegroundReceiveSurfaces( - std::function status_codes_callback) { + absl::AnyInvocable status_codes_callback) { status_codes_callback(StatusCodes::kOk); } @@ -148,11 +169,6 @@ std::string FakeNearbySharingService::Dump() const { return ""; } NearbyShareSettings* FakeNearbySharingService::GetSettings() { return nullptr; } -NearbyShareLocalDeviceDataManager* -FakeNearbySharingService::GetLocalDeviceDataManager() { - return nullptr; -} - NearbyShareContactManager* FakeNearbySharingService::GetContactManager() { return nullptr; } @@ -166,6 +182,14 @@ AccountManager* FakeNearbySharingService::GetAccountManager() { return nullptr; } +Clock& FakeNearbySharingService::GetClock() { return clock_; } + +SyncManager& FakeNearbySharingService::sync_manager() { return *sync_manager_; } + +OutgoingTargetsManager& FakeNearbySharingService::outgoing_targets_manager() { + return *outgoing_targets_manager_; +} + void FakeNearbySharingService::FireHighVisibilityChangeRequested() { for (auto& observer : observers_.GetObservers()) { observer->OnHighVisibilityChangeRequested(); @@ -229,28 +253,31 @@ void FakeNearbySharingService::FireReceiveTransferUpdate( // Fire discovery events. void FakeNearbySharingService::FireShareTargetDiscovered( - SendSurfaceState state, ShareTarget share_target) { - if (state == SendSurfaceState::kForeground) { - for (auto& entry : foreground_send_surface_map_) { - entry.second.OnShareTargetDiscovered(share_target); - } - } else { - for (auto& entry : background_send_surface_map_) { - entry.second.OnShareTargetDiscovered(share_target); - } + ShareTarget share_target) { + for (auto& entry : foreground_send_surface_map_) { + entry.second.OnShareTargetDiscovered(share_target); + } + for (auto& entry : background_send_surface_map_) { + entry.second.OnShareTargetDiscovered(share_target); } } -void FakeNearbySharingService::FireShareTargetLost(SendSurfaceState state, - ShareTarget share_target) { - if (state == SendSurfaceState::kForeground) { - for (auto& entry : foreground_send_surface_map_) { - entry.second.OnShareTargetLost(share_target); - } - } else { - for (auto& entry : background_send_surface_map_) { - entry.second.OnShareTargetLost(share_target); - } +void FakeNearbySharingService::FireShareTargetUpdated( + ShareTarget share_target) { + for (auto& entry : foreground_send_surface_map_) { + entry.second.OnShareTargetUpdated(share_target); + } + for (auto& entry : background_send_surface_map_) { + entry.second.OnShareTargetUpdated(share_target); + } +} + +void FakeNearbySharingService::FireShareTargetLost(ShareTarget share_target) { + for (auto& entry : foreground_send_surface_map_) { + entry.second.OnShareTargetLost(share_target); + } + for (auto& entry : background_send_surface_map_) { + entry.second.OnShareTargetLost(share_target); } } diff --git a/sharing/fake_nearby_sharing_service.h b/sharing/fake_nearby_sharing_service.h index 9aaf0376..2b56e41c 100644 --- a/sharing/fake_nearby_sharing_service.h +++ b/sharing/fake_nearby_sharing_service.h @@ -20,11 +20,16 @@ #include #include +#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" #include "absl/container/flat_hash_map.h" +#include "absl/functional/any_invocable.h" +#include "absl/time/time.h" #include "internal/base/observer_list.h" +#include "internal/platform/clock.h" #include "sharing/advertisement.h" #include "sharing/attachment_container.h" -#include "sharing/local_device_data/nearby_share_local_device_data_manager.h" +#include "sharing/certificates/nearby_share_certificate_manager.h" +#include "sharing/internal/api/preference_manager.h" #include "sharing/nearby_sharing_service.h" #include "sharing/nearby_sharing_settings.h" #include "sharing/share_target.h" @@ -32,12 +37,21 @@ #include "sharing/transfer_metadata.h" #include "sharing/transfer_update_callback.h" #include "sharing/wrapped_share_target_discovered_callback.h" +#include "internal/test/fake_clock.h" +#include "internal/test/fake_task_runner.h" +#include "location/nearby/sharing/lib/rpc/fake_nearby_share_client.h" +#include "location/nearby/sharing/lib/sync/sync_manager.h" +#include "sharing/analytics/analytics_recorder.h" +#include "sharing/fake_nearby_connections_manager.h" +#include "sharing/internal/test/fake_preference_manager.h" +#include "sharing/outgoing_targets_manager.h" namespace nearby { namespace sharing { class FakeNearbySharingService : public NearbySharingService { public: + FakeNearbySharingService(); ~FakeNearbySharingService() override = default; void AddObserver(Observer* observer) override; @@ -54,27 +68,27 @@ class FakeNearbySharingService : public NearbySharingService { ShareTargetDiscoveredCallback* discovery_callback, SendSurfaceState state, Advertisement::BlockedVendorId blocked_vendor_id, bool disable_wifi_hotspot, - std::function status_codes_callback) override; + absl::AnyInvocable status_codes_callback) override; // Unregisters the current send surface. void UnregisterSendSurface( TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) override; + absl::AnyInvocable status_codes_callback) override; // Registers a receiver surface for handling payload transfer status. void RegisterReceiveSurface( TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state, Advertisement::BlockedVendorId vendor_id, - std::function status_codes_callback) override; + absl::AnyInvocable status_codes_callback) override; // Unregisters the current receive surface. void UnregisterReceiveSurface( TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) override; + absl::AnyInvocable status_codes_callback) override; // Unregisters all foreground receive surfaces. void ClearForegroundReceiveSurfaces( - std::function status_codes_callback) override; + absl::AnyInvocable status_codes_callback) override; // Returns true if there is an ongoing file transfer. bool IsTransferring() const override; @@ -104,12 +118,39 @@ class FakeNearbySharingService : public NearbySharingService { status_codes_callback) override; std::string Dump() const override; + bool IsBluetoothPresent() const override { return true; } + bool IsBluetoothPowered() const override { return true; } + bool IsExtendedAdvertisingSupported() const override { return true; } + bool IsLanConnected() const override { return true; } + std::string GetQrCodeUrl() const override { return ""; } + void SetVisibility( + proto::DeviceVisibility visibility, absl::Duration expiration, + absl::AnyInvocable callback) override {} + void UpdateFilePathsInProgress(bool update_file_paths) override {} NearbyShareSettings* GetSettings() override; - NearbyShareLocalDeviceDataManager* GetLocalDeviceDataManager() override; NearbyShareContactManager* GetContactManager() override; NearbyShareCertificateManager* GetCertificateManager() override; AccountManager* GetAccountManager() override; + Clock& GetClock() override; + void SetAlternateServiceUuidForDiscovery( + uint16_t alternate_service_uuid) override {} + SyncManager& sync_manager() override; + OutgoingTargetsManager& outgoing_targets_manager() override; + + nearby::sharing::api::IdentityRpcClient& fake_identity_rpc_client() { + return identity_rpc_client_; + } + nearby::sharing::api::PreferenceManager& fake_preference_manager() { + return preference_manager_; + } + FakeNearbyConnectionsManager& fake_nearby_connections_manager() { + return connections_manager_; + } + FakeTaskRunner& fake_task_runner() { return service_thread_; } + analytics::AnalyticsRecorder& analytics_recorder() { + return analytics_recorder_; + } // Fake methods to support test scenarios. @@ -130,9 +171,9 @@ class FakeNearbySharingService : public NearbySharingService { TransferMetadata transfer_metadata); // Fire discovery events. - void FireShareTargetDiscovered(SendSurfaceState state, - ShareTarget share_target); - void FireShareTargetLost(SendSurfaceState state, ShareTarget share_target); + void FireShareTargetDiscovered(ShareTarget share_target); + void FireShareTargetUpdated(ShareTarget share_target); + void FireShareTargetLost(ShareTarget share_target); private: ObserverList observers_; @@ -147,6 +188,14 @@ class FakeNearbySharingService : public NearbySharingService { background_send_surface_map_; ObserverList foreground_receive_transfer_callbacks_; ObserverList background_receive_transfer_callbacks_; + FakeClock clock_; + FakeTaskRunner service_thread_; + FakeNearbyConnectionsManager connections_manager_; + analytics::AnalyticsRecorder analytics_recorder_; + FakePreferenceManager preference_manager_; + FakeNearbyIdentityClient identity_rpc_client_; + std::unique_ptr sync_manager_; + std::unique_ptr outgoing_targets_manager_; }; } // namespace sharing diff --git a/sharing/nearby_sharing_service.h b/sharing/nearby_sharing_service.h index f664367c..6460f3b8 100644 --- a/sharing/nearby_sharing_service.h +++ b/sharing/nearby_sharing_service.h @@ -20,14 +20,15 @@ #include #include +#include "location/nearby/sharing/lib/sync/sync_manager.h" #include "absl/functional/any_invocable.h" #include "absl/time/time.h" #include "internal/platform/clock.h" #include "sharing/advertisement.h" #include "sharing/attachment_container.h" #include "sharing/certificates/nearby_share_certificate_manager.h" -#include "sharing/local_device_data/nearby_share_local_device_data_manager.h" #include "sharing/nearby_sharing_settings.h" +#include "sharing/outgoing_targets_manager.h" #include "sharing/share_target_discovered_callback.h" #include "sharing/transfer_update_callback.h" @@ -140,28 +141,28 @@ class NearbySharingService { ShareTargetDiscoveredCallback* discovery_callback, SendSurfaceState state, Advertisement::BlockedVendorId blocked_vendor_id, bool disable_wifi_hotspot, - std::function status_codes_callback) = 0; + absl::AnyInvocable status_codes_callback) = 0; // Unregisters the current send surface. virtual void UnregisterSendSurface( TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) = 0; + absl::AnyInvocable status_codes_callback) = 0; // Registers a receiver surface for handling payload transfer status, and // advertises the vendor ID specified by |vendor_id|. virtual void RegisterReceiveSurface( TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state, Advertisement::BlockedVendorId vendor_id, - std::function status_codes_callback) = 0; + absl::AnyInvocable status_codes_callback) = 0; // Unregisters the current receive surface. virtual void UnregisterReceiveSurface( TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) = 0; + absl::AnyInvocable status_codes_callback) = 0; // Unregisters all foreground receive surfaces. virtual void ClearForegroundReceiveSurfaces( - std::function status_codes_callback) = 0; + absl::AnyInvocable status_codes_callback) = 0; // Returns true if there is an ongoing file transfer. virtual bool IsTransferring() const = 0; @@ -215,13 +216,14 @@ class NearbySharingService { virtual void UpdateFilePathsInProgress(bool update_file_paths) = 0; virtual NearbyShareSettings* GetSettings() = 0; - virtual NearbyShareLocalDeviceDataManager* GetLocalDeviceDataManager() = 0; virtual NearbyShareContactManager* GetContactManager() = 0; virtual NearbyShareCertificateManager* GetCertificateManager() = 0; virtual AccountManager* GetAccountManager() = 0; virtual Clock& GetClock() = 0; virtual void SetAlternateServiceUuidForDiscovery( uint16_t alternate_service_uuid) = 0; + virtual SyncManager& sync_manager() = 0; + virtual OutgoingTargetsManager& outgoing_targets_manager() = 0; }; } // namespace nearby::sharing diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 5a59f2e8..caaa3c05 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -430,16 +430,16 @@ void NearbySharingServiceImpl::RegisterSendSurface( TransferUpdateCallback* transfer_callback, ShareTargetDiscoveredCallback* discovery_callback, SendSurfaceState state, BlockedVendorId blocked_vendor_id, bool disable_wifi_hotspot, - std::function status_codes_callback) { + absl::AnyInvocable status_codes_callback) { RunOnNearbySharingServiceThread( "api_register_send_surface", [this, transfer_callback, discovery_callback, state, blocked_vendor_id, disable_wifi_hotspot, - status_codes_callback = std::move(status_codes_callback)]() { + status_codes_callback = std::move(status_codes_callback)]() mutable { if (state != SendSurfaceState::kForeground && state != SendSurfaceState::kBackground) { LOG(ERROR) << "Invalid SendSurfaceState: " << static_cast(state); - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); + status_codes_callback(StatusCodes::kInvalidArgument); return; } DCHECK(transfer_callback); @@ -456,7 +456,7 @@ void NearbySharingServiceImpl::RegisterSendSurface( background_send_surface_map_.contains(transfer_callback)) { VLOG(1) << "RegisterSendSurface failed. Already registered for a " "different state."; - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); + status_codes_callback(StatusCodes::kInvalidArgument); return; } BlockedVendorId sending_id = GetSendingVendorId(); @@ -464,7 +464,7 @@ void NearbySharingServiceImpl::RegisterSendSurface( LOG(INFO) << "RegisterSendSurface failed. Already registered to " "block a different vendor ID " << static_cast(sending_id); - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); + status_codes_callback(StatusCodes::kInvalidArgument); return; } WrappedShareTargetDiscoveredCallback wrapped_callback( @@ -483,8 +483,7 @@ void NearbySharingServiceImpl::RegisterSendSurface( VLOG(1) << "Ignore registering (and unregistering if registered) send " "surface because we're currently receiving files."; - std::move(status_codes_callback)( - StatusCodes::kTransferAlreadyInProgress); + status_codes_callback(StatusCodes::kTransferAlreadyInProgress); return; } @@ -538,17 +537,17 @@ void NearbySharingServiceImpl::RegisterSendSurface( << background_send_surface_map_.size(); InvalidateSendSurfaceState(); - std::move(status_codes_callback)(StatusCodes::kOk); + status_codes_callback(StatusCodes::kOk); }); } void NearbySharingServiceImpl::UnregisterSendSurface( TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) { + absl::AnyInvocable status_codes_callback) { RunOnNearbySharingServiceThread( "api_unregister_send_surface", [this, transfer_callback, - status_codes_callback = std::move(status_codes_callback)]() { + status_codes_callback = std::move(status_codes_callback)]() mutable { StatusCodes status_codes = InternalUnregisterSendSurface(transfer_callback); @@ -557,23 +556,23 @@ void NearbySharingServiceImpl::UnregisterSendSurface( << ", background_send_surface_map_:" << background_send_surface_map_.size(); - std::move(status_codes_callback)(status_codes); + status_codes_callback(status_codes); }); } void NearbySharingServiceImpl::RegisterReceiveSurface( TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state, BlockedVendorId vendor_id, - std::function status_codes_callback) { + absl::AnyInvocable status_codes_callback) { RunOnNearbySharingServiceThread( "api_register_receive_surface", [this, transfer_callback, state, vendor_id, - status_codes_callback = std::move(status_codes_callback)]() { + status_codes_callback = std::move(status_codes_callback)]() mutable { if (state != ReceiveSurfaceState::kForeground && state != ReceiveSurfaceState::kBackground) { LOG(ERROR) << "Invalid ReceiveSurfaceState: " << static_cast(state); - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); + status_codes_callback(StatusCodes::kInvalidArgument); return; } DCHECK(transfer_callback); @@ -591,14 +590,14 @@ void NearbySharingServiceImpl::RegisterReceiveSurface( if (GetReceiveCallbacksMapFromState(state).contains( transfer_callback)) { VLOG(1) << "transfer callback already registered, ignoring"; - std::move(status_codes_callback)(StatusCodes::kOk); + status_codes_callback(StatusCodes::kOk); return; } if (foreground_receive_callbacks_map_.contains(transfer_callback) || background_receive_callbacks_map_.contains(transfer_callback)) { LOG(ERROR) << ": transfer callback already registered but for a " "different state."; - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); + status_codes_callback(StatusCodes::kInvalidArgument); return; } if (ShouldBlockSurfaceRegistration(vendor_id, @@ -609,7 +608,7 @@ void NearbySharingServiceImpl::RegisterReceiveSurface( << static_cast(vendor_id) << " because the current vendor_id is " << static_cast(GetReceivingVendorId()); - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); + status_codes_callback(StatusCodes::kInvalidArgument); return; } @@ -652,33 +651,34 @@ void NearbySharingServiceImpl::RegisterReceiveSurface( certificate_manager_->ForceUploadPrivateCertificates(); } InvalidateReceiveSurfaceState(); - std::move(status_codes_callback)(StatusCodes::kOk); + status_codes_callback(StatusCodes::kOk); }); } void NearbySharingServiceImpl::UnregisterReceiveSurface( TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) { + absl::AnyInvocable status_codes_callback) { RunOnNearbySharingServiceThread( "api_unregister_receive_surface", [this, transfer_callback, - status_codes_callback = std::move(status_codes_callback)]() { + status_codes_callback = std::move(status_codes_callback)]() mutable { StatusCodes status_codes = InternalUnregisterReceiveSurface(transfer_callback); VLOG(1) << "UnregisterReceiveSurface: foreground_receive_callbacks_:" << foreground_receive_callbacks_map_.size() << ", background_receive_callbacks_:" << background_receive_callbacks_map_.size(); - std::move(status_codes_callback)(status_codes); + status_codes_callback(status_codes); return; }); } void NearbySharingServiceImpl::ClearForegroundReceiveSurfaces( - std::function status_codes_callback) { + absl::AnyInvocable status_codes_callback) { RunOnNearbySharingServiceThread( "api_clear_foreground_receive_surfaces", - [this, status_codes_callback = std::move(status_codes_callback)]() { + [this, + status_codes_callback = std::move(status_codes_callback)]() mutable { std::vector fg_receivers; for (const auto& callback : foreground_receive_callbacks_map_) { fg_receivers.push_back(callback.first); @@ -689,7 +689,7 @@ void NearbySharingServiceImpl::ClearForegroundReceiveSurfaces( if (InternalUnregisterReceiveSurface(callback) != StatusCodes::kOk) status = StatusCodes::kError; } - std::move(status_codes_callback)(status); + status_codes_callback(status); }); } @@ -976,11 +976,6 @@ NearbyShareSettings* NearbySharingServiceImpl::GetSettings() { return settings_.get(); } -NearbyShareLocalDeviceDataManager* -NearbySharingServiceImpl::GetLocalDeviceDataManager() { - return local_device_data_manager_.get(); -} - NearbyShareContactManager* NearbySharingServiceImpl::GetContactManager() { return contact_manager_.get(); } diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index fc3eeae8..1e082a7b 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -122,19 +122,19 @@ class NearbySharingServiceImpl ShareTargetDiscoveredCallback* discovery_callback, SendSurfaceState state, Advertisement::BlockedVendorId blocked_vendor_id, bool disable_wifi_hotspot, - std::function status_codes_callback) override; + absl::AnyInvocable status_codes_callback) override; void UnregisterSendSurface( TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) override; + absl::AnyInvocable status_codes_callback) override; void RegisterReceiveSurface( TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state, Advertisement::BlockedVendorId vendor_id, - std::function status_codes_callback) override; + absl::AnyInvocable status_codes_callback) override; void UnregisterReceiveSurface( TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) override; + absl::AnyInvocable status_codes_callback) override; void ClearForegroundReceiveSurfaces( - std::function status_codes_callback) override; + absl::AnyInvocable status_codes_callback) override; bool IsTransferring() const override; bool IsScanning() const override; bool IsBluetoothPresent() const override; @@ -159,7 +159,6 @@ class NearbySharingServiceImpl proto::DeviceVisibility visibility, absl::Duration expiration, absl::AnyInvocable callback) override; NearbyShareSettings* GetSettings() override; - NearbyShareLocalDeviceDataManager* GetLocalDeviceDataManager() override; NearbyShareContactManager* GetContactManager() override; NearbyShareCertificateManager* GetCertificateManager() override; AccountManager* GetAccountManager() override; @@ -168,6 +167,10 @@ class NearbySharingServiceImpl uint16_t alternate_service_uuid) override { alternate_service_uuid_ = alternate_service_uuid; } + SyncManager& sync_manager() override { return sync_manager_; } + OutgoingTargetsManager& outgoing_targets_manager() override { + return outgoing_targets_manager_; + } // NearbyConnectionsManager::IncomingConnectionListener: void OnIncomingConnection(absl::string_view endpoint_id, diff --git a/sharing/outgoing_targets_manager.cc b/sharing/outgoing_targets_manager.cc index 86087baa..eeb490d4 100644 --- a/sharing/outgoing_targets_manager.cc +++ b/sharing/outgoing_targets_manager.cc @@ -342,4 +342,19 @@ void OutgoingTargetsManager::ForEachShareTarget( } } +std::vector OutgoingTargetsManager::GetBindingIds( + int64_t share_target_id) { + std::vector binding_ids; + auto session_it = outgoing_share_session_map_.find(share_target_id); + if (session_it == outgoing_share_session_map_.end()) { + return {}; + } + std::optional certificate = + session_it->second.certificate(); + if (certificate.has_value()) { + return {certificate->binding_id()}; + } + return {}; +} + } // namespace nearby::sharing diff --git a/sharing/outgoing_targets_manager.h b/sharing/outgoing_targets_manager.h index 6917f0e4..7da8d2b4 100644 --- a/sharing/outgoing_targets_manager.h +++ b/sharing/outgoing_targets_manager.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "absl/base/nullability.h" #include "absl/container/flat_hash_map.h" @@ -94,6 +95,8 @@ class OutgoingTargetsManager { void ForEachShareTarget( absl::AnyInvocable callback); + std::vector GetBindingIds(int64_t share_target_id); + private: // If an existing target matching either endpoint_id or share_target.device_id // is found, the existing share target id is returned. diff --git a/sharing/outgoing_targets_manager_test.cc b/sharing/outgoing_targets_manager_test.cc index 60965259..e6f696eb 100644 --- a/sharing/outgoing_targets_manager_test.cc +++ b/sharing/outgoing_targets_manager_test.cc @@ -27,6 +27,8 @@ #include "internal/test/fake_task_runner.h" #include "sharing/analytics/analytics_recorder.h" #include "sharing/attachment_container.h" +#include "sharing/certificates/nearby_share_decrypted_public_certificate.h" +#include "sharing/certificates/test_util.h" #include "sharing/fake_nearby_connections_manager.h" #include "sharing/nearby_connection_impl.h" #include "sharing/nearby_connections_types.h" @@ -781,5 +783,36 @@ TEST_F(OutgoingTargetsManagerTest, AllTargetsLostConnectedSessionsNotClosed) { nullptr); } +TEST_F(OutgoingTargetsManagerTest, GetBindingIds_NonExistentTarget) { + EXPECT_TRUE(outgoing_targets_manager_.GetBindingIds(1234).empty()); +} + +TEST_F(OutgoingTargetsManagerTest, GetBindingIds_NoCertificate) { + constexpr int kShareTargetId = 1234; + constexpr absl::string_view kEndpointId = "endpoint_id"; + ShareTarget target; + target.id = kShareTargetId; + + outgoing_targets_manager_.OnShareTargetDiscovered( + target, kEndpointId, /*certificate=*/std::nullopt); + + EXPECT_TRUE(outgoing_targets_manager_.GetBindingIds(kShareTargetId).empty()); +} + +TEST_F(OutgoingTargetsManagerTest, GetBindingIds_WithCertificate) { + constexpr int kShareTargetId = 1234; + constexpr absl::string_view kEndpointId = "endpoint_id"; + ShareTarget target; + target.id = kShareTargetId; + NearbyShareDecryptedPublicCertificate cert = + GetNearbyShareTestDecryptedPublicCertificate(); + + outgoing_targets_manager_.OnShareTargetDiscovered(target, kEndpointId, cert); + + std::vector binding_ids = + outgoing_targets_manager_.GetBindingIds(kShareTargetId); + EXPECT_THAT(binding_ids, ElementsAre(cert.binding_id())); +} + } // namespace } // namespace nearby::sharing From c0db20961d007dc10edda1b4634d6b3a4b85f566 Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 16 Mar 2026 16:29:37 -0700 Subject: [PATCH 018/151] Remove AutoReconnection code PiperOrigin-RevId: 884691071 --- connections/implementation/client_proxy.cc | 19 +++--------- connections/implementation/client_proxy.h | 8 ----- .../implementation/endpoint_manager.cc | 4 --- .../implementation/endpoint_manager_test.cc | 7 ++--- .../flags/nearby_connections_feature_flags.h | 6 ++-- connections/implementation/offline_frames.cc | 25 ---------------- connections/implementation/offline_frames.h | 2 -- .../implementation/offline_frames_test.cc | 29 ------------------- connections/implementation/simulation_user.h | 7 ++--- internal/platform/feature_flags.h | 8 ----- 10 files changed, 10 insertions(+), 105 deletions(-) diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index d53e1a18..df7ec898 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -119,14 +119,11 @@ ClientProxy::ClientProxy(::nearby::analytics::EventLogger* event_logger) supports_safe_to_disconnect_ = NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature:: kEnableSafeToDisconnect); - support_auto_reconnect_ = NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature::kEnableAutoReconnect); - local_safe_to_disconnect_version_ = NearbyFlags::GetInstance().GetInt64Flag( - config_package_nearby::nearby_connections_feature:: - kSafeToDisconnectVersion); LOG(INFO) << "[safe-to-disconnect]: Local enabled: " - << supports_safe_to_disconnect_ - << "; Version: " << local_safe_to_disconnect_version_; + << supports_safe_to_disconnect_ << "; Version: " + << NearbyFlags::GetInstance().GetInt64Flag( + config_package_nearby::nearby_connections_feature:: + kSafeToDisconnectVersion); // Generate a 7 bits dedup value. absl::BitGen bitgen; dct_dedup_ = absl::Uniform(bitgen, 0, 1 << 7); @@ -1008,14 +1005,6 @@ bool ClientProxy::IsSafeToDisconnectEnabled(absl::string_view endpoint_id) { .min_nc_version_supports_safe_to_disconnect); } -bool ClientProxy::IsAutoReconnectEnabled(absl::string_view endpoint_id) { - return IsSupportAutoReconnect() && - GetRemoteSafeToDisconnectVersion(endpoint_id).has_value() && - (GetRemoteSafeToDisconnectVersion(endpoint_id) >= - FeatureFlags::GetInstance() - .GetFlags() - .min_nc_version_supports_auto_reconnect); -} bool ClientProxy::IsPayloadReceivedAckEnabled(absl::string_view endpoint_id) { return IsSupportSafeToDisconnect() && diff --git a/connections/implementation/client_proxy.h b/connections/implementation/client_proxy.h index 05406a27..685765a8 100644 --- a/connections/implementation/client_proxy.h +++ b/connections/implementation/client_proxy.h @@ -303,18 +303,12 @@ class ClientProxy final { return supports_safe_to_disconnect_; } - bool IsSupportAutoReconnect() const { return support_auto_reconnect_; } - - const std::int32_t& GetLocalSafeToDisconnectVersion() const { - return local_safe_to_disconnect_version_; - } std::optional GetRemoteSafeToDisconnectVersion( absl::string_view endpoint_id) const; void SetRemoteSafeToDisconnectVersion( absl::string_view endpoint_id, const std::int32_t& safe_to_disconnect_version); bool IsSafeToDisconnectEnabled(absl::string_view endpoint_id); - bool IsAutoReconnectEnabled(absl::string_view endpoint_id); bool IsPayloadReceivedAckEnabled(absl::string_view endpoint_id); // Returns the multiplex socket supports status for local device. @@ -549,8 +543,6 @@ class ClientProxy final { // For Nearby Connections' own device provider. std::unique_ptr connections_device_provider_; bool supports_safe_to_disconnect_; - bool support_auto_reconnect_; - std::int32_t local_safe_to_disconnect_version_; // Allowed to use WebRTC over non-cellular networks. bool webrtc_non_cellular_ = false; // Whether DCT is enabled. diff --git a/connections/implementation/endpoint_manager.cc b/connections/implementation/endpoint_manager.cc index ecde9b08..15fdd726 100644 --- a/connections/implementation/endpoint_manager.cc +++ b/connections/implementation/endpoint_manager.cc @@ -782,10 +782,6 @@ void EndpointManager::RemoveEndpoint(ClientProxy* client, << (safe_disconnect_result ? "true" : "false"); } } - if (safe_disconnect_result == - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION) { - // TODO(b/297259496): Autoreconnect - } // Unregistering from channel_manager_ will also serve to terminate // the dedicated handler and KeepAlive threads we started when we registered diff --git a/connections/implementation/endpoint_manager_test.cc b/connections/implementation/endpoint_manager_test.cc index 0f906e3c..d9a01b9a 100644 --- a/connections/implementation/endpoint_manager_test.cc +++ b/connections/implementation/endpoint_manager_test.cc @@ -136,16 +136,13 @@ class MockFrameProcessor : public EndpointManager::FrameProcessor { class SetSafeToDisconnect { public: - SetSafeToDisconnect(bool safe_to_disconnect, bool auto_reconnect, + SetSafeToDisconnect(bool safe_to_disconnect, bool payload_received_ack, std::int32_t safe_to_disconnect_version) { NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature:: kEnableSafeToDisconnect, safe_to_disconnect); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature::kEnableAutoReconnect, - auto_reconnect); NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature:: kEnablePayloadReceivedAck, @@ -187,7 +184,7 @@ class EndpointManagerTest : public ::testing::Test { EXPECT_TRUE(done.Await(absl::Milliseconds(1000)).result()); } } - SetSafeToDisconnect set_safe_to_disconnect_{true, false, true, 5}; + SetSafeToDisconnect set_safe_to_disconnect_{true, true, 5}; std::unique_ptr client_ = std::make_unique(); ConnectionOptions connection_options_{ .keep_alive_interval_millis = 5000, diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h index f241106d..e26b11e1 100644 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -37,9 +37,6 @@ constexpr auto kDisableInstantOnLostOnBleWithoutExtended = // When true, enable advertising for instant on lost feature. constexpr auto kEnableAdvertisingForInstantOnLost = flags::Flag(kConfigPackage, "45708614", true); -// Enable/Disable auto_reconnect feature. -constexpr auto kEnableAutoReconnect = - flags::Flag(kConfigPackage, "45427690", false); // Enable/Disable AWDL in Nearby connections SDK. constexpr auto kEnableAwdl = flags::Flag(kConfigPackage, "45690762", false); @@ -109,7 +106,8 @@ constexpr auto kRefactorBleL2cap = constexpr auto kEnableSharedPeripheralManager = flags::Flag(kConfigPackage, "45770787", false); // Set the safe-to-disconnect version. -// 0. Disabled all. 1. safe-to-disconnect 2. reserved 3. auto-reconnect +// 0. Disabled all. 1. safe-to-disconnect 2. reserved 3. +// auto-reconnect(deprecated) // 4. auto-resume 5. non-distance-constraint-recovery 6. payload_ack constexpr auto kSafeToDisconnectVersion = flags::Flag(kConfigPackage, "45425841", 0); diff --git a/connections/implementation/offline_frames.cc b/connections/implementation/offline_frames.cc index ce7ff30e..45b91311 100644 --- a/connections/implementation/offline_frames.cc +++ b/connections/implementation/offline_frames.cc @@ -38,7 +38,6 @@ namespace { using ExceptionOrOfflineFrame = ExceptionOr<::location::nearby::connections::OfflineFrame>; -using ::location::nearby::connections::AutoReconnectFrame; using ::location::nearby::connections::BandwidthUpgradeNegotiationFrame; using ::location::nearby::connections::ConnectionRequestFrame; using ::location::nearby::connections::ConnectionResponseFrame; @@ -574,30 +573,6 @@ ByteArray ForDisconnection(bool request_safe_to_disconnect, return ToBytes(std::move(frame)); } -ByteArray ForAutoReconnectIntroduction(const std::string& endpoint_id) { - OfflineFrame frame; - - frame.set_version(OfflineFrame::V1); - auto* v1_frame = frame.mutable_v1(); - v1_frame->set_type(V1Frame::AUTO_RECONNECT); - auto* auto_reconnect = v1_frame->mutable_auto_reconnect(); - auto_reconnect->set_endpoint_id(endpoint_id); - auto_reconnect->set_event_type(AutoReconnectFrame::CLIENT_INTRODUCTION); - - return ToBytes(std::move(frame)); -} - -ByteArray ForAutoReconnectIntroductionAck() { - OfflineFrame frame; - - frame.set_version(OfflineFrame::V1); - auto* v1_frame = frame.mutable_v1(); - v1_frame->set_type(V1Frame::AUTO_RECONNECT); - auto* auto_reconnect = v1_frame->mutable_auto_reconnect(); - auto_reconnect->set_event_type(AutoReconnectFrame::CLIENT_INTRODUCTION_ACK); - - return ToBytes(std::move(frame)); -} UpgradePathInfo::Medium MediumToUpgradePathInfoMedium(Medium medium) { switch (medium) { diff --git a/connections/implementation/offline_frames.h b/connections/implementation/offline_frames.h index 36567eba..e8e4b7d9 100644 --- a/connections/implementation/offline_frames.h +++ b/connections/implementation/offline_frames.h @@ -117,8 +117,6 @@ ByteArray ForKeepAlive(); ByteArray ForKeepAlive(bool ack, uint32_t seq_num); ByteArray ForDisconnection(bool request_safe_to_disconnect, bool ack_safe_to_disconnect); -ByteArray ForAutoReconnectIntroduction(const std::string& endpoint_id); -ByteArray ForAutoReconnectIntroductionAck(); UpgradePathInfo::Medium MediumToUpgradePathInfoMedium(Medium medium); Medium UpgradePathInfoMediumToMedium(UpgradePathInfo::Medium medium); diff --git a/connections/implementation/offline_frames_test.cc b/connections/implementation/offline_frames_test.cc index 2f3f7965..e52099ef 100644 --- a/connections/implementation/offline_frames_test.cc +++ b/connections/implementation/offline_frames_test.cc @@ -737,35 +737,6 @@ TEST(OfflineFramesTest, CanGenerateDisconnection) { EXPECT_THAT(message, EqualsProto(kExpected)); } -TEST(OfflineFramesTest, CanGenerateAutoReconnectIntroduction) { - constexpr absl::string_view kExpected = - R"pb( - version: V1 - v1: < - type: AUTO_RECONNECT - auto_reconnect: < event_type: CLIENT_INTRODUCTION endpoint_id: "ABC" > - >)pb"; - ByteArray bytes = ForAutoReconnectIntroduction(std::string(kEndpointId)); - auto response = FromBytes(bytes); - ASSERT_TRUE(response.ok()); - OfflineFrame message = response.result(); - EXPECT_THAT(message, EqualsProto(kExpected)); -} - -TEST(OfflineFramesTest, CanGenerateAutoReconnectIntroductionAck) { - constexpr absl::string_view kExpected = - R"pb( - version: V1 - v1: < - type: AUTO_RECONNECT - auto_reconnect: < event_type: CLIENT_INTRODUCTION_ACK > - >)pb"; - ByteArray bytes = ForAutoReconnectIntroductionAck(); - auto response = FromBytes(bytes); - ASSERT_TRUE(response.ok()); - OfflineFrame message = response.result(); - EXPECT_THAT(message, EqualsProto(kExpected)); -} TEST(OfflineFramesTest, CanGenerateBwuPathRequest) { constexpr absl::string_view kExpected = diff --git a/connections/implementation/simulation_user.h b/connections/implementation/simulation_user.h index 417ab2f8..b257dc0b 100644 --- a/connections/implementation/simulation_user.h +++ b/connections/implementation/simulation_user.h @@ -46,16 +46,13 @@ namespace connections { class SetSafeToDisconnect { public: - explicit SetSafeToDisconnect(bool safe_to_disconnect, bool auto_reconnect, + explicit SetSafeToDisconnect(bool safe_to_disconnect, bool payload_received_ack, std::int32_t safe_to_disconnect_version) { NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature:: kEnableSafeToDisconnect, safe_to_disconnect); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature::kEnableAutoReconnect, - auto_reconnect); NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature:: kEnablePayloadReceivedAck, @@ -81,7 +78,7 @@ class SimulationUser { SimulationUser(const std::string& device_name, BooleanMediumSelector allowed = BooleanMediumSelector(), SetSafeToDisconnect set_safe_to_disconnect = - SetSafeToDisconnect(true, false, true, 5)) + SetSafeToDisconnect(true, true, 5)) : info_{ByteArray{device_name}}, advertising_options_{ { diff --git a/internal/platform/feature_flags.h b/internal/platform/feature_flags.h index cad1ba6a..a4483839 100644 --- a/internal/platform/feature_flags.h +++ b/internal/platform/feature_flags.h @@ -75,14 +75,6 @@ class FeatureFlags { // auto-resume 5. non-distance-constraint-recovery 6. payload_ack std::int32_t min_nc_version_supports_safe_to_disconnect = 1; std::int32_t min_nc_version_supports_auto_reconnect = 3; - absl::Duration safe_to_disconnect_reconnect_retry_delay_millis = - absl::Milliseconds(4000); - absl::Duration safe_to_disconnect_reconnect_timeout_millis = - absl::Milliseconds(15000); - std::int32_t safe_to_disconnect_reconnect_retry_attempts = 3; - absl::Duration - safe_to_disconnect_reconnect_skip_duplicated_endpoint_duration = - absl::Milliseconds(2000); // Android code won't be able to launch "payload_received_ack" feature for // in near future, so change "payload_received_ack" version from "2" to "5" // after auto-reconnect and auto-resume. From 614563c3fe055278db4eb5950804944fc1fbfd7c Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 16 Mar 2026 22:31:00 -0700 Subject: [PATCH 019/151] Refactor OutgoingShareSession to handle both transfers and pairing. PiperOrigin-RevId: 884809727 --- sharing/nearby_sharing_service_impl.cc | 74 ++++++++++++++++---------- sharing/nearby_sharing_service_impl.h | 6 ++- sharing/outgoing_share_session.cc | 2 +- sharing/outgoing_share_session.h | 7 ++- 4 files changed, 56 insertions(+), 33 deletions(-) diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index caaa3c05..0d08d02e 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -737,16 +737,6 @@ void NearbySharingServiceImpl::SendAttachments( return; } } - // Outgoing connections always announces with contacts visibility. - std::optional> endpoint_info = - CreateEndpointInfo(DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, - local_device_data_manager_->GetDeviceName()); - if (!endpoint_info) { - LOG(WARNING) << "Could not create local endpoint info."; - std::move(status_codes_callback)(StatusCodes::kError); - return; - } - OutgoingShareSession* session = outgoing_targets_manager_.GetOutgoingShareSession(share_target_id); if (!session) { @@ -754,29 +744,39 @@ void NearbySharingServiceImpl::SendAttachments( std::move(status_codes_callback)(StatusCodes::kInvalidArgument); return; } - - app_info_->SetActiveFlag(); - + StatusCodes status_code = StatusCodes::kOk; if (session->InitiateSendAttachments( - std::move(attachment_container))) { - OutgoingSessionConnect(*session, std::move(*endpoint_info)); + std::move(attachment_container ))) { + status_code = ConnectOutgoingSessionOnServiceThread(*session); } - std::move(status_codes_callback)(StatusCodes::kOk); + std::move(status_codes_callback)(status_code); }); } -void NearbySharingServiceImpl::OutgoingSessionConnect( - OutgoingShareSession& session, std::vector endpoint_info) { +NearbySharingService::StatusCodes +NearbySharingServiceImpl::ConnectOutgoingSessionOnServiceThread( + OutgoingShareSession& session) { + // Outgoing connections always announces with contacts visibility. + std::optional> endpoint_info = + CreateEndpointInfo(DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, + local_device_data_manager_->GetDeviceName()); + if (!endpoint_info) { + LOG(WARNING) << "Could not create local endpoint info."; + return StatusCodes::kError; + } + app_info_->SetActiveFlag(); + OnTransferStarted(/*is_incoming=*/false); is_connecting_ = true; InvalidateSendSurfaceState(); int64_t share_target_id = session.share_target().id; session.Connect( - std::move(endpoint_info), settings_->GetDataUsage(), + std::move(*endpoint_info), settings_->GetDataUsage(), GetDisableWifiHotspotState(), absl::bind_front(&NearbySharingServiceImpl::OnOutgoingConnection, this, share_target_id)); + return StatusCodes::kOk; } bool NearbySharingServiceImpl::OutgoingSessionAccept( @@ -1366,7 +1366,7 @@ void NearbySharingServiceImpl::AdapterPresentChanged( void NearbySharingServiceImpl::AdapterPoweredChanged( sharing::api::BluetoothAdapter* adapter, bool powered) { - // When adpater is powered on, it takes some time for the RFCOMM service to + // When adapter is powered on, it takes some time for the RFCOMM service to // be ready. If we don't wait the RfCommServiceProvider::CreateAsync() call // fails with a "device is not ready for use" error. // Waiting 500ms seems to be enough to allow it to reliably work. @@ -2521,10 +2521,19 @@ void NearbySharingServiceImpl::OnOutgoingConnectionKeyVerificationDone( session->Abort(TransferMetadata::Status::kDeviceAuthenticationFailed); return; } + if (session->is_transfer_session()) { + BeginOutgoingTransfer(*session); + } else { + BeginOutgoingPairing(*session); + } +} +void NearbySharingServiceImpl::BeginOutgoingTransfer( + OutgoingShareSession& session) { VLOG(1) << __func__ << ": Preparing to send introduction to " - << share_target_id; - if (!session->SendIntroduction([this, share_target_id]() { + << session.share_target().id; + if (!session.SendIntroduction([this, share_target_id = + session.share_target().id]() { VLOG(1) << "Outgoing mutual acceptance timed out, closing connection for " << share_target_id; @@ -2537,27 +2546,34 @@ void NearbySharingServiceImpl::OnOutgoingConnectionKeyVerificationDone( })) { LOG(WARNING) << __func__ << ": No payloads tied to transfer, disconnecting."; - session->Abort(TransferMetadata::Status::kMediaUnavailable); + session.Abort(TransferMetadata::Status::kMediaUnavailable); return; } // Auto Accept if key verification is successful or skip sender confirmation. bool protection_enabled = preference_manager_.GetBoolean(PrefNames::kAdvancedProtectionEnabled, /*default_value=*/false); - session->SetAdvancedProtectionStatus(protection_enabled, - /*advanced_protection_mismatch=*/false); - if (session->token().empty() || !protection_enabled) { + session.SetAdvancedProtectionStatus(protection_enabled, + /*advanced_protection_mismatch=*/false); + if (session.token().empty() || !protection_enabled) { // Auto accept if no token or if advanced protection is disabled. - OutgoingSessionAccept(*session); + OutgoingSessionAccept(session); } else { - session->UpdateTransferMetadata( + session.UpdateTransferMetadata( TransferMetadataBuilder() .set_status(TransferMetadata::Status::kAwaitingLocalConfirmation) - .set_token(session->token()) + .set_token(session.token()) .build()); } } +void NearbySharingServiceImpl::BeginOutgoingPairing( + OutgoingShareSession& session) { + VLOG(1) << __func__ << ": Preparing to initiate pairing with " + << session.share_target().id; + // TODO(ftsui): Implement this. +} + void NearbySharingServiceImpl::OnReceivedIntroduction( IncomingShareSession& session, const IntroductionFrame& frame) { LOG(INFO) << __func__ << ": Successfully read the introduction frame."; diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index 1e082a7b..b3528bc3 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -293,8 +293,8 @@ class NearbySharingServiceImpl absl::string_view endpoint_id, NearbyConnection* connection, Status status); - void OutgoingSessionConnect(OutgoingShareSession& session, - std::vector endpoint_info); + StatusCodes ConnectOutgoingSessionOnServiceThread( + OutgoingShareSession& session); void Fail(IncomingShareSession& session, TransferMetadata::Status status); void OnIncomingAdvertisementDecoded( @@ -317,6 +317,8 @@ class NearbySharingServiceImpl int64_t share_target_id, PairedKeyVerificationRunner::PairedKeyVerificationResult result, ::location::nearby::proto::sharing::OSType share_target_os_type); + void BeginOutgoingTransfer(OutgoingShareSession& session); + void BeginOutgoingPairing(OutgoingShareSession& session); void OnIncomingSessionFrameRead( int64_t share_target_id, bool is_timeout, diff --git a/sharing/outgoing_share_session.cc b/sharing/outgoing_share_session.cc index 2522d02a..0073f259 100644 --- a/sharing/outgoing_share_session.cc +++ b/sharing/outgoing_share_session.cc @@ -40,7 +40,6 @@ #include "sharing/nearby_connections_manager.h" #include "sharing/nearby_connections_types.h" #include "sharing/nearby_sharing_util.h" -#include "sharing/paired_key_verification_runner.h" #include "sharing/payload_tracker.h" #include "sharing/share_session.h" #include "sharing/share_target.h" @@ -151,6 +150,7 @@ void OutgoingShareSession::InvokeTransferUpdateCallback( bool OutgoingShareSession::InitiateSendAttachments( std::unique_ptr attachment_container) { SetAttachmentContainer(std::move(*attachment_container)); + is_transfer_session_ = true; is_connecting_ = true; // Set session ID. diff --git a/sharing/outgoing_share_session.h b/sharing/outgoing_share_session.h index 21b8b8e6..d7a37430 100644 --- a/sharing/outgoing_share_session.h +++ b/sharing/outgoing_share_session.h @@ -34,7 +34,6 @@ #include "sharing/nearby_connection.h" #include "sharing/nearby_connections_manager.h" #include "sharing/nearby_connections_types.h" -#include "sharing/paired_key_verification_runner.h" #include "sharing/proto/enums.pb.h" #include "sharing/share_session.h" #include "sharing/share_target.h" @@ -159,6 +158,10 @@ class OutgoingShareSession : public ShareSession { const std::vector& file_payloads() const { return file_payloads_; } + // Returns true if the session is a transfer session. + // Otherwise, it is a pairing session. + bool is_transfer_session() const { return is_transfer_session_; } + protected: void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override; void OnConnectionDisconnected() override; @@ -196,6 +199,8 @@ class OutgoingShareSession : public ShareSession { bool advanced_protection_enabled_ = false; bool advanced_protection_mismatch_ = false; bool is_connecting_ = false; + // Session can be for transfer or pairing. + bool is_transfer_session_ = false; }; } // namespace nearby::sharing From 2d13fb2750700244a1d17062e75d02a581964dc9 Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 16 Mar 2026 22:43:52 -0700 Subject: [PATCH 020/151] Replace libjingle_peerconnection_api with the proper dependencies. PiperOrigin-RevId: 884814527 --- connections/implementation/mediums/BUILD | 3 ++- .../implementation/mediums/webrtc/BUILD | 10 +++++--- internal/platform/BUILD | 3 ++- internal/platform/implementation/BUILD | 3 ++- internal/platform/implementation/apple/BUILD | 4 ++-- internal/platform/implementation/g3/BUILD | 6 ++--- .../platform/implementation/windows/BUILD | 24 ++++++++++--------- 7 files changed, 31 insertions(+), 22 deletions(-) diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index e12c6e42..beca2b4e 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -74,7 +74,8 @@ cc_library( "//internal/platform/implementation:platform", "//internal/platform/implementation:wifi_utils", "//proto/mediums:web_rtc_signaling_frames_cc_proto", - # TODO: Support WebRTC + # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep + # "//third_party/webrtc/files/stable/webrtc/api:jsep", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:btree", "@com_google_absl//absl/container:flat_hash_map", diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index 71662a36..a2b92747 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -45,7 +45,10 @@ cc_library( "//internal/platform:logging", "//internal/platform:types", "//proto/mediums:web_rtc_signaling_frames_cc_proto", - # TODO: Support WebRTC + # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep + # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", + # "//third_party/webrtc/files/stable/webrtc/api:jsep", + # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/memory", @@ -97,8 +100,9 @@ cc_test( "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # buildcleaner: keep - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", + # "//third_party/webrtc/files/stable/webrtc/api:jsep", + # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/time", diff --git a/internal/platform/BUILD b/internal/platform/BUILD index f2a62bf3..fd82b22d 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -367,7 +367,8 @@ cc_library( "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", "//internal/platform/implementation:wifi_utils", - # TODO: Support WebRTC + # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep + # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 708acebc..d6092802 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -122,7 +122,8 @@ cc_library( "//internal/platform:uuid", "//internal/proto:credential_cc_proto", "//internal/proto:local_credential_cc_proto", - # TODO: Support WebRTC + # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep + # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/functional:any_invocable", diff --git a/internal/platform/implementation/apple/BUILD b/internal/platform/implementation/apple/BUILD index 141c6ea0..496e5b7d 100644 --- a/internal/platform/implementation/apple/BUILD +++ b/internal/platform/implementation/apple/BUILD @@ -111,8 +111,8 @@ objc_library( "//internal/platform:types", "//internal/proto:tachyon_cc_proto", "//third_party/webrtc/files/stable/webrtc/api/task_queue:default_task_queue_factory", - "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", + # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "//third_party/webrtc/files/stable/webrtc/rtc_base:checks", "//internal/platform:base", "//internal/platform/implementation:comm", diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index f2a980a2..4aa9171c 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -114,9 +114,9 @@ cc_library( "//internal/platform/implementation:comm", "//internal/platform/implementation:wifi_utils", "//internal/proto:credential_cc_proto", - "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", + # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index e8322555..d9b860c6 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -252,10 +252,10 @@ cc_library( "//internal/platform:logging", "//internal/platform:tachyon_express_signaling_messenger", "//internal/platform/implementation:comm", - "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/files/stable/webrtc/api:rtc_error", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", + # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + # "//third_party/webrtc/files/stable/webrtc/api:rtc_error", + # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", "@com_google_absl//absl/strings", ], @@ -374,10 +374,11 @@ cc_library( "//internal/platform/implementation/shared:count_down_latch", "//internal/platform/implementation/windows/generated:types", "//third_party/intel/pie", - "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/files/stable/webrtc/api:rtc_error", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", + # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", + # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + # "//third_party/webrtc/files/stable/webrtc/api:rtc_error", + # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/base:nullability", @@ -460,9 +461,10 @@ cc_test( ":webrtc", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform_impl", - "//third_party/webrtc/files/stable/webrtc/api:jsep", - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", + # "//third_party/webrtc/files/stable/webrtc/api:jsep", + # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_googletest//:gtest_main", ], From 86dde4cd78f0c05d04a4946d276733f96de88620 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 18 Mar 2026 09:57:15 -0700 Subject: [PATCH 021/151] Fix hotspot candidates PiperOrigin-RevId: 885651650 --- .../implementation/windows/wifi_hotspot_server_socket.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc b/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc index 434d7a09..4482e122 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc @@ -112,6 +112,10 @@ void WifiHotspotServerSocket::PopulateHotspotCredentials( std::vector service_addresses; bool has_ipv4_address = false; for (int i = 0; i < ip_address_max_retries; i++) { + // Force refresh network info since assignment of the well known + // static IP address to the hotspot interface does not trigger the IP + // interface change notification in network_monitor.cc. + NetworkInfo::GetNetworkInfo().Refresh(); for (const auto& net_interface : NetworkInfo::GetNetworkInfo().GetInterfaces()) { // service_addresses should only have addresses from a single interface. @@ -120,11 +124,13 @@ void WifiHotspotServerSocket::PopulateHotspotCredentials( LOG(INFO) << "Found Wifi Hotspot interface, index: " << net_interface.index; for (const SocketAddress& ipaddress : net_interface.ipv6_addresses) { + VLOG(1) << "Found ipv6 address: " << ipaddress.ToString(); // IPv6 link-local addresses are allowed and preferred since it skips // the DHCP wait time. service_addresses.push_back(ipaddress.ToServiceAddress(GetPort())); } for (const SocketAddress& ipaddress : net_interface.ipv4_addresses) { + VLOG(1) << "Found ipv4 address: " << ipaddress.ToString(); // Skip link-local IPv4 addresses. if (ipaddress.IsV4LinkLocal()) { continue; From 9c3523cf6c9eb4baf91d259d546f6b2f2b1a29df Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 18 Mar 2026 13:51:12 -0700 Subject: [PATCH 022/151] Move rpc deadline setting up to client. PiperOrigin-RevId: 885770162 --- .../certificates/nearby_share_certificate_manager_impl.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sharing/certificates/nearby_share_certificate_manager_impl.cc b/sharing/certificates/nearby_share_certificate_manager_impl.cc index 2fe80bb4..35984b59 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl.cc +++ b/sharing/certificates/nearby_share_certificate_manager_impl.cc @@ -336,7 +336,7 @@ void NearbyShareCertificateManagerImpl::CertificateDownloadContext:: request.set_page_token(*next_page_token_); } nearby_identity_client_->QuerySharedCredentials( - std::move(request), + std::move(request), api::IdentityRpcClient::kTimeout, [this](const absl::StatusOr& response) mutable { if (!response.ok()) { @@ -545,7 +545,7 @@ bool NearbyShareCertificateManagerImpl::UploadDeviceCertificatesInExecutor( bool regenerate_certificates = false; absl::Notification notification; nearby_identity_client_->PublishDevice( - std::move(request), + std::move(request), api::IdentityRpcClient::kTimeout, [&upload_certificates_succeeded, ®enerate_certificates, ¬ification](const absl::StatusOr& response) { upload_certificates_succeeded = response.ok(); @@ -877,7 +877,7 @@ bool NearbyShareCertificateManagerImpl::UpdateAccountInfoInExecutor() { bool get_account_info_succeeded = false; absl::Notification notification; nearby_identity_client_->GetAccountInfo( - std::move(request), + std::move(request), api::IdentityRpcClient::kTimeout, [this, &get_account_info_succeeded, ¬ification]( const absl::StatusOr& response) mutable { if (!response.ok()) { From 593e46c8586da5fcce8a185194edea5e51bf0131 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 19 Mar 2026 16:30:59 -0700 Subject: [PATCH 023/151] Use new QuerySharedCredentials rpc when file sync is enabled. PiperOrigin-RevId: 886435458 --- sharing/certificates/BUILD | 4 + .../nearby_share_certificate_manager_impl.cc | 62 +++++++++++- .../nearby_share_certificate_manager_impl.h | 1 + ...rby_share_certificate_manager_impl_test.cc | 99 ++++++++++++++++++- 4 files changed, 164 insertions(+), 2 deletions(-) diff --git a/sharing/certificates/BUILD b/sharing/certificates/BUILD index 0b2a6f1f..b0073e37 100644 --- a/sharing/certificates/BUILD +++ b/sharing/certificates/BUILD @@ -48,10 +48,12 @@ cc_library( "//internal/base", "//internal/base:file_path", "//internal/crypto_cros", + "//internal/flags:nearby_flags", "//internal/platform:mac_address", "//internal/platform:types", "//location/nearby/sharing/lib/account:account_manager", "//location/nearby/sharing/lib/rpc:sharing_rpc_client", + "//sharing/flags/generated:generated_flags", "//sharing/internal/api:platform", "//sharing/internal/base", "//sharing/internal/public:logging", @@ -126,12 +128,14 @@ cc_test( ":test_support", "//google/nearby/identity/v1:resources_cc_proto", "//google/nearby/identity/v1:rpcs_cc_proto", + "//internal/flags:nearby_flags", "//internal/platform:mac_address", "//internal/platform/implementation:platform_impl", "//location/nearby/sharing/lib/account:account_manager", "//location/nearby/sharing/lib/account:fake_account_manager", "//location/nearby/sharing/lib/rpc:fake_nearby_share_client", "//sharing/common:enum", + "//sharing/flags/generated:generated_flags", "//sharing/internal/api:mock_sharing_platform", "//sharing/internal/api:platform", "//sharing/internal/public:pref_names", diff --git a/sharing/certificates/nearby_share_certificate_manager_impl.cc b/sharing/certificates/nearby_share_certificate_manager_impl.cc index 35984b59..5797059a 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl.cc +++ b/sharing/certificates/nearby_share_certificate_manager_impl.cc @@ -45,6 +45,7 @@ #include "absl/time/time.h" #include "absl/types/span.h" #include "internal/base/file_path.h" +#include "internal/flags/nearby_flags.h" #include "internal/platform/mac_address.h" #include "sharing/certificates/common.h" #include "sharing/certificates/constants.h" @@ -54,6 +55,7 @@ #include "sharing/certificates/nearby_share_decrypted_public_certificate.h" #include "sharing/certificates/nearby_share_encrypted_metadata_key.h" #include "sharing/certificates/nearby_share_private_certificate.h" +#include "sharing/flags/generated/nearby_sharing_feature_flags.h" #include "sharing/internal/api/bluetooth_adapter.h" #include "sharing/internal/api/preference_manager.h" #include "sharing/internal/api/public_certificate_database.h" @@ -82,6 +84,10 @@ using ::google::nearby::identity::v1::PublishDeviceRequest; using ::google::nearby::identity::v1::PublishDeviceResponse; using ::google::nearby::identity::v1::QuerySharedCredentialsRequest; using ::google::nearby::identity::v1::QuerySharedCredentialsResponse; +using ::google::nearby::identity::v1:: + QuerySharedCredentialsWithBindingIdsRequest; +using ::google::nearby::identity::v1:: + QuerySharedCredentialsWithBindingIdsResponse; using ::google::nearby::identity::v1::SharedCredential; using ::nearby::sharing::api::PreferenceManager; using ::nearby::sharing::api::PublicCertificateDatabase; @@ -372,6 +378,55 @@ void NearbyShareCertificateManagerImpl::CertificateDownloadContext:: }); } + +void NearbyShareCertificateManagerImpl::CertificateDownloadContext:: + QuerySharedCredentialsWithBindingIdsFetchNextPage() { + LOG(INFO) << __func__ + << ": Downloading public certificates with binding ids page=" + << page_number_; + page_number_++; + QuerySharedCredentialsWithBindingIdsRequest request; + request.set_name(absl::StrCat("devices/", device_id_)); + if (next_page_token_.has_value()) { + request.set_page_token(*next_page_token_); + } + nearby_identity_client_->QuerySharedCredentialsWithBindingIds( + std::move(request), api::IdentityRpcClient::kTimeout, + [this](const absl::StatusOr& + response) mutable { + if (!response.ok()) { + LOG(WARNING) << "Failed to download public certificates: " + << response.status(); + std::move(download_callback_)(response.status()); + return; + } + for (const auto& credential : response->shared_credentials()) { + if (credential.data_type() != + SharedCredential::DATA_TYPE_PUBLIC_CERTIFICATE) { + continue; + } + PublicCertificate certificate; + if (!certificate.ParseFromString(credential.data())) { + LOG(ERROR) << "Failed parsing to PublicCertificate, credential.id: " + << credential.id() << " data: " + << absl::BytesToHexString(credential.data()); + continue; + } + VLOG(1) << "Successfully parsed credential: " << credential.id(); + certificates_.push_back(certificate); + } + + if (response->next_page_token().empty()) { + LOG(INFO) << "Completed download of " << certificates_.size() + << " certificates"; + std::move(download_callback_)(std::move(certificates_)); + return; + } + next_page_token_ = response->next_page_token(); + QuerySharedCredentialsWithBindingIdsFetchNextPage(); + }); +} + bool NearbyShareCertificateManagerImpl::UpdatePublicCertificates( const std::vector& certificates) { // Save certificates to store. @@ -437,7 +492,12 @@ bool NearbyShareCertificateManagerImpl::DownloadPublicCertificatesInExecutor() { } notification.Notify(); }); - context->QuerySharedCredentialsFetchNextPage(); + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_sharing_feature::kEnableFileSync)) { + context->QuerySharedCredentialsWithBindingIdsFetchNextPage(); + } else { + context->QuerySharedCredentialsFetchNextPage(); + } // Wait for all pages of certificates to be downloaded. // MUST not terminate early, otherwise notification will go out of scope, and // the callback will call Notify on a destroyed object. diff --git a/sharing/certificates/nearby_share_certificate_manager_impl.h b/sharing/certificates/nearby_share_certificate_manager_impl.h index f3ca9a58..5f93cad6 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl.h +++ b/sharing/certificates/nearby_share_certificate_manager_impl.h @@ -118,6 +118,7 @@ class NearbyShareCertificateManagerImpl // On successful download, if page token in the response is empty, the // |download_success_callback_| is invoked with all downloaded certificates. void QuerySharedCredentialsFetchNextPage(); + void QuerySharedCredentialsWithBindingIdsFetchNextPage(); private: nearby::sharing::api::IdentityRpcClient* absl_nonnull const diff --git a/sharing/certificates/nearby_share_certificate_manager_impl_test.cc b/sharing/certificates/nearby_share_certificate_manager_impl_test.cc index 5db57f16..ebd994a6 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl_test.cc +++ b/sharing/certificates/nearby_share_certificate_manager_impl_test.cc @@ -39,6 +39,7 @@ #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "absl/types/span.h" +#include "internal/flags/nearby_flags.h" #include "internal/platform/mac_address.h" #include "sharing/certificates/constants.h" #include "sharing/certificates/fake_nearby_share_certificate_storage.h" @@ -48,6 +49,7 @@ #include "sharing/certificates/nearby_share_encrypted_metadata_key.h" #include "sharing/certificates/nearby_share_private_certificate.h" #include "sharing/certificates/test_util.h" +#include "sharing/flags/generated/nearby_sharing_feature_flags.h" #include "sharing/internal/api/mock_sharing_platform.h" #include "sharing/internal/public/pref_names.h" #include "sharing/internal/test/fake_bluetooth_adapter.h" @@ -70,6 +72,10 @@ using ::google::nearby::identity::v1::PublishDeviceRequest; using ::google::nearby::identity::v1::PublishDeviceResponse; using ::google::nearby::identity::v1::QuerySharedCredentialsRequest; using ::google::nearby::identity::v1::QuerySharedCredentialsResponse; +using ::google::nearby::identity::v1:: + QuerySharedCredentialsWithBindingIdsRequest; +using ::google::nearby::identity::v1:: + QuerySharedCredentialsWithBindingIdsResponse; using ::nearby::sharing::proto::DeviceVisibility; using ::nearby::sharing::proto::PublicCertificate; using ::testing::Not; @@ -100,6 +106,7 @@ class NearbyShareCertificateManagerImplTest ~NearbyShareCertificateManagerImplTest() override = default; void SetUp() override { + NearbyFlags::GetInstance().ResetOverridedValues(); ON_CALL(mock_sharing_platform_, GetPreferenceManager) .WillByDefault(ReturnRef(preference_manager_)); ON_CALL(mock_sharing_platform_, GetAccountManager) @@ -304,7 +311,7 @@ class NearbyShareCertificateManagerImplTest std::max(max_not_after_self_share, cert.not_after()); break; default: - DCHECK(false); + FAIL() << "Unexpected visibility: " << cert.visibility(); break; } @@ -423,6 +430,78 @@ class NearbyShareCertificateManagerImplTest return response; } + void QuerySharedCredentialsWithBindingIdsFlow( + size_t num_pages, DownloadPublicCertificatesResult result) { + size_t prev_num_results = download_scheduler_->handled_results().size(); + cert_store_->SetPublicCertificateIds(kPublicCertificateIds); + + size_t initial_num_notifications = + num_public_certs_downloaded_notifications_; + size_t initial_num_public_cert_exp_reschedules = + public_cert_exp_scheduler_->num_reschedule_calls(); + + std::vector> + responses; + std::string page_token; + for (size_t page_number = 0; page_number < num_pages; ++page_number) { + bool last_page = page_number == num_pages - 1; + if (last_page && result == DownloadPublicCertificatesResult::kHttpError) { + responses.push_back(absl::InternalError("")); + break; + } + page_token = last_page ? std::string() + : absl::StrCat(kPageTokenPrefix, page_number); + responses.push_back(BuildQuerySharedCredentialsWithBindingIdsResponse( + page_number, page_token)); + } + + identity_client_.SetQuerySharedCredentialsWithBindingIdsResponses( + responses); + cert_store_->SetAddPublicCertificatesResult( + result != DownloadPublicCertificatesResult::kStorageError); + download_scheduler_->InvokeRequestCallback(); + Sync(); + + std::vector requests = + identity_client_.query_shared_credentials_with_binding_ids_requests(); + EXPECT_EQ(requests.size(), num_pages); + EXPECT_EQ(requests.back().name(), absl::StrCat("devices/", kDeviceId)); + ASSERT_EQ(download_scheduler_->handled_results().size(), + prev_num_results + 1); + + bool success = result == DownloadPublicCertificatesResult::kSuccess; + EXPECT_EQ(download_scheduler_->handled_results().back(), success); + EXPECT_EQ(num_public_certs_downloaded_notifications_, + initial_num_notifications + (success ? 1u : 0u)); + EXPECT_EQ(public_cert_exp_scheduler_->num_reschedule_calls(), + initial_num_public_cert_exp_reschedules + (success ? 1u : 0u)); + } + + QuerySharedCredentialsWithBindingIdsResponse + BuildQuerySharedCredentialsWithBindingIdsResponse( + size_t page_number, absl::string_view page_token) { + QuerySharedCredentialsWithBindingIdsResponse response; + int i = 0; + for (auto public_certificate : public_certificates_) { + auto* shared_credential = response.add_shared_credentials(); + shared_credential->set_id(page_number * 100 + i); + if (i % 2 == 0) { + shared_credential->set_data_type( + google::nearby::identity::v1::SharedCredential:: + DATA_TYPE_PUBLIC_CERTIFICATE); + } else { + shared_credential->set_data_type( + google::nearby::identity::v1::SharedCredential:: + DATA_TYPE_SHARED_CREDENTIAL); + } + *shared_credential->mutable_data() = + public_certificate.SerializeAsString(); + i++; + } + response.set_next_page_token(page_token); + return response; + } + void CheckStorageAddCertificates( const FakeNearbyShareCertificateStorage::AddPublicCertificatesCall& add_cert_call) { @@ -700,6 +779,24 @@ TEST_F(NearbyShareCertificateManagerImplTest, /*num_pages=*/2, DownloadPublicCertificatesResult::kHttpError)); } +TEST_F(NearbyShareCertificateManagerImplTest, + QuerySharedCredentialsWithBindingIdsSuccess) { + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_sharing_feature::kEnableFileSync, true); + Initialize(); + ASSERT_NO_FATAL_FAILURE(QuerySharedCredentialsWithBindingIdsFlow( + /*num_pages=*/2, DownloadPublicCertificatesResult::kSuccess)); +} + +TEST_F(NearbyShareCertificateManagerImplTest, + QuerySharedCredentialsWithBindingIdsRPCFailure) { + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_sharing_feature::kEnableFileSync, true); + Initialize(); + ASSERT_NO_FATAL_FAILURE(QuerySharedCredentialsWithBindingIdsFlow( + /*num_pages=*/2, DownloadPublicCertificatesResult::kHttpError)); +} + TEST_F(NearbyShareCertificateManagerImplTest, ClearPublicCertificates) { Initialize(); cert_manager_->ClearPublicCertificates([&](bool result) {}); From 92e901e466c196e8c5049fd66147ecdb25aac6e8 Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 20 Mar 2026 14:48:57 -0700 Subject: [PATCH 024/151] Always include preferences_manager.h in platform.h. PiperOrigin-RevId: 886985043 --- internal/platform/implementation/platform.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/platform/implementation/platform.h b/internal/platform/implementation/platform.h index f1ac4ac1..49aaed18 100644 --- a/internal/platform/implementation/platform.h +++ b/internal/platform/implementation/platform.h @@ -39,15 +39,13 @@ #include "internal/platform/implementation/log_message.h" #include "internal/platform/implementation/mutex.h" #include "internal/platform/implementation/output_file.h" +#include "internal/platform/implementation/preferences_manager.h" #include "internal/platform/implementation/scheduled_executor.h" #include "internal/platform/implementation/submittable_executor.h" #include "internal/platform/implementation/timer.h" #ifndef NO_WEBRTC #include "internal/platform/implementation/webrtc.h" #endif -#ifndef NEARBY_CHROMIUM -#include "internal/platform/implementation/preferences_manager.h" -#endif #include "internal/platform/implementation/wifi.h" #include "internal/platform/implementation/wifi_direct.h" #include "internal/platform/implementation/wifi_hotspot.h" From 8946f208831f6a8d9a329afa7f90ccaf890a3f58 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 20 Mar 2026 15:46:52 -0700 Subject: [PATCH 025/151] Return more specific transfer failure status. PiperOrigin-RevId: 887009931 --- sharing/nearby_sharing_service_impl.cc | 7 ++-- sharing/nearby_sharing_service_impl.h | 2 +- sharing/outgoing_share_session.cc | 12 +++--- sharing/outgoing_share_session.h | 6 ++- sharing/outgoing_share_session_test.cc | 51 +++++++++++++++----------- 5 files changed, 45 insertions(+), 33 deletions(-) diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 0d08d02e..2769409c 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -2443,7 +2443,7 @@ void NearbySharingServiceImpl::OnIncomingSessionFrameRead( if (is_timeout) { LOG(WARNING) << __func__ << ": Timed out reading frame from target: " << share_target_id; - session->Abort(TransferMetadata::Status::kFailed); + session->Abort(TransferMetadata::Status::kTimedOut); return; } if (!frame.has_value()) { @@ -2609,7 +2609,8 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( } void NearbySharingServiceImpl::OnReceiveConnectionResponse( - int64_t share_target_id, std::optional frame) { + int64_t share_target_id, bool is_timeout, + std::optional frame) { OutgoingShareSession* session = outgoing_targets_manager_.GetOutgoingShareSession(share_target_id); if (!session || !session->IsConnected()) { @@ -2620,7 +2621,7 @@ void NearbySharingServiceImpl::OnReceiveConnectionResponse( } std::optional status = - session->HandleConnectionResponse(std::move(frame)); + session->HandleConnectionResponse(is_timeout, std::move(frame)); if (status.has_value()) { session->Abort(*status); return; diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index b3528bc3..542594b2 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -327,7 +327,7 @@ class NearbySharingServiceImpl IncomingShareSession& session, const nearby::sharing::service::proto::IntroductionFrame& frame); void OnReceiveConnectionResponse( - int64_t share_target_id, + int64_t share_target_id, bool is_timeout, std::optional frame); void OnStorageCheckCompleted(IncomingShareSession& session); diff --git a/sharing/outgoing_share_session.cc b/sharing/outgoing_share_session.cc index 0073f259..4c194315 100644 --- a/sharing/outgoing_share_session.cc +++ b/sharing/outgoing_share_session.cc @@ -316,7 +316,8 @@ bool OutgoingShareSession::FillIntroductionFrame( } bool OutgoingShareSession::AcceptTransfer( - std::function)> + std::function)> response_callback) { if (!IsConnected()) { LOG(WARNING) << "Accept invoked for unconnected share target"; @@ -339,10 +340,10 @@ bool OutgoingShareSession::AcceptTransfer( [callback = std::move(response_callback)](bool is_timeout, std::optional frame) { if (!frame.has_value()) { - callback(std::nullopt); + callback(is_timeout, std::nullopt); return; } - callback(frame->connection_response()); + callback(is_timeout, frame->connection_response()); }, kReadResponseFrameTimeout); return true; @@ -429,14 +430,15 @@ bool OutgoingShareSession::SendIntroduction( std::optional OutgoingShareSession::HandleConnectionResponse( - std::optional response) { + bool is_timeout, std::optional response) { // Stop accept timer. mutual_acceptance_timeout_.reset(); if (!response.has_value()) { LOG(WARNING) << "Failed to read a response from the remote device. Disconnecting."; - return TransferMetadata::Status::kFailed; + return is_timeout ? TransferMetadata::Status::kTimedOut + : TransferMetadata::Status::kFailed; } VLOG(1) << "Successfully read the connection response frame."; diff --git a/sharing/outgoing_share_session.h b/sharing/outgoing_share_session.h index d7a37430..f8eb02a9 100644 --- a/sharing/outgoing_share_session.h +++ b/sharing/outgoing_share_session.h @@ -80,14 +80,16 @@ class OutgoingShareSession : public ShareSession { // ConnectionResponseFrame. bool AcceptTransfer( std::function< - void(std::optional< - nearby::sharing::service::proto::ConnectionResponseFrame>)> + void(bool is_timeout, + std::optional< + nearby::sharing::service::proto::ConnectionResponseFrame>)> response_callback); // Process the ConnectionResponseFrame. // On success, returns std::nullopt. // On failure, returns the status if the connection should be aborted. std::optional HandleConnectionResponse( + bool is_timeout, std::optional response); diff --git a/sharing/outgoing_share_session_test.cc b/sharing/outgoing_share_session_test.cc index 983fc8fb..3ebf44f4 100644 --- a/sharing/outgoing_share_session_test.cc +++ b/sharing/outgoing_share_session_test.cc @@ -45,7 +45,6 @@ #include "sharing/nearby_connection_impl.h" #include "sharing/nearby_connections_manager.h" #include "sharing/nearby_connections_types.h" -#include "sharing/paired_key_verification_runner.h" #include "sharing/proto/analytics/nearby_sharing_log.pb.h" #include "sharing/proto/analytics/nearby_sharing_log.proto.static_reflection.h" #include "sharing/proto/wire_format.pb.h" @@ -61,7 +60,6 @@ namespace { using ::location::nearby::proto::sharing::EstablishConnectionStatus; using ::location::nearby::proto::sharing::EventCategory; using ::location::nearby::proto::sharing::EventType; -using ::location::nearby::proto::sharing::OSType; using ::nearby::analytics::HasCategory; using ::nearby::analytics::HasEventType; using ::nearby::sharing::analytics::proto::SharingLog; @@ -507,7 +505,7 @@ TEST_F(OutgoingShareSessionTest, SendIntroductionTimeoutCancelled) { Call(_, HasStatus(TransferMetadata::Status::kInProgress))); std::optional status = - session_.HandleConnectionResponse(response); + session_.HandleConnectionResponse(/*is_timeout=*/false, response); EXPECT_THAT(status.has_value(), IsFalse()); fake_clock_.FastForward(absl::Seconds(60)); @@ -517,9 +515,9 @@ TEST_F(OutgoingShareSessionTest, SendIntroductionTimeoutCancelled) { } TEST_F(OutgoingShareSessionTest, AcceptTransferNotConnected) { - EXPECT_THAT( - session_.AcceptTransfer([](std::optional) {}), - IsFalse()); + EXPECT_THAT(session_.AcceptTransfer( + [](bool, std::optional) {}), + IsFalse()); } TEST_F(OutgoingShareSessionTest, AcceptTransferNotReady) { @@ -527,9 +525,9 @@ TEST_F(OutgoingShareSessionTest, AcceptTransferNotReady) { session_.set_session_id(1234); ConnectionSuccess(&connection); - EXPECT_THAT( - session_.AcceptTransfer([](std::optional) {}), - IsFalse()); + EXPECT_THAT(session_.AcceptTransfer( + [](bool, std::optional) {}), + IsFalse()); } TEST_F(OutgoingShareSessionTest, AcceptTransferSuccess) { @@ -553,12 +551,12 @@ TEST_F(OutgoingShareSessionTest, AcceptTransferSuccess) { Call(_, HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance))); bool connection_response_received = false; - EXPECT_THAT( - session_.AcceptTransfer([&connection_response_received]( - std::optional) { - connection_response_received = true; - }), - IsTrue()); + EXPECT_THAT(session_.AcceptTransfer( + [&connection_response_received]( + bool, std::optional) { + connection_response_received = true; + }), + IsTrue()); // Send response frame nearby::sharing::service::proto::Frame frame = @@ -575,19 +573,28 @@ TEST_F(OutgoingShareSessionTest, AcceptTransferSuccess) { EXPECT_THAT(connection_response_received, IsTrue()); } -TEST_F(OutgoingShareSessionTest, HandleConnectionResponseEmptyResponse) { +TEST_F(OutgoingShareSessionTest, HandleConnectionResponseEmptyResponseFailed) { std::optional status = - session_.HandleConnectionResponse(std::nullopt); + session_.HandleConnectionResponse(/*is_timeout=*/false, std::nullopt); ASSERT_THAT(status.has_value(), IsTrue()); EXPECT_THAT(status.value(), Eq(TransferMetadata::Status::kFailed)); } +TEST_F(OutgoingShareSessionTest, + HandleConnectionResponseEmptyResponseTimedOut) { + std::optional status = + session_.HandleConnectionResponse(/*is_timeout=*/true, std::nullopt); + + ASSERT_THAT(status.has_value(), IsTrue()); + EXPECT_THAT(status.value(), Eq(TransferMetadata::Status::kTimedOut)); +} + TEST_F(OutgoingShareSessionTest, HandleConnectionResponseRejectResponse) { ConnectionResponseFrame response; response.set_status(ConnectionResponseFrame::REJECT); std::optional status = - session_.HandleConnectionResponse(response); + session_.HandleConnectionResponse(/*is_timeout=*/false, response); ASSERT_THAT(status.has_value(), IsTrue()); EXPECT_THAT(status.value(), Eq(TransferMetadata::Status::kRejected)); @@ -598,7 +605,7 @@ TEST_F(OutgoingShareSessionTest, ConnectionResponseFrame response; response.set_status(ConnectionResponseFrame::NOT_ENOUGH_SPACE); std::optional status = - session_.HandleConnectionResponse(response); + session_.HandleConnectionResponse(/*is_timeout=*/false, response); ASSERT_THAT(status.has_value(), IsTrue()); EXPECT_THAT(status.value(), Eq(TransferMetadata::Status::kNotEnoughSpace)); @@ -609,7 +616,7 @@ TEST_F(OutgoingShareSessionTest, ConnectionResponseFrame response; response.set_status(ConnectionResponseFrame::UNSUPPORTED_ATTACHMENT_TYPE); std::optional status = - session_.HandleConnectionResponse(response); + session_.HandleConnectionResponse(/*is_timeout=*/false, response); ASSERT_THAT(status.has_value(), IsTrue()); EXPECT_THAT(status.value(), @@ -620,7 +627,7 @@ TEST_F(OutgoingShareSessionTest, HandleConnectionResponseTimeoutResponse) { ConnectionResponseFrame response; response.set_status(ConnectionResponseFrame::TIMED_OUT); std::optional status = - session_.HandleConnectionResponse(response); + session_.HandleConnectionResponse(/*is_timeout=*/true, response); ASSERT_THAT(status.has_value(), IsTrue()); EXPECT_THAT(status.value(), Eq(TransferMetadata::Status::kTimedOut)); @@ -636,7 +643,7 @@ TEST_F(OutgoingShareSessionTest, HandleConnectionResponseAcceptResponse) { Call(_, HasStatus(TransferMetadata::Status::kInProgress))); std::optional status = - session_.HandleConnectionResponse(response); + session_.HandleConnectionResponse(/*is_timeout=*/false, response); ASSERT_THAT(status.has_value(), IsFalse()); } From 17204408ac92acd471b9e2c722a31a444a367851 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 23 Mar 2026 17:24:24 -0700 Subject: [PATCH 026/151] Add Pairing flow. PiperOrigin-RevId: 888356880 --- sharing/BUILD | 6 +- sharing/incoming_frames_reader.cc | 7 +- sharing/incoming_frames_reader.h | 12 +- sharing/outgoing_share_session.cc | 42 ++++ sharing/outgoing_share_session.h | 11 ++ sharing/outgoing_share_session_test.cc | 183 ++++++++++++++++++ .../paired_key_verification_runner_test.cc | 32 +-- 7 files changed, 267 insertions(+), 26 deletions(-) diff --git a/sharing/BUILD b/sharing/BUILD index d03c3f5a..20356bdb 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -169,6 +169,7 @@ cc_library( "//sharing/internal/public:logging", "//sharing/proto:wire_format_cc_proto", "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/memory", "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", @@ -537,12 +538,11 @@ cc_test( "//sharing/certificates", "//sharing/certificates:test_support", "//sharing/internal/public:logging", - "//sharing/internal/public:types", - "//sharing/internal/test:nearby_test", "//sharing/proto:enums_cc_proto", "//sharing/proto:share_cc_proto", "//sharing/proto:wire_format_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], @@ -909,7 +909,6 @@ cc_test( ":attachments", ":connection_types", ":nearby_connection_impl", - ":paired_key_verification_runner", ":share_session", ":test_support", ":transfer_metadata", @@ -921,6 +920,7 @@ cc_test( "//internal/network:url", "//internal/platform/implementation:platform_impl", "//internal/test", + "//net/proto2/contrib/parse_proto:parse_text_proto", "//sharing/analytics", "//sharing/certificates:test_support", "//sharing/common:enum", diff --git a/sharing/incoming_frames_reader.cc b/sharing/incoming_frames_reader.cc index 72be3530..73c3cb43 100644 --- a/sharing/incoming_frames_reader.cc +++ b/sharing/incoming_frames_reader.cc @@ -24,6 +24,7 @@ #include #include +#include "absl/functional/any_invocable.h" #include "absl/memory/memory.h" #include "absl/synchronization/mutex.h" #include "absl/time/time.h" @@ -66,21 +67,21 @@ IncomingFramesReader::~IncomingFramesReader() { } void IncomingFramesReader::ReadFrame( - std::function)> callback, + absl::AnyInvocable)> callback, absl::Duration timeout) { ProcessReadRequest(std::nullopt, std::move(callback), timeout); } void IncomingFramesReader::ReadFrame( FrameType frame_type, - std::function)> callback, + absl::AnyInvocable)> callback, absl::Duration timeout) { ProcessReadRequest(frame_type, std::move(callback), timeout); } void IncomingFramesReader::ProcessReadRequest( std::optional frame_type, - std::function)> callback, + absl::AnyInvocable)> callback, absl::Duration timeout) { std::unique_ptr cached_frame; { diff --git a/sharing/incoming_frames_reader.h b/sharing/incoming_frames_reader.h index cd3ba339..b03845d4 100644 --- a/sharing/incoming_frames_reader.h +++ b/sharing/incoming_frames_reader.h @@ -25,6 +25,7 @@ #include #include "absl/base/thread_annotations.h" +#include "absl/functional/any_invocable.h" #include "absl/synchronization/mutex.h" #include "absl/time/time.h" #include "internal/platform/task_runner.h" @@ -54,7 +55,7 @@ class IncomingFramesReader // Note: Callers are expected wait for `callback` to be run before scheduling // subsequent calls to ReadFrame(..). virtual void ReadFrame( - std::function< + absl::AnyInvocable< void(bool is_timeout, std::optional)> callback, @@ -70,7 +71,7 @@ class IncomingFramesReader // subsequent calls to ReadFrame(..). virtual void ReadFrame( nearby::sharing::service::proto::V1Frame::FrameType frame_type, - std::function< + absl::AnyInvocable< void(bool is_timeout, std::optional)> callback, @@ -84,8 +85,9 @@ class IncomingFramesReader struct ReadFrameInfo { std::optional frame_type = std::nullopt; - std::function)> + absl::AnyInvocable)> callback = nullptr; absl::Duration timeout = absl::ZeroDuration(); }; @@ -93,7 +95,7 @@ class IncomingFramesReader void ProcessReadRequest( std::optional frame_type, - std::function< + absl::AnyInvocable< void(bool is_timeout, std::optional)> callback, diff --git a/sharing/outgoing_share_session.cc b/sharing/outgoing_share_session.cc index 4c194315..38e845e4 100644 --- a/sharing/outgoing_share_session.cc +++ b/sharing/outgoing_share_session.cc @@ -41,6 +41,7 @@ #include "sharing/nearby_connections_types.h" #include "sharing/nearby_sharing_util.h" #include "sharing/payload_tracker.h" +#include "sharing/proto/wire_format.pb.h" #include "sharing/share_session.h" #include "sharing/share_target.h" #include "sharing/text_attachment.h" @@ -55,6 +56,8 @@ namespace { using ::location::nearby::proto::sharing::ConnectionLayerStatus; using ::location::nearby::proto::sharing::EstablishConnectionStatus; using ::nearby::sharing::proto::DataUsage; +using ::nearby::sharing::service::proto::BindingRequest; +using ::nearby::sharing::service::proto::BindingResponse; using ::nearby::sharing::service::proto::ConnectionResponseFrame; using ::nearby::sharing::service::proto::Frame; using ::nearby::sharing::service::proto::IntroductionFrame; @@ -632,4 +635,43 @@ OutgoingShareSession::ProcessPayloadTransferUpdates() { return metadata; } +void OutgoingShareSession::StartPeerBinding( + std::string binding_id, BindingRequest::Type binding_type, + absl::AnyInvocable callback) { + Frame frame; + frame.set_version(Frame::V1); + V1Frame* v1_frame = frame.mutable_v1(); + v1_frame->set_type(V1Frame::BINDINGS); + BindingRequest* binding_request = + v1_frame->mutable_bindings()->mutable_binding_request(); + binding_request->set_binding_id(binding_id); + binding_request->set_type(binding_type); + WriteFrame(frame); + LOG(INFO) << "Waiting for bindings response frame from " << share_target().id; + UpdateTransferMetadata( + TransferMetadataBuilder() + .set_token(token()) + .set_status(TransferMetadata::Status::kAwaitingRemoteAcceptance) + .build()); + frames_reader()->ReadFrame( + nearby::sharing::service::proto::V1Frame::BINDINGS, + [callback = std::move(callback)]( + bool is_timeout, std::optional frame) mutable { + if (!frame.has_value()) { + std::move(callback)(BindingResponse::FAILURE); + return; + } + if (!frame->has_bindings() || + !frame->bindings().has_binding_response() || + frame->bindings().binding_response().status() != + BindingResponse::SUCCESS) { + std::move(callback)(BindingResponse::FAILURE); + return; + } + // Peer binding flow completed successfully. + std::move(callback)(BindingResponse::SUCCESS); + }, + kReadResponseFrameTimeout); +} + } // namespace nearby::sharing diff --git a/sharing/outgoing_share_session.h b/sharing/outgoing_share_session.h index f8eb02a9..fb28496a 100644 --- a/sharing/outgoing_share_session.h +++ b/sharing/outgoing_share_session.h @@ -164,6 +164,17 @@ class OutgoingShareSession : public ShareSession { // Otherwise, it is a pairing session. bool is_transfer_session() const { return is_transfer_session_; } + // Initiates the peer binding message exchange with the remote device. + // `binding_id` is the result of a successful call to InitiateBinding rpc. + // `callback` is called when either a BindingResponse frame is received or a + // timeout occurs. + void StartPeerBinding( + std::string binding_id, + nearby::sharing::service::proto::BindingRequest::Type binding_type, + absl::AnyInvocable< + void(nearby::sharing::service::proto::BindingResponse::Status)> + callback); + protected: void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override; void OnConnectionDisconnected() override; diff --git a/sharing/outgoing_share_session_test.cc b/sharing/outgoing_share_session_test.cc index 3ebf44f4..670bd680 100644 --- a/sharing/outgoing_share_session_test.cc +++ b/sharing/outgoing_share_session_test.cc @@ -22,6 +22,7 @@ #include #include +#include "net/proto2/contrib/parse_proto/parse_text_proto.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" @@ -63,6 +64,8 @@ using ::location::nearby::proto::sharing::EventType; using ::nearby::analytics::HasCategory; using ::nearby::analytics::HasEventType; using ::nearby::sharing::analytics::proto::SharingLog; +using ::nearby::sharing::service::proto::BindingRequest; +using ::nearby::sharing::service::proto::BindingResponse; using ::nearby::sharing::service::proto::ConnectionResponseFrame; using ::nearby::sharing::service::proto::Frame; using ::nearby::sharing::service::proto::IntroductionFrame; @@ -71,6 +74,7 @@ using ::nearby::sharing::service::proto::WifiCredentials; using ::testing::_; using ::testing::AllOf; using ::testing::Eq; +using ::protobuf_matchers::EqualsProto; using ::testing::InSequence; using ::testing::IsEmpty; using ::testing::IsFalse; @@ -916,5 +920,184 @@ TEST_F(OutgoingShareSessionTest, EXPECT_TRUE(session_.certificate().has_value()); EXPECT_THAT(session_.endpoint_id(), Eq(endpoint_id_org)); } + +TEST_F(OutgoingShareSessionTest, StartPeerBindingSuccess) { + session_.set_session_id(1234); + NearbyConnectionImpl connection(device_info_); + ConnectionSuccess(&connection); + Frame expected_binding_request_frame = + proto2::contrib::parse_proto::ParseTextProtoOrDie( + R"pb( + version: V1 + v1 { + type: BINDINGS + bindings { + binding_request { + binding_id: "test_binding_id" + type: FILESYNC + } + } + } + )pb"); + std::vector frame_data; + connections_manager_.set_send_payload_callback( + [&](std::unique_ptr payload, + std::weak_ptr + listener) { + frame_data = std::move(payload->content.bytes_payload.bytes); + }); + EXPECT_CALL( + transfer_metadata_callback_, + Call(_, HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance))); + + BindingResponse::Status binding_response_status = BindingResponse::FAILURE; + session_.StartPeerBinding("test_binding_id", BindingRequest::FILESYNC, + [&binding_response_status]( + BindingResponse::Status status) { + binding_response_status = status; + }); + + Frame frame; + ASSERT_THAT(frame.ParseFromArray(frame_data.data(), frame_data.size()), + IsTrue()); + EXPECT_THAT(frame, EqualsProto(expected_binding_request_frame)); + + // Send response frame + nearby::sharing::service::proto::Frame response_frame = + proto2::contrib::parse_proto::ParseTextProtoOrDie( + R"pb( + version: V1 + v1 { + type: BINDINGS + bindings { + binding_response { + status: SUCCESS + } + } + } + )pb" + ); + std::vector data; + data.resize(response_frame.ByteSizeLong()); + EXPECT_THAT(response_frame.SerializeToArray(data.data(), data.size()), + IsTrue()); + connection.WriteMessage(std::move(data)); + + EXPECT_THAT(binding_response_status, Eq(BindingResponse::SUCCESS)); +} + +TEST_F(OutgoingShareSessionTest, StartPeerBindingTimeout) { + session_.set_session_id(1234); + NearbyConnectionImpl connection(device_info_); + ConnectionSuccess(&connection); + Frame expected_binding_request_frame = + proto2::contrib::parse_proto::ParseTextProtoOrDie( + R"pb( + version: V1 + v1 { + type: BINDINGS + bindings { + binding_request { + binding_id: "test_binding_id" + type: FILESYNC + } + } + } + )pb"); + std::vector frame_data; + connections_manager_.set_send_payload_callback( + [&](std::unique_ptr payload, + std::weak_ptr + listener) { + frame_data = std::move(payload->content.bytes_payload.bytes); + }); + EXPECT_CALL( + transfer_metadata_callback_, + Call(_, HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance))); + + BindingResponse::Status binding_response_status = BindingResponse::FAILURE; + session_.StartPeerBinding("test_binding_id", BindingRequest::FILESYNC, + [&binding_response_status]( + BindingResponse::Status status) { + binding_response_status = status; + }); + + Frame frame; + ASSERT_THAT(frame.ParseFromArray(frame_data.data(), frame_data.size()), + IsTrue()); + EXPECT_THAT(frame, EqualsProto(expected_binding_request_frame)); + + // Fast forward to the disconnection timeout. + fake_clock_.FastForward(absl::Seconds(60)); + fake_task_runner_.SyncWithTimeout(absl::Milliseconds(100)); + + EXPECT_THAT(binding_response_status, Eq(BindingResponse::FAILURE)); +} + +TEST_F(OutgoingShareSessionTest, StartPeerBindingFailure) { + session_.set_session_id(1234); + NearbyConnectionImpl connection(device_info_); + ConnectionSuccess(&connection); + Frame expected_binding_request_frame = + proto2::contrib::parse_proto::ParseTextProtoOrDie( + R"pb( + version: V1 + v1 { + type: BINDINGS + bindings { + binding_request { + binding_id: "test_binding_id" + type: FILESYNC + } + } + } + )pb"); + std::vector frame_data; + connections_manager_.set_send_payload_callback( + [&](std::unique_ptr payload, + std::weak_ptr + listener) { + frame_data = std::move(payload->content.bytes_payload.bytes); + }); + EXPECT_CALL( + transfer_metadata_callback_, + Call(_, HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance))); + + BindingResponse::Status binding_response_status = BindingResponse::FAILURE; + session_.StartPeerBinding("test_binding_id", BindingRequest::FILESYNC, + [&binding_response_status]( + BindingResponse::Status status) { + binding_response_status = status; + }); + + Frame frame; + ASSERT_THAT(frame.ParseFromArray(frame_data.data(), frame_data.size()), + IsTrue()); + EXPECT_THAT(frame, EqualsProto(expected_binding_request_frame)); + + // Send response frame + nearby::sharing::service::proto::Frame response_frame = + proto2::contrib::parse_proto::ParseTextProtoOrDie( + R"pb( + version: V1 + v1 { + type: BINDINGS + bindings { + binding_response { + status: FAILURE + } + } + } + )pb" + ); + std::vector data; + data.resize(response_frame.ByteSizeLong()); + EXPECT_THAT(response_frame.SerializeToArray(data.data(), data.size()), + IsTrue()); + connection.WriteMessage(std::move(data)); + + EXPECT_THAT(binding_response_status, Eq(BindingResponse::FAILURE)); +} + } // namespace } // namespace nearby::sharing diff --git a/sharing/paired_key_verification_runner_test.cc b/sharing/paired_key_verification_runner_test.cc index c022e972..32e0e72c 100644 --- a/sharing/paired_key_verification_runner_test.cc +++ b/sharing/paired_key_verification_runner_test.cc @@ -28,6 +28,7 @@ #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "absl/functional/any_invocable.h" #include "absl/time/time.h" #include "internal/platform/task_runner.h" #include "internal/test/fake_clock.h" @@ -142,18 +143,18 @@ class MockIncomingFramesReader : public IncomingFramesReader { NearbyConnection* connection) : IncomingFramesReader(service_thread, connection) {} - MOCK_METHOD( - void, ReadFrame, - (std::function)> callback, - absl::Duration timeout), - (override)); + MOCK_METHOD(void, ReadFrame, + (absl::AnyInvocable)> + callback, + absl::Duration timeout), + (override)); - MOCK_METHOD( - void, ReadFrame, - (service::proto::V1Frame_FrameType frame_type, - std::function)> callback, - absl::Duration timeout), - (override)); + MOCK_METHOD(void, ReadFrame, + (service::proto::V1Frame_FrameType frame_type, + absl::AnyInvocable)> + callback, + absl::Duration timeout), + (override)); }; PairedKeyVerificationRunner::PairedKeyVerificationResult Merge( @@ -240,9 +241,9 @@ class PairedKeyVerificationRunnerTest : public testing::Test { ReadFrame(testing::Eq(V1Frame::PAIRED_KEY_ENCRYPTION), testing::_, testing::Eq(kTimeout))) .WillOnce(testing::WithArg<1>( - [frame_type]( - std::function)> - callback) { + [frame_type](absl::AnyInvocable)> + callback) { if (frame_type == ReturnFrameType::kNull) { std::move(callback)(/*is_timeout=*/false, std::nullopt); return; @@ -302,7 +303,8 @@ class PairedKeyVerificationRunnerTest : public testing::Test { ReadFrame(testing::Eq(V1Frame::PAIRED_KEY_RESULT), testing::_, testing::Eq(kTimeout))) .WillOnce(testing::WithArg<1>( - [=](std::function)> + [=](absl::AnyInvocable)> callback) { if (frame_type == ReturnFrameType::kNull) { std::move(callback)(/*is_timeout=*/false, std::nullopt); From e8dbe745f83932a9689272ed0c7d5d7f26f4b8f2 Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 24 Mar 2026 23:31:42 -0700 Subject: [PATCH 027/151] Fix a few error triggered when trying to roll nearby in Chromium. PiperOrigin-RevId: 889051225 --- connections/implementation/client_proxy.cc | 9 +++++++++ internal/platform/implementation/platform.h | 18 +++++++----------- internal/platform/implementation/shared/file.h | 4 ++-- internal/platform/service_address.h | 13 +++++++++++++ 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index df7ec898..760f358c 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -60,7 +60,9 @@ #include "internal/platform/byte_array.h" #include "internal/platform/cancelable_alarm.h" #include "internal/platform/cancellation_flag.h" +#ifndef NEARBY_CHROMIUM #include "internal/platform/device_info_impl.h" +#endif #include "internal/platform/error_code_params.h" #include "internal/platform/error_code_recorder.h" #include "internal/platform/feature_flags.h" @@ -1329,6 +1331,12 @@ std::optional ClientProxy::GetEndpointIdForDct() const { return dct_endpoint_id_; } +#ifdef NEARBY_CHROMIUM +void ClientProxy::InitializePreferencesManager() { + // This method is not currently used by Chromium. + NOTREACHED(); +} +#else void ClientProxy::InitializePreferencesManager() { LOG(INFO) << "ClientProxy [InitializePreferencesManager]: client=" << GetClientId(); @@ -1350,6 +1358,7 @@ void ClientProxy::InitializePreferencesManager() { << GetClientId(); } } +#endif void ClientProxy::SaveClientInfoToPreferences() { MutexLock lock(&mutex_); diff --git a/internal/platform/implementation/platform.h b/internal/platform/implementation/platform.h index 49aaed18..6c923033 100644 --- a/internal/platform/implementation/platform.h +++ b/internal/platform/implementation/platform.h @@ -134,7 +134,6 @@ class ImplementationPlatform { static std::unique_ptr CreateWifiHotspotMedium(); static std::unique_ptr CreateWifiDirectMedium(); static std::unique_ptr CreateTimer(); - static std::unique_ptr CreateDeviceInfo(); #ifndef NO_WEBRTC static std::unique_ptr CreateWebRtcMedium(); #endif @@ -145,10 +144,17 @@ class ImplementationPlatform { state_updated_callback) { return nullptr; } + static std::unique_ptr + CreatePreferencesManager(absl::string_view path) { + return nullptr; + } #else static std::unique_ptr CreateAppLifecycleMonitor( std::function state_updated_callback); + static std::unique_ptr + CreatePreferencesManager(absl::string_view path); + static std::unique_ptr CreateDeviceInfo(); #endif // Gets HTTP response from remote server. @@ -159,16 +165,6 @@ class ImplementationPlatform { // return WebResponse if HTTP status code between 200 and 300. // other cases will return absl Status in error. static absl::StatusOr SendRequest(const WebRequest& request); - -#if defined(NEARBY_CHROMIUM) - static std::unique_ptr - CreatePreferencesManager(absl::string_view path) { - return nullptr; - } -#else - static std::unique_ptr - CreatePreferencesManager(absl::string_view path); -#endif }; } // namespace api diff --git a/internal/platform/implementation/shared/file.h b/internal/platform/implementation/shared/file.h index fbf7bfd0..ddc71828 100644 --- a/internal/platform/implementation/shared/file.h +++ b/internal/platform/implementation/shared/file.h @@ -15,7 +15,6 @@ #ifndef PLATFORM_IMPL_SHARED_FILE_H_ #define PLATFORM_IMPL_SHARED_FILE_H_ -#include #include #include #include @@ -23,6 +22,7 @@ #include "absl/strings/string_view.h" #include "absl/time/time.h" +#include "internal/platform/byte_array.h" #include "internal/platform/exception.h" #include "internal/platform/implementation/input_file.h" #include "internal/platform/implementation/output_file.h" @@ -49,7 +49,7 @@ class IOFile final : public api::InputFile, public api::OutputFile { void SetLastModifiedTime(absl::Time last_modified_time) override; private: - explicit IOFile(absl::string_view file_path) : path_(file_path) {}; + explicit IOFile(absl::string_view file_path) : path_(file_path) {} void OpenForRead(); void OpenForWrite(); diff --git a/internal/platform/service_address.h b/internal/platform/service_address.h index dfc6d83b..887e0b18 100644 --- a/internal/platform/service_address.h +++ b/internal/platform/service_address.h @@ -16,6 +16,7 @@ #define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_SERVICE_ADDRESS_H_ #include +#include #include #include @@ -44,6 +45,18 @@ void AbslStringify(Sink& sink, const ServiceAddress& service_address) { service_address.port); } +#ifdef NEARBY_CHROMIUM +// Support logging of ServiceAddress (Chromium does not use absl log). +inline std::ostream& operator<<(std::ostream& os, + const ServiceAddress& service_address) { + return os << "[" + << WifiUtils::GetHumanReadableIpAddress( + std::string(service_address.address.begin(), + service_address.address.end())) + << "]:" << service_address.port; +} +#endif + void ServiceAddressToProto( const ServiceAddress& service_address, location::nearby::connections::ServiceAddress& proto); From c855c882c49612c50189126776d80eb1e27c55aa Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 25 Mar 2026 13:09:39 -0700 Subject: [PATCH 028/151] absl::StatusOr is banned in Chromium https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++-features.md#statusor-banned PiperOrigin-RevId: 889397318 --- internal/platform/implementation/platform.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/platform/implementation/platform.h b/internal/platform/implementation/platform.h index 6c923033..8cce972e 100644 --- a/internal/platform/implementation/platform.h +++ b/internal/platform/implementation/platform.h @@ -155,7 +155,6 @@ class ImplementationPlatform { static std::unique_ptr CreatePreferencesManager(absl::string_view path); static std::unique_ptr CreateDeviceInfo(); -#endif // Gets HTTP response from remote server. // @@ -165,6 +164,7 @@ class ImplementationPlatform { // return WebResponse if HTTP status code between 200 and 300. // other cases will return absl Status in error. static absl::StatusOr SendRequest(const WebRequest& request); +#endif }; } // namespace api From a189a612f99a3814ae02f9d7c48319e9c485a517 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 27 Mar 2026 12:19:26 -0700 Subject: [PATCH 029/151] Add InitiatePairing to NearbySharingService. PiperOrigin-RevId: 890580038 --- sharing/BUILD | 1 + sharing/fake_nearby_sharing_service.h | 6 + sharing/nearby_sharing_service.h | 6 + sharing/nearby_sharing_service_impl.cc | 106 +++++++++- sharing/nearby_sharing_service_impl.h | 12 ++ sharing/nearby_sharing_service_impl_test.cc | 212 +++++++++++++++++++- 6 files changed, 337 insertions(+), 6 deletions(-) diff --git a/sharing/BUILD b/sharing/BUILD index 20356bdb..cf5615b9 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -394,6 +394,7 @@ cc_library( "//location/nearby/sharing/lib/account:account_manager", "//location/nearby/sharing/lib/rpc:grpc_async_client_factory", "//location/nearby/sharing/lib/rpc:sharing_rpc_client", + "//location/nearby/sharing/lib/sync:sync_binding_prefs_cc_proto", "//location/nearby/sharing/lib/sync:sync_manager", "//proto:sharing_enums_cc_proto", "//sharing/analytics", diff --git a/sharing/fake_nearby_sharing_service.h b/sharing/fake_nearby_sharing_service.h index 2b56e41c..db47f7b1 100644 --- a/sharing/fake_nearby_sharing_service.h +++ b/sharing/fake_nearby_sharing_service.h @@ -117,6 +117,12 @@ class FakeNearbySharingService : public NearbySharingService { std::function status_codes_callback) override; + void InitiatePairing( + int64_t share_target_id, + service::proto::BindingRequest::Type binding_type, + absl::AnyInvocable + status_codes_callback) override {} + std::string Dump() const override; bool IsBluetoothPresent() const override { return true; } bool IsBluetoothPowered() const override { return true; } diff --git a/sharing/nearby_sharing_service.h b/sharing/nearby_sharing_service.h index 6460f3b8..da83f804 100644 --- a/sharing/nearby_sharing_service.h +++ b/sharing/nearby_sharing_service.h @@ -206,6 +206,12 @@ class NearbySharingService { int64_t share_target_id, std::function status_codes_callback) = 0; + virtual void InitiatePairing( + int64_t share_target_id, + service::proto::BindingRequest::Type binding_type, + absl::AnyInvocable + status_codes_callback) = 0; + // Checks to make sure visibility setting is valid and updates the service's // visibility if so. virtual void SetVisibility( diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 2769409c..1214f38b 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -33,6 +33,7 @@ #include "location/nearby/sharing/lib/account/account_manager.h" #include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" +#include "location/nearby/sharing/lib/sync/sync_binding_prefs.pb.h" #include "absl/base/nullability.h" #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" @@ -113,10 +114,12 @@ using ::absl::Milliseconds; using ::location::nearby::proto::sharing::OSType; using ::location::nearby::proto::sharing::ResponseToIntroduction; using ::location::nearby::proto::sharing::SessionStatus; -using ::nearby::sharing::api::SharingPlatform; using ::nearby::sharing::api::IdentityRpcClient; +using ::nearby::sharing::api::SharingPlatform; using ::nearby::sharing::proto::DataUsage; using ::nearby::sharing::proto::DeviceVisibility; +using ::nearby::sharing::service::proto::BindingRequest; +using ::nearby::sharing::service::proto::BindingResponse; using ::nearby::sharing::service::proto::ConnectionResponseFrame; using ::nearby::sharing::service::proto::IntroductionFrame; @@ -948,6 +951,33 @@ void NearbySharingServiceImpl::DoCancel( std::move(status_codes_callback)(StatusCodes::kOk); } +void NearbySharingServiceImpl::InitiatePairing( + int64_t share_target_id, BindingRequest::Type binding_type, + absl::AnyInvocable + status_codes_callback) { + RunOnNearbySharingServiceThread( + "api_initiate_pairing", + [this, share_target_id, binding_type, + status_codes_callback = std::move(status_codes_callback)]() mutable { + LOG(INFO) << "InitiatePairing is called"; + OutgoingShareSession* session = + outgoing_targets_manager_.GetOutgoingShareSession(share_target_id); + if (!session) { + LOG(WARNING) << "InitiatePairing invoked for unknown share target"; + std::move(status_codes_callback)(StatusCodes::kInvalidArgument); + return; + } + if (binding_type != BindingRequest::FILESYNC) { + LOG(WARNING) << __func__ << "Only FileSync bindings are supported."; + std::move(status_codes_callback)(StatusCodes::kInvalidArgument); + return; + } + // Start connection without attachments will initiate pairing. + std::move(status_codes_callback)( + ConnectOutgoingSessionOnServiceThread(*session)); + }); +} + void NearbySharingServiceImpl::SetVisibility( proto::DeviceVisibility visibility, absl::Duration expiration, absl::AnyInvocable callback) { @@ -2571,7 +2601,79 @@ void NearbySharingServiceImpl::BeginOutgoingPairing( OutgoingShareSession& session) { VLOG(1) << __func__ << ": Preparing to initiate pairing with " << session.share_target().id; - // TODO(ftsui): Implement this. + // Verify that remote really authenticated with self share certificate. + if (!session.self_share()) { + LOG(WARNING) << __func__ << ": Not self share, skipping pairing."; + session.Abort(TransferMetadata::Status::kDeviceAuthenticationFailed); + return; + } + // Call InitiateBinding rpc. + sync_manager_.AsyncInitiateSyncBinding( + [this, share_target_id = session.share_target().id]( + absl::StatusOr binding_status) { + LOG(INFO) << __func__ << ": Sync binding rpc completed."; + OnInitiateSyncBindingResponse(share_target_id, + std::move(binding_status)); + }); +} + +void NearbySharingServiceImpl::OnInitiateSyncBindingResponse( + int64_t share_target_id, absl::StatusOr binding_status) { + RunOnNearbySharingServiceThread( + "start_peer_binding", + [this, share_target_id, binding_status = std::move(binding_status)]() { + OutgoingShareSession* session = + outgoing_targets_manager_.GetOutgoingShareSession(share_target_id); + if (!session || !session->IsConnected()) { + LOG(WARNING) << __func__ + << ": Session not connected, stop binding to: " + << share_target_id; + return; + } + if (binding_status.ok()) { + std::string binding_id = binding_status.value(); + LOG(INFO) << __func__ + << ": Sync binding rpc succeeded: id=" << binding_id; + session->StartPeerBinding( + binding_id, BindingRequest::FILESYNC, + [this, share_target_id, + binding_id](BindingResponse::Status status) { + OnPeerSyncBindingComplete(share_target_id, binding_id, status); + }); + } else { + LOG(INFO) << __func__ << ": Sync binding rpc failed."; + session->Abort(TransferMetadata::Status::kFailed); + } + }); +} + +void NearbySharingServiceImpl::OnPeerSyncBindingComplete( + int64_t share_target_id, absl::string_view binding_id, + BindingResponse::Status status) { + OutgoingShareSession* session = + outgoing_targets_manager_.GetOutgoingShareSession(share_target_id); + if (!session || !session->IsConnected()) { + LOG(WARNING) << __func__ << ": Session not connected, stop binding to: " + << share_target_id; + return; + } + if (status != BindingResponse::SUCCESS) { + LOG(INFO) << __func__ << ": Sync binding response failed."; + session->Abort(TransferMetadata::Status::kFailed); + return; + } + sync::SyncBinding binding; + binding.set_binding_id(binding_id); + binding.set_source_name(session->share_target().device_name); + // Set default destination directory to Downloads/`device_name`. + FilePath destination_path{settings_->GetCustomSavePath()}; + destination_path.append(FilePath(session->share_target().device_name)); + binding.set_destination_directory(destination_path.ToString()); + sync_manager_.AddSyncBinding(binding); + session->UpdateTransferMetadata( + TransferMetadataBuilder() + .set_status(TransferMetadata::Status::kComplete) + .build()); } void NearbySharingServiceImpl::OnReceivedIntroduction( diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index 542594b2..5a0a2fca 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -34,6 +34,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/functional/any_invocable.h" +#include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "absl/types/span.h" @@ -155,6 +156,10 @@ class NearbySharingServiceImpl void Cancel(int64_t share_target_id, std::function status_codes_callback) override; + void InitiatePairing(int64_t share_target_id, + service::proto::BindingRequest::Type binding_type, + absl::AnyInvocable + status_codes_callback) override; void SetVisibility( proto::DeviceVisibility visibility, absl::Duration expiration, absl::AnyInvocable callback) override; @@ -401,6 +406,13 @@ class NearbySharingServiceImpl bool OutgoingSessionAccept(OutgoingShareSession& session); void OnIncomingFilesMetadataUpdated(int64_t share_target_id, TransferMetadata metadata, bool success); + // Called when InitiateBinding rpc returns. + void OnInitiateSyncBindingResponse( + int64_t share_target_id, absl::StatusOr binding_status); + // Called when Bindings response frame is received from the peer. + void OnPeerSyncBindingComplete( + int64_t share_target_id, absl::string_view binding_id, + service::proto::BindingResponse::Status status); // Notify all registered send surfaces of share target state changes. void NotifyShareTargetDiscovered(const ShareTarget& share_target); diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index 4a12ad4b..46dfd81f 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -115,6 +115,7 @@ using ::nearby::sharing::service::proto::PairedKeyResultFrame; using ::nearby::sharing::service::proto::TextMetadata; using ::nearby::sharing::service::proto::V1Frame; using ::testing::_; +using ::protobuf_matchers::EqualsProto; using ::testing::InSequence; using ::testing::NiceMock; using ::testing::Return; @@ -842,19 +843,22 @@ class NearbySharingServiceImplTest : public testing::Test { int64_t SetUpOutgoingShareTarget( MockTransferUpdateCallback& transfer_callback, - MockShareTargetDiscoveredCallback& discovery_callback) { + MockShareTargetDiscoveredCallback& discovery_callback, + bool for_self_share = false) { SetUpKeyVerification( /*is_incoming=*/false, PairedKeyResultFrame::SUCCESS); fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, GetToken()); fake_nearby_connections_manager_->set_nearby_connection(connection_.get()); - return DiscoverShareTarget(transfer_callback, discovery_callback); + return DiscoverShareTarget(transfer_callback, discovery_callback, + for_self_share); } int64_t DiscoverShareTarget( MockTransferUpdateCallback& transfer_callback, - MockShareTargetDiscoveredCallback& discovery_callback) { + MockShareTargetDiscoveredCallback& discovery_callback, + bool for_self_share = false) { SetLanConnected(true); // Start discovering, to ensure a discovery listener is registered. @@ -876,7 +880,7 @@ class NearbySharingServiceImplTest : public testing::Test { std::move(endpoint_info)); FlushTesting(); ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1, - /*success=*/true); + /*success=*/true, for_self_share); return discovered_target_id; } @@ -4896,5 +4900,205 @@ TEST_F(NearbySharingServiceImplTest, NotifyLogoutSucceededWithCredentialError) { FlushTesting(); } +TEST_F(NearbySharingServiceImplTest, InitiatePairingNotSelfShare) { + MockTransferUpdateCallback transfer_callback; + MockShareTargetDiscoveredCallback discovery_callback; + int64_t target_id = SetUpOutgoingShareTarget( + transfer_callback, discovery_callback, /*for_self_share=*/false); + ScopedSendSurface s(service_.get(), &transfer_callback); + + absl::Notification notification; + ExpectTransferUpdates(transfer_callback, target_id, + {TransferMetadata::Status::kConnecting, + TransferMetadata::Status::kDeviceAuthenticationFailed}, + [&] { notification.Notify(); }); + + absl::Notification pairing_notification; + NearbySharingServiceImpl::StatusCodes pairing_result; + EXPECT_CALL(*mock_app_info_, SetActiveFlag()); + service_->InitiatePairing( + target_id, service::proto::BindingRequest::FILESYNC, + [&](NearbySharingServiceImpl::StatusCodes status_code) { + pairing_result = status_code; + pairing_notification.Notify(); + }); + EXPECT_TRUE( + pairing_notification.WaitForNotificationWithTimeout(kTaskWaitTimeout)); + EXPECT_EQ(pairing_result, NearbySharingServiceImpl::StatusCodes::kOk); + + FlushTesting(); + // Verify data sent to the remote device so far. + EXPECT_TRUE(ExpectPairedKeyEncryptionFrame()); + EXPECT_TRUE(ExpectPairedKeyResultFrame()); + // Wait for the transfer updates. + EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout)); +} + +TEST_F(NearbySharingServiceImplTest, InitiatePairingBindingRpcFailed) { + MockTransferUpdateCallback transfer_callback; + MockShareTargetDiscoveredCallback discovery_callback; + int64_t target_id = SetUpOutgoingShareTarget( + transfer_callback, discovery_callback, /*for_self_share=*/true); + ScopedSendSurface s(service_.get(), &transfer_callback); + + absl::Notification notification; + ExpectTransferUpdates(transfer_callback, target_id, + {TransferMetadata::Status::kConnecting, + TransferMetadata::Status::kFailed}, + [&] { notification.Notify(); }); + + absl::Notification pairing_notification; + NearbySharingServiceImpl::StatusCodes pairing_result; + EXPECT_CALL(*mock_app_info_, SetActiveFlag()); + nearby_identity_client_.SetInitiateBindingResponses( + {absl::InternalError("Binding RPC failed")}); + service_->InitiatePairing( + target_id, service::proto::BindingRequest::FILESYNC, + [&](NearbySharingServiceImpl::StatusCodes status_code) { + pairing_result = status_code; + pairing_notification.Notify(); + }); + EXPECT_TRUE( + pairing_notification.WaitForNotificationWithTimeout(kTaskWaitTimeout)); + EXPECT_EQ(pairing_result, NearbySharingServiceImpl::StatusCodes::kOk); + + FlushTesting(); + // Verify data sent to the remote device so far. + EXPECT_TRUE(ExpectPairedKeyEncryptionFrame()); + EXPECT_TRUE(ExpectPairedKeyResultFrame()); + // Wait for the transfer updates. + EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout)); +} + +TEST_F(NearbySharingServiceImplTest, + InitiatePairingPeerBindingResponseTimeout) { + MockTransferUpdateCallback transfer_callback; + MockShareTargetDiscoveredCallback discovery_callback; + int64_t target_id = SetUpOutgoingShareTarget( + transfer_callback, discovery_callback, /*for_self_share=*/true); + ScopedSendSurface s(service_.get(), &transfer_callback); + absl::Notification notification; + ExpectTransferUpdates(transfer_callback, target_id, + {TransferMetadata::Status::kConnecting, + TransferMetadata::Status::kAwaitingRemoteAcceptance, + TransferMetadata::Status::kFailed}, + [&] { notification.Notify(); }); + + absl::Notification pairing_notification; + NearbySharingServiceImpl::StatusCodes pairing_result; + EXPECT_CALL(*mock_app_info_, SetActiveFlag()); + constexpr absl::string_view kBindingId = "binding_id"; + google::nearby::identity::v1::InitiateBindingResponse response; + response.set_binding_id(kBindingId); + nearby_identity_client_.SetInitiateBindingResponses({response}); + service_->InitiatePairing( + target_id, service::proto::BindingRequest::FILESYNC, + [&](NearbySharingServiceImpl::StatusCodes status_code) { + pairing_result = status_code; + pairing_notification.Notify(); + }); + EXPECT_TRUE( + pairing_notification.WaitForNotificationWithTimeout(kTaskWaitTimeout)); + EXPECT_EQ(pairing_result, NearbySharingServiceImpl::StatusCodes::kOk); + + FlushTesting(); + // Verify data sent to the remote device so far. + if (!ExpectPairedKeyEncryptionFrame()) { + return; + } + + if (!ExpectPairedKeyResultFrame()) { + return; + } + // Check BindingRequest frame sent to the remote device. + std::unique_ptr frame = GetWrittenFrame(); + ASSERT_TRUE(frame->has_v1()); + EXPECT_EQ(frame->v1().type(), service::proto::V1Frame::BINDINGS); + EXPECT_EQ(frame->v1().bindings().binding_request().binding_id(), kBindingId); + EXPECT_EQ(frame->v1().bindings().binding_request().type(), + service::proto::BindingRequest::FILESYNC); + + // BindingResponse frame timeout. + FastForward(absl::Seconds(60)); + // Wait for the transfer updates. + EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout)); +} + +TEST_F(NearbySharingServiceImplTest, InitiatePairingSuccess) { + MockTransferUpdateCallback transfer_callback; + MockShareTargetDiscoveredCallback discovery_callback; + int64_t target_id = SetUpOutgoingShareTarget( + transfer_callback, discovery_callback, /*for_self_share=*/true); + ScopedSendSurface s(service_.get(), &transfer_callback); + absl::Notification notification; + ExpectTransferUpdates(transfer_callback, target_id, + {TransferMetadata::Status::kConnecting, + TransferMetadata::Status::kAwaitingRemoteAcceptance, + TransferMetadata::Status::kComplete}, + [&] { notification.Notify(); }); + + absl::Notification pairing_notification; + NearbySharingServiceImpl::StatusCodes pairing_result; + EXPECT_CALL(*mock_app_info_, SetActiveFlag()); + constexpr absl::string_view kBindingId = "binding_id"; + google::nearby::identity::v1::InitiateBindingResponse response; + response.set_binding_id(kBindingId); + nearby_identity_client_.SetInitiateBindingResponses({response}); + service_->InitiatePairing( + target_id, service::proto::BindingRequest::FILESYNC, + [&](NearbySharingServiceImpl::StatusCodes status_code) { + pairing_result = status_code; + pairing_notification.Notify(); + }); + EXPECT_TRUE( + pairing_notification.WaitForNotificationWithTimeout(kTaskWaitTimeout)); + EXPECT_EQ(pairing_result, NearbySharingServiceImpl::StatusCodes::kOk); + + FlushTesting(); + // Verify data sent to the remote device so far. + if (!ExpectPairedKeyEncryptionFrame()) { + return; + } + + if (!ExpectPairedKeyResultFrame()) { + return; + } + // Check BindingRequest frame sent to the remote device. + std::unique_ptr frame = GetWrittenFrame(); + ASSERT_TRUE(frame->has_v1()); + EXPECT_EQ(frame->v1().type(), service::proto::V1Frame::BINDINGS); + EXPECT_EQ(frame->v1().bindings().binding_request().binding_id(), kBindingId); + EXPECT_EQ(frame->v1().bindings().binding_request().type(), + service::proto::BindingRequest::FILESYNC); + + preference_manager_.SetString(PrefNames::kCustomSavePath, "Downloads"); + Frame binding_response_frame; + binding_response_frame.set_version(Frame::V1); + binding_response_frame.mutable_v1()->set_type( + service::proto::V1Frame::BINDINGS); + binding_response_frame.mutable_v1() + ->mutable_bindings() + ->mutable_binding_response() + ->set_status(service::proto::BindingResponse::SUCCESS); + std::vector result_bytes(binding_response_frame.ByteSizeLong()); + binding_response_frame.SerializeToArray(result_bytes.data(), + result_bytes.size()); + ReceiveMessageFromConnection(std::move(result_bytes)); + + // Wait for the transfer updates. + EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout)); + + std::optional binding = + preference_manager_.GetSyncBindingValue(); + ASSERT_TRUE(binding.has_value()); + EXPECT_EQ(binding->sync_bindings().size(), 1); + sync::SyncBinding expected_binding; + expected_binding.set_binding_id(kBindingId); + expected_binding.set_source_name(kDeviceName); + expected_binding.set_destination_directory( + FilePath("Downloads").append(FilePath(kDeviceName)).ToString()); + EXPECT_THAT(binding->sync_bindings(0), EqualsProto(expected_binding)); +} + } // namespace NearbySharingServiceUnitTests } // namespace nearby::sharing From 300881d3edf5723065b552984adc3ac791ac2e73 Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 27 Mar 2026 14:02:35 -0700 Subject: [PATCH 030/151] Add more speed test results, rssi and inactivity event count PiperOrigin-RevId: 890625346 --- internal/proto/analytics/connections_log.proto | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/proto/analytics/connections_log.proto b/internal/proto/analytics/connections_log.proto index 1e10edad..3be13ef3 100644 --- a/internal/proto/analytics/connections_log.proto +++ b/internal/proto/analytics/connections_log.proto @@ -451,6 +451,13 @@ message ConnectionsLog { // The speed test report. optional SpeedTestReport speed_test_report = 15; + + // The count of long inactivity events without any payload transfer. + optional int32 inactivity_count = 16; + + // The RSSI (radio signal strength indicator) in dBm. + // INTERNET_RSSI_UNKNOWN (-127) if unknown. + optional int32 rssi = 17; } message SpeedTestReport { From 90028655d2d63846fab281c52e194b0eb5003734 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 30 Mar 2026 09:10:39 -0700 Subject: [PATCH 031/151] Cleanup DeviceInfo PiperOrigin-RevId: 891750619 --- internal/platform/device_info_impl.cc | 21 ++------ .../apple/Tests/GNCDeviceInfoTest.mm | 17 ++---- .../implementation/apple/device_info.h | 12 ++--- .../implementation/apple/device_info.mm | 18 +++---- .../platform/implementation/device_info.h | 10 ++-- .../platform/implementation/g3/device_info.h | 21 +++----- .../implementation/windows/device_info.cc | 53 ++++--------------- .../implementation/windows/device_info.h | 10 ++-- .../windows/device_info_test.cc | 13 ++--- .../windows/preferences_repository_test.cc | 12 +++-- 10 files changed, 55 insertions(+), 132 deletions(-) diff --git a/internal/platform/device_info_impl.cc b/internal/platform/device_info_impl.cc index 79d5be7f..91c04021 100644 --- a/internal/platform/device_info_impl.cc +++ b/internal/platform/device_info_impl.cc @@ -44,32 +44,19 @@ api::DeviceInfo::OsType DeviceInfoImpl::GetOsType() const { } FilePath DeviceInfoImpl::GetDownloadPath() const { - std::optional path = device_info_impl_->GetDownloadPath(); - if (path.has_value()) { - return *path; - } - return Files::GetTemporaryDirectory(); + return device_info_impl_->GetDownloadPath(); } FilePath DeviceInfoImpl::GetAppDataPath() const { - std::optional path = device_info_impl_->GetLocalAppDataPath(); - if (path.has_value()) { - return *path; - } - return Files::GetTemporaryDirectory(); + return device_info_impl_->GetLocalAppDataPath(FilePath()); } FilePath DeviceInfoImpl::GetTemporaryPath() const { - std::optional path = device_info_impl_->GetTemporaryPath(); - if (path.has_value()) { - return *path; - } - return Files::GetTemporaryDirectory(); + return device_info_impl_->GetTemporaryPath(); } FilePath DeviceInfoImpl::GetLogPath() const { - std::optional path = device_info_impl_->GetLogPath(); - return path.value_or(GetTemporaryPath()); + return device_info_impl_->GetLogPath(); } std::optional DeviceInfoImpl::GetAvailableDiskSpaceInBytes( diff --git a/internal/platform/implementation/apple/Tests/GNCDeviceInfoTest.mm b/internal/platform/implementation/apple/Tests/GNCDeviceInfoTest.mm index 39988866..edaf54ad 100644 --- a/internal/platform/implementation/apple/Tests/GNCDeviceInfoTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCDeviceInfoTest.mm @@ -49,27 +49,20 @@ } - (void)testGetDownloadPath { - XCTAssertNotNil(@(_deviceInfo->GetDownloadPath().value().GetPath().c_str())); + XCTAssertNotNil(@(_deviceInfo->GetDownloadPath().GetPath().c_str())); } - (void)testGetLocalAppDataPath { - XCTAssertNotNil(@(_deviceInfo->GetLocalAppDataPath().value().GetPath().c_str())); -} - -- (void)testGetCommonAppDataPath { - XCTAssertNotNil(@(_deviceInfo->GetCommonAppDataPath().value().GetPath().c_str())); + XCTAssertNotNil( + @(_deviceInfo->GetLocalAppDataPath(nearby::FilePath("sub_path")).GetPath().c_str())); } - (void)testGetTemporaryPath { - XCTAssertNotNil(@(_deviceInfo->GetTemporaryPath().value().GetPath().c_str())); + XCTAssertNotNil(@(_deviceInfo->GetTemporaryPath().GetPath().c_str())); } - (void)testGetLogPath { - XCTAssertNotNil(@(_deviceInfo->GetLogPath().value().GetPath().c_str())); -} - -- (void)testGetCrashDumpPath { - XCTAssertNotNil(@(_deviceInfo->GetCrashDumpPath().value().GetPath().c_str())); + XCTAssertNotNil(@(_deviceInfo->GetLogPath().GetPath().c_str())); } - (void)testIsScreenLocked { diff --git a/internal/platform/implementation/apple/device_info.h b/internal/platform/implementation/apple/device_info.h index ce436201..e42b2b16 100644 --- a/internal/platform/implementation/apple/device_info.h +++ b/internal/platform/implementation/apple/device_info.h @@ -34,17 +34,13 @@ class DeviceInfo : public api::DeviceInfo { api::DeviceInfo::OsType GetOsType() const override; - std::optional GetDownloadPath() const override; + FilePath GetDownloadPath() const override; - std::optional GetLocalAppDataPath() const override; + FilePath GetLocalAppDataPath(FilePath sub_path) const override; - std::optional GetCommonAppDataPath() const override; + FilePath GetTemporaryPath() const override; - std::optional GetTemporaryPath() const override; - - std::optional GetLogPath() const override; - - std::optional GetCrashDumpPath() const override; + FilePath GetLogPath() const override; bool IsScreenLocked() const override; diff --git a/internal/platform/implementation/apple/device_info.mm b/internal/platform/implementation/apple/device_info.mm index 08dc3536..c66f3148 100644 --- a/internal/platform/implementation/apple/device_info.mm +++ b/internal/platform/implementation/apple/device_info.mm @@ -79,7 +79,7 @@ api::DeviceInfo::OsType DeviceInfo::GetOsType() const { #endif } -std::optional DeviceInfo::GetDownloadPath() const { +FilePath DeviceInfo::GetDownloadPath() const { NSFileManager *manager = [NSFileManager defaultManager]; NSError *error = nil; @@ -90,30 +90,24 @@ std::optional DeviceInfo::GetDownloadPath() const { error:&error]; if (!downloadsURL) { GNCLoggerError(@"Failed to get download path: %@", error); - return std::nullopt; + return GetTemporaryPath(); } return FilePath(absl::string_view([downloadsURL.path cString])); } -std::optional DeviceInfo::GetLocalAppDataPath() const { - return FilePath(absl::string_view([GNCLocalAppDataPath().path cString])); +FilePath DeviceInfo::GetLocalAppDataPath(FilePath sub_path) const { + return FilePath(absl::string_view([GNCLocalAppDataPath().path cString])).append(sub_path); } -std::optional DeviceInfo::GetCommonAppDataPath() const { return GetLocalAppDataPath(); } - -std::optional DeviceInfo::GetTemporaryPath() const { +FilePath DeviceInfo::GetTemporaryPath() const { return FilePath(absl::string_view([NSTemporaryDirectory() cString])); } -std::optional DeviceInfo::GetLogPath() const { +FilePath DeviceInfo::GetLogPath() const { return FilePath(absl::string_view([GNCLogPath().path cString])); } -std::optional DeviceInfo::GetCrashDumpPath() const { - return FilePath(absl::string_view([GNCCrashDumpPath().path cString])); -} - bool DeviceInfo::IsScreenLocked() const { return false; } void DeviceInfo::RegisterScreenLockedListener( diff --git a/internal/platform/implementation/device_info.h b/internal/platform/implementation/device_info.h index 19aca037..4426ef7d 100644 --- a/internal/platform/implementation/device_info.h +++ b/internal/platform/implementation/device_info.h @@ -46,12 +46,10 @@ class DeviceInfo { virtual OsType GetOsType() const = 0; // Gets known paths of current user. - virtual std::optional GetDownloadPath() const = 0; - virtual std::optional GetLocalAppDataPath() const = 0; - virtual std::optional GetCommonAppDataPath() const = 0; - virtual std::optional GetTemporaryPath() const = 0; - virtual std::optional GetLogPath() const = 0; - virtual std::optional GetCrashDumpPath() const = 0; + virtual FilePath GetDownloadPath() const = 0; + virtual FilePath GetLocalAppDataPath(FilePath sub_path) const = 0; + virtual FilePath GetTemporaryPath() const = 0; + virtual FilePath GetLogPath() const = 0; // Monitor screen status virtual bool IsScreenLocked() const = 0; diff --git a/internal/platform/implementation/g3/device_info.h b/internal/platform/implementation/g3/device_info.h index 5ff18863..6754d46f 100644 --- a/internal/platform/implementation/g3/device_info.h +++ b/internal/platform/implementation/g3/device_info.h @@ -45,33 +45,24 @@ class DeviceInfo : public api::DeviceInfo { return api::DeviceInfo::OsType::kChromeOs; } - std::optional GetDownloadPath() const override { + FilePath GetDownloadPath() const override { return Files::GetTemporaryDirectory(); } - std::optional GetLocalAppDataPath() const override { + FilePath GetLocalAppDataPath(FilePath sub_path) const override { if (MediumEnvironment::Instance() .GetEnvironmentConfig() .use_temporary_directory_for_app_path) { - return Files::GetTemporaryDirectory(); + return Files::GetTemporaryDirectory().append(sub_path); } - - return GetAppDataPath(); + return GetAppDataPath().append(sub_path); } - std::optional GetCommonAppDataPath() const override { + FilePath GetTemporaryPath() const override { return Files::GetTemporaryDirectory(); } - std::optional GetTemporaryPath() const override { - return Files::GetTemporaryDirectory(); - } - - std::optional GetLogPath() const override { - return Files::GetTemporaryDirectory(); - } - - std::optional GetCrashDumpPath() const override { + FilePath GetLogPath() const override { return Files::GetTemporaryDirectory(); } diff --git a/internal/platform/implementation/windows/device_info.cc b/internal/platform/implementation/windows/device_info.cc index ba05e5d3..348f7ce6 100644 --- a/internal/platform/implementation/windows/device_info.cc +++ b/internal/platform/implementation/windows/device_info.cc @@ -30,27 +30,11 @@ #include "internal/platform/implementation/windows/device_paths.h" #include "internal/platform/implementation/windows/string_utils.h" #include "internal/platform/implementation/windows/utils.h" -#include "winrt/Windows.Foundation.Collections.h" -#include "winrt/Windows.Foundation.h" -#include "winrt/Windows.System.h" namespace nearby::windows { -using IInspectable = winrt::Windows::Foundation::IInspectable; -using KnownUserProperties = winrt::Windows::System::KnownUserProperties; -using User = winrt::Windows::System::User; -using UserType = winrt::Windows::System::UserType; -using UserAuthenticationStatus = - winrt::Windows::System::UserAuthenticationStatus; - using ::nearby::windows::string_utils::WideStringToString; -template -using IVectorView = winrt::Windows::Foundation::Collections::IVectorView; - -template -using IAsyncOperation = winrt::Windows::Foundation::IAsyncOperation; - std::optional DeviceInfo::GetOsDeviceName() const { std::optional device_name = GetDnsHostName(); if (device_name.has_value()) { @@ -60,7 +44,6 @@ std::optional DeviceInfo::GetOsDeviceName() const { } api::DeviceInfo::DeviceType DeviceInfo::GetDeviceType() const { - // TODO(b/230132370): return correct device type on the Windows platform. return api::DeviceInfo::DeviceType::kLaptop; } @@ -68,7 +51,7 @@ api::DeviceInfo::OsType DeviceInfo::GetOsType() const { return api::DeviceInfo::OsType::kWindows; } -std::optional DeviceInfo::GetDownloadPath() const { +FilePath DeviceInfo::GetDownloadPath() const { PWSTR path; HRESULT result = SHGetKnownFolderPath(FOLDERID_Downloads, KF_FLAG_DEFAULT, nullptr, &path); @@ -79,37 +62,19 @@ std::optional DeviceInfo::GetDownloadPath() const { } CoTaskMemFree(path); - return std::nullopt; -} - -std::optional DeviceInfo::GetLocalAppDataPath() const { - return nearby::platform::windows::GetLocalAppDataPath(FilePath()); -} - -std::optional DeviceInfo::GetCommonAppDataPath() const { - PWSTR path; - HRESULT result = SHGetKnownFolderPath(FOLDERID_ProgramData, KF_FLAG_DEFAULT, - /*hToken=*/nullptr, &path); - if (result == S_OK) { - std::wstring common_app_data_path{path}; - CoTaskMemFree(path); - return FilePath(std::wstring_view(common_app_data_path)); - } - - CoTaskMemFree(path); - return std::nullopt; -} - -std::optional DeviceInfo::GetTemporaryPath() const { return Files::GetTemporaryDirectory(); } -std::optional DeviceInfo::GetLogPath() const { - return nearby::platform::windows::GetLogPath(); +FilePath DeviceInfo::GetLocalAppDataPath(FilePath sub_path) const { + return nearby::platform::windows::GetLocalAppDataPath(sub_path); } -std::optional DeviceInfo::GetCrashDumpPath() const { - return nearby::platform::windows::GetCrashDumpPath(); +FilePath DeviceInfo::GetTemporaryPath() const { + return Files::GetTemporaryDirectory(); +} + +FilePath DeviceInfo::GetLogPath() const { + return nearby::platform::windows::GetLogPath(); } bool DeviceInfo::IsScreenLocked() const { diff --git a/internal/platform/implementation/windows/device_info.h b/internal/platform/implementation/windows/device_info.h index 1b4cfe99..8de0d388 100644 --- a/internal/platform/implementation/windows/device_info.h +++ b/internal/platform/implementation/windows/device_info.h @@ -37,12 +37,10 @@ class DeviceInfo : public api::DeviceInfo { api::DeviceInfo::DeviceType GetDeviceType() const override; api::DeviceInfo::OsType GetOsType() const override; - std::optional GetDownloadPath() const override; - std::optional GetLocalAppDataPath() const override; - std::optional GetCommonAppDataPath() const override; - std::optional GetTemporaryPath() const override; - std::optional GetLogPath() const override; - std::optional GetCrashDumpPath() const override; + FilePath GetDownloadPath() const override; + FilePath GetLocalAppDataPath(FilePath sub_path) const override; + FilePath GetTemporaryPath() const override; + FilePath GetLogPath() const override; bool IsScreenLocked() const override; void RegisterScreenLockedListener( diff --git a/internal/platform/implementation/windows/device_info_test.cc b/internal/platform/implementation/windows/device_info_test.cc index 6431e5ea..295992a6 100644 --- a/internal/platform/implementation/windows/device_info_test.cc +++ b/internal/platform/implementation/windows/device_info_test.cc @@ -40,23 +40,20 @@ TEST(DeviceInfo, GetOsType) { } TEST(DeviceInfo, DISABLED_GetLocalAppDataPath) { - EXPECT_TRUE(DeviceInfo().GetLocalAppDataPath().has_value()); + EXPECT_FALSE( + DeviceInfo().GetLocalAppDataPath(FilePath("sub_path")).IsEmpty()); } TEST(DeviceInfo, DISABLED_GetDownloadPath) { - EXPECT_TRUE(DeviceInfo().GetDownloadPath().has_value()); + EXPECT_FALSE(DeviceInfo().GetDownloadPath().IsEmpty()); } TEST(DeviceInfo, DISABLED_GetTemporaryPath) { - EXPECT_TRUE(DeviceInfo().GetTemporaryPath().has_value()); + EXPECT_FALSE(DeviceInfo().GetTemporaryPath().IsEmpty()); } TEST(DeviceInfo, DISABLED_GetLogPath) { - EXPECT_TRUE(DeviceInfo().GetLogPath().has_value()); -} - -TEST(DeviceInfo, DISABLED_GetCrashDumpPath) { - EXPECT_TRUE(DeviceInfo().GetCrashDumpPath().has_value()); + EXPECT_FALSE(DeviceInfo().GetLogPath().IsEmpty()); } TEST(DeviceInfo, DISABLED_IsScreenLocked) { diff --git a/internal/platform/implementation/windows/preferences_repository_test.cc b/internal/platform/implementation/windows/preferences_repository_test.cc index 0ef8de90..473e5105 100644 --- a/internal/platform/implementation/windows/preferences_repository_test.cc +++ b/internal/platform/implementation/windows/preferences_repository_test.cc @@ -44,7 +44,8 @@ TEST(PreferencesRepository, LoadWithBadPath) { TEST(PreferencesRepository, RecoverFromBadPreferences) { std::optional app_data_path = - api::ImplementationPlatform::CreateDeviceInfo()->GetLocalAppDataPath(); + api::ImplementationPlatform::CreateDeviceInfo()->GetLocalAppDataPath( + FilePath()); ASSERT_TRUE(app_data_path.has_value()); FilePath full_path = app_data_path->append(FilePath(kPreferencesPath)); FilePath full_name = app_data_path->append(FilePath(kPreferencesFileName)); @@ -63,7 +64,8 @@ TEST(PreferencesRepository, RecoverFromBadPreferences) { TEST(PreferencesRepository, SaveAndLoadPreferences) { std::optional app_data_path = - api::ImplementationPlatform::CreateDeviceInfo()->GetLocalAppDataPath(); + api::ImplementationPlatform::CreateDeviceInfo()->GetLocalAppDataPath( + FilePath()); ASSERT_TRUE(app_data_path.has_value()); FilePath full_path = app_data_path->append(FilePath(kPreferencesPath)); FilePath full_name = app_data_path->append(FilePath(kPreferencesFileName)); @@ -86,7 +88,8 @@ TEST(PreferencesRepository, SaveAndLoadPreferences) { TEST(PreferencesRepository, LoadFromBackup) { std::optional app_data_path = - api::ImplementationPlatform::CreateDeviceInfo()->GetLocalAppDataPath(); + api::ImplementationPlatform::CreateDeviceInfo()->GetLocalAppDataPath( + FilePath()); ASSERT_TRUE(app_data_path.has_value()); FilePath full_path = app_data_path->append(FilePath(kPreferencesPath)); FilePath full_name = app_data_path->append(FilePath(kPreferencesFileName)); @@ -123,7 +126,8 @@ TEST(PreferencesRepository, LoadFromBackup) { TEST(PreferencesRepository, RecoverFromCorruption) { std::optional app_data_path = - api::ImplementationPlatform::CreateDeviceInfo()->GetLocalAppDataPath(); + api::ImplementationPlatform::CreateDeviceInfo()->GetLocalAppDataPath( + FilePath()); ASSERT_TRUE(app_data_path.has_value()); FilePath full_path = app_data_path->append(FilePath(kPreferencesPath)); FilePath full_name = app_data_path->append(FilePath(kPreferencesFileName)); From ac70b1f91fa8d922ae133a92542021611f67af6c Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 30 Mar 2026 16:33:59 -0700 Subject: [PATCH 032/151] Remove SyncConfig frames. PiperOrigin-RevId: 891975054 --- sharing/BUILD | 2 - sharing/common/nearby_share_prefs.cc | 1 - sharing/incoming_share_session.cc | 45 ------------------- sharing/incoming_share_session.h | 7 --- sharing/internal/api/BUILD | 1 - sharing/internal/api/preference_manager.h | 11 ----- sharing/internal/public/pref_names.h | 7 --- sharing/internal/test/BUILD | 1 - .../internal/test/fake_preference_manager.cc | 30 ------------- .../internal/test/fake_preference_manager.h | 7 --- sharing/nearby_sharing_service_impl.cc | 6 --- 11 files changed, 118 deletions(-) diff --git a/sharing/BUILD b/sharing/BUILD index cf5615b9..4de4b542 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -236,8 +236,6 @@ cc_library( "//internal/base:file_path", "//internal/base:files", "//internal/platform:types", - "//location/nearby/sharing/lib/sync:sync_config_prefs_cc_proto", - "//location/nearby/sharing/lib/sync:sync_manager", "//proto:sharing_enums_cc_proto", "//sharing/analytics", "//sharing/certificates", diff --git a/sharing/common/nearby_share_prefs.cc b/sharing/common/nearby_share_prefs.cc index 279b352b..9d988ba5 100644 --- a/sharing/common/nearby_share_prefs.cc +++ b/sharing/common/nearby_share_prefs.cc @@ -67,7 +67,6 @@ void RegisterNearbySharingPrefs(PreferenceManager& preference_manager, preference_manager.Remove(PrefNames::kUsers); preference_manager.SetBoolean(PrefNames::kAdvancedProtectionEnabled, false); - preference_manager.RemoveAllSyncConfigs(); preference_manager.RemoveAllBindingConfigs(); } diff --git a/sharing/incoming_share_session.cc b/sharing/incoming_share_session.cc index 870c7787..a0e8e0d5 100644 --- a/sharing/incoming_share_session.cc +++ b/sharing/incoming_share_session.cc @@ -24,8 +24,6 @@ #include #include -#include "location/nearby/sharing/lib/sync/sync_config_prefs.pb.h" -#include "location/nearby/sharing/lib/sync/sync_manager.h" #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" #include "absl/time/time.h" @@ -53,16 +51,12 @@ namespace nearby::sharing { namespace { -using ::location::nearby::proto::sharing::OSType; using ::location::nearby::proto::sharing::ResponseToIntroduction; using ::nearby::sharing::service::proto::AppMetadata; using ::nearby::sharing::service::proto::ConnectionResponseFrame; -using ::nearby::sharing::service::proto::Frame; using ::nearby::sharing::service::proto::IntroductionFrame; -using ::nearby::sharing::service::proto::SyncConfig; using ::nearby::sharing::service::proto::V1Frame; using ::nearby::sharing::service::proto::WifiCredentials; -using ::nearby::sharing::sync::SyncConfigPrefs; } // namespace @@ -499,43 +493,4 @@ void IncomingShareSession::PushPayloadTransferUpdateForTest( payload_updates_queue()->Queue(std::move(update)); } -void IncomingShareSession::ProcessSyncFrame( - SyncManager& sync_manager, - const nearby::sharing::service::proto::SyncFrame& sync_frame) { - if (session_phase_ != SessionPhase::kUninitialized) { - LOG(WARNING) << "Ignore SyncFrame received in unexpected session phase: " - << static_cast(session_phase_); - return; - } - // TODO: b/485304482 - Check that the connected device is authenticated and is - // part of a sync pairing. - if (!certificate().has_value()) { - LOG(WARNING) << "Ignore SyncFrame received from unauthenticated device."; - return; - } - if (false && - !sync_manager.IsFileSyncBinding(certificate()->binding_id())) { - LOG(WARNING) << "Ignore SyncFrame received in unexpected binding id: " - << certificate()->binding_id(); - return; - } - session_phase_ = SessionPhase::kSync; - if (sync_frame.has_handshake()) { - VLOG(1) << __func__ << ": Received FileSync Handshake"; - WriteSyncConfigFrame( - sync_manager.GetSyncConfig(certificate()->binding_id()) - .value_or(SyncConfigPrefs()) - .sync_config()); - } -} - -void IncomingShareSession::WriteSyncConfigFrame(const SyncConfig& config) { - Frame frame; - frame.set_version(Frame::V1); - V1Frame* v1_frame = frame.mutable_v1(); - v1_frame->set_type(V1Frame::FILE_SYNC); - *v1_frame->mutable_file_sync()->mutable_config() = config; - WriteFrame(frame); -} - } // namespace nearby::sharing diff --git a/sharing/incoming_share_session.h b/sharing/incoming_share_session.h index 5a9d91ee..b7e86007 100644 --- a/sharing/incoming_share_session.h +++ b/sharing/incoming_share_session.h @@ -21,7 +21,6 @@ #include #include -#include "location/nearby/sharing/lib/sync/sync_manager.h" #include "absl/functional/any_invocable.h" #include "internal/base/file_path.h" #include "internal/platform/clock.h" @@ -104,9 +103,6 @@ class IncomingShareSession : public ShareSession { // Called when an incoming connection is established. void OnConnected(NearbyConnection* connection); - void ProcessSyncFrame(nearby::sharing::SyncManager& sync_manager, - const nearby::sharing::service::proto::SyncFrame& sync_frame); - protected: void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override; @@ -128,9 +124,6 @@ class IncomingShareSession : public ShareSession { // Returns true if all payloads were successfully finalized. bool FinalizePayloads(); - void WriteSyncConfigFrame( - const nearby::sharing::service::proto::SyncConfig& config); - std::function transfer_update_callback_; diff --git a/sharing/internal/api/BUILD b/sharing/internal/api/BUILD index f643fd2f..1a09ee39 100644 --- a/sharing/internal/api/BUILD +++ b/sharing/internal/api/BUILD @@ -44,7 +44,6 @@ cc_library( "//internal/platform:types", "//location/nearby/sharing/lib/account:account_manager", "//location/nearby/sharing/lib/sync:sync_binding_prefs_cc_proto", - "//location/nearby/sharing/lib/sync:sync_config_prefs_cc_proto", "//sharing/proto:share_cc_proto", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/strings:string_view", diff --git a/sharing/internal/api/preference_manager.h b/sharing/internal/api/preference_manager.h index 7c6f00ca..58fba5aa 100644 --- a/sharing/internal/api/preference_manager.h +++ b/sharing/internal/api/preference_manager.h @@ -23,7 +23,6 @@ #include #include "location/nearby/sharing/lib/sync/sync_binding_prefs.pb.h" -#include "location/nearby/sharing/lib/sync/sync_config_prefs.pb.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "absl/types/span.h" @@ -81,10 +80,6 @@ class PreferenceManager { virtual void RemoveDictionaryItem(absl::string_view key, absl::string_view dictionary_item) = 0; - virtual void SetSyncConfigValue( - absl::string_view binding_id, - const nearby::sharing::sync::SyncConfigPrefs& value) = 0; - virtual void SetSyncBindingValue( const nearby::sharing::sync::SyncBindingPrefs& value) = 0; @@ -127,17 +122,11 @@ class PreferenceManager { virtual std::optional GetDictionaryStringValue( absl::string_view key, absl::string_view dictionary_item) const = 0; - virtual std::optional - GetSyncConfigValue(absl::string_view binding_id) const = 0; - virtual std::optional GetSyncBindingValue() const = 0; // Removes preferences virtual void Remove(absl::string_view key) = 0; - // Removes all sync configs. - // Observers are not notified for each removed config. - virtual void RemoveAllSyncConfigs() = 0; // Removes all binding configs. // Observers are not notified for each removed config. virtual void RemoveAllBindingConfigs() = 0; diff --git a/sharing/internal/public/pref_names.h b/sharing/internal/public/pref_names.h index 83ced43c..6daef139 100644 --- a/sharing/internal/public/pref_names.h +++ b/sharing/internal/public/pref_names.h @@ -61,13 +61,6 @@ class PrefNames { // TODO: b/485304482 - define data format for binding configs. static constexpr absl::string_view kBindingConfigPrefix = "nearby_sharing.binding_config."; - - // Sync configs preferences are stored in pref keys: - // kSyncConfigPrefix + - // Example: "nearby_sharing.sync_config.01243347-2343-4324-3423-432432432432" - // Data stored in sync config prefs is a SyncConfig proto. - static constexpr absl::string_view kSyncConfigPrefix = - "nearby_sharing.sync_config."; }; } // namespace nearby::sharing diff --git a/sharing/internal/test/BUILD b/sharing/internal/test/BUILD index 0342ae4c..a6069b4c 100644 --- a/sharing/internal/test/BUILD +++ b/sharing/internal/test/BUILD @@ -41,7 +41,6 @@ cc_library( "//internal/platform:types", "//internal/test", "//location/nearby/sharing/lib/sync:sync_binding_prefs_cc_proto", - "//location/nearby/sharing/lib/sync:sync_config_prefs_cc_proto", "//sharing/internal/api:platform", "//sharing/internal/public:pref_names", "//sharing/internal/public:types", diff --git a/sharing/internal/test/fake_preference_manager.cc b/sharing/internal/test/fake_preference_manager.cc index cac1bb32..27066249 100644 --- a/sharing/internal/test/fake_preference_manager.cc +++ b/sharing/internal/test/fake_preference_manager.cc @@ -23,7 +23,6 @@ #include #include "location/nearby/sharing/lib/sync/sync_binding_prefs.pb.h" -#include "location/nearby/sharing/lib/sync/sync_config_prefs.pb.h" #include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" @@ -37,7 +36,6 @@ namespace nearby { using ::nearby::sharing::PrefNames; using ::nearby::sharing::api::PrivateCertificateData; using ::nearby::sharing::sync::SyncBindingPrefs; -using ::nearby::sharing::sync::SyncConfigPrefs; // Preference suffix for the sync binding information. constexpr absl::string_view kFileSyncBindingName = "FileSync"; @@ -245,12 +243,6 @@ void FakePreferenceManager::RemoveDictionaryItem( NotifyPreferenceChanged(key); } -void FakePreferenceManager::SetSyncConfigValue(absl::string_view binding_id, - const SyncConfigPrefs& value) { - SetValue(absl::StrCat(PrefNames::kSyncConfigPrefix, binding_id), - value.SerializeAsString()); -} - void FakePreferenceManager::SetSyncBindingValue( const SyncBindingPrefs& value) { SetValue(absl::StrCat(PrefNames::kBindingConfigPrefix, kFileSyncBindingName), @@ -341,21 +333,6 @@ std::optional FakePreferenceManager::GetDictionaryStringValue( return GetDictionaryValue(key, dictionary_item); } -std::optional FakePreferenceManager::GetSyncConfigValue( - absl::string_view binding_id) const { - std::string serialized_sync_config; - serialized_sync_config = - GetString(absl::StrCat(PrefNames::kSyncConfigPrefix, binding_id), ""); - if (serialized_sync_config.empty()) { - return std::nullopt; - } - SyncConfigPrefs sync_config; - if (!sync_config.ParseFromString(serialized_sync_config)) { - return std::nullopt; - } - return sync_config; -} - std::optional FakePreferenceManager::GetSyncBindingValue() const { std::string serialized_sync_binding; @@ -381,13 +358,6 @@ void FakePreferenceManager::Remove(absl::string_view key) { NotifyPreferenceChanged(key); } -void FakePreferenceManager::RemoveAllSyncConfigs() { - absl::MutexLock lock(mutex_); - absl::erase_if(values_, [](const auto& item) { - return item.first.starts_with(PrefNames::kSyncConfigPrefix); - }); -} - void FakePreferenceManager::RemoveAllBindingConfigs() { absl::MutexLock lock(mutex_); absl::erase_if(values_, [](const auto& item) { diff --git a/sharing/internal/test/fake_preference_manager.h b/sharing/internal/test/fake_preference_manager.h index 88f7eb1e..1fb023cf 100644 --- a/sharing/internal/test/fake_preference_manager.h +++ b/sharing/internal/test/fake_preference_manager.h @@ -24,7 +24,6 @@ #include #include "location/nearby/sharing/lib/sync/sync_binding_prefs.pb.h" -#include "location/nearby/sharing/lib/sync/sync_config_prefs.pb.h" #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" @@ -76,9 +75,6 @@ class FakePreferenceManager : public nearby::sharing::api::PreferenceManager { void RemoveDictionaryItem(absl::string_view key, absl::string_view dictionary_item) override; - void SetSyncConfigValue( - absl::string_view binding_id, - const nearby::sharing::sync::SyncConfigPrefs& value) override; void SetSyncBindingValue( const nearby::sharing::sync::SyncBindingPrefs& value) override; @@ -115,13 +111,10 @@ class FakePreferenceManager : public nearby::sharing::api::PreferenceManager { absl::string_view key, absl::string_view dictionary_item) const override; std::optional GetDictionaryStringValue( absl::string_view key, absl::string_view dictionary_item) const override; - std::optional - GetSyncConfigValue(absl::string_view binding_id) const override; std::optional GetSyncBindingValue() const override; void Remove(absl::string_view key) override; - void RemoveAllSyncConfigs() override; void RemoveAllBindingConfigs() override; void AddObserver( diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 1214f38b..8e53dbef 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -2498,12 +2498,6 @@ void NearbySharingServiceImpl::OnIncomingSessionFrameRead( OnReceivedIntroduction(*session, frame->introduction()); // OnReceivedIntroduction will schedule the next ReadFrame. return; - case service::proto::V1Frame::FILE_SYNC: - if (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_sharing_feature::kEnableFileSync)) { - session->ProcessSyncFrame(sync_manager_, frame->file_sync()); - } - break; default: LOG(ERROR) << __func__ << ": Discarding unknown frame of type: " << static_cast(frame->type()); From f088ef3b74178c2fa147faef99515e6e56feb697 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 30 Mar 2026 22:17:08 -0700 Subject: [PATCH 033/151] Remove unnecessary DevicInfoImpl class. PiperOrigin-RevId: 892102193 --- connections/implementation/client_proxy.cc | 7 +- internal/platform/BUILD | 3 - internal/platform/device_info.h | 74 ---------------- internal/platform/device_info_impl.cc | 88 ------------------- internal/platform/device_info_impl.h | 63 ------------- internal/platform/implementation/BUILD | 2 + .../platform/implementation/device_info.h | 24 +++++ internal/test/fake_device_info.h | 13 +-- internal/test/fake_device_info_test.cc | 17 ++-- sharing/BUILD | 7 +- sharing/internal/api/BUILD | 9 +- sharing/internal/api/mock_sharing_platform.h | 4 +- sharing/internal/api/sharing_platform.h | 4 +- sharing/local_device_data/BUILD | 1 - ...by_share_local_device_data_manager_impl.cc | 23 ++--- ...rby_share_local_device_data_manager_impl.h | 8 +- ...are_local_device_data_manager_impl_test.cc | 10 +-- sharing/nearby_connection_impl.cc | 4 +- sharing/nearby_connection_impl.h | 6 +- sharing/nearby_connections_manager_factory.cc | 4 +- sharing/nearby_connections_manager_factory.h | 4 +- sharing/nearby_connections_manager_impl.cc | 5 +- sharing/nearby_connections_manager_impl.h | 6 +- sharing/nearby_sharing_service_impl.cc | 10 +-- sharing/nearby_sharing_service_impl.h | 4 +- sharing/nearby_sharing_settings.cc | 6 +- sharing/nearby_sharing_settings.h | 7 +- sharing/nearby_sharing_util.cc | 17 ---- sharing/nearby_sharing_util.h | 10 --- 29 files changed, 107 insertions(+), 333 deletions(-) delete mode 100644 internal/platform/device_info.h delete mode 100644 internal/platform/device_info_impl.cc delete mode 100644 internal/platform/device_info_impl.h diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index 760f358c..a1a5ce88 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -61,7 +61,7 @@ #include "internal/platform/cancelable_alarm.h" #include "internal/platform/cancellation_flag.h" #ifndef NEARBY_CHROMIUM -#include "internal/platform/device_info_impl.h" +#include "internal/platform/implementation/device_info.h" #endif #include "internal/platform/error_code_params.h" #include "internal/platform/error_code_recorder.h" @@ -1340,10 +1340,11 @@ void ClientProxy::InitializePreferencesManager() { void ClientProxy::InitializePreferencesManager() { LOG(INFO) << "ClientProxy [InitializePreferencesManager]: client=" << GetClientId(); - auto device_info_ = std::make_unique(); + std::unique_ptr device_info_ = + nearby::api::ImplementationPlatform::CreateDeviceInfo(); FilePath preferences_path = - device_info_->GetAppDataPath().append(FilePath(kPreferencesFilePath)); + device_info_->GetLocalAppDataPath(FilePath(kPreferencesFilePath)); if (!Files::FileExists(preferences_path)) { Files::CreateDirectories(preferences_path); diff --git a/internal/platform/BUILD b/internal/platform/BUILD index fd82b22d..77fc1061 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -210,7 +210,6 @@ cc_library( srcs = [ "blocking_queue_stream.cc", "clock_impl.cc", - "device_info_impl.cc", "monitored_runnable.cc", "pending_job_registry.cc", "pipe.cc", @@ -231,8 +230,6 @@ cc_library( "condition_variable.h", "count_down_latch.h", "crypto.h", - "device_info.h", - "device_info_impl.h", "direct_executor.h", "file.h", "future.h", diff --git a/internal/platform/device_info.h b/internal/platform/device_info.h deleted file mode 100644 index 159d2d74..00000000 --- a/internal/platform/device_info.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2021 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 PLATFORM_PUBLIC_DEVICE_INFO_H_ -#define PLATFORM_PUBLIC_DEVICE_INFO_H_ - -#include -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/base/file_path.h" -#include "internal/platform/implementation/device_info.h" - -namespace nearby { - -class DeviceInfo { - public: - virtual ~DeviceInfo() = default; - - // All strings are UTF-8 encoded. - virtual std::string GetOsDeviceName() const = 0; - virtual api::DeviceInfo::DeviceType GetDeviceType() const = 0; - virtual api::DeviceInfo::OsType GetOsType() const = 0; - - virtual FilePath GetDownloadPath() const = 0; - virtual FilePath GetAppDataPath() const = 0; - virtual FilePath GetTemporaryPath() const = 0; - virtual FilePath GetLogPath() const = 0; - - virtual std::optional GetAvailableDiskSpaceInBytes( - const FilePath& path) const = 0; - - virtual bool IsScreenLocked() const = 0; - virtual void RegisterScreenLockedListener( - absl::string_view listener_name, - std::function callback) = 0; - virtual void UnregisterScreenLockedListener( - absl::string_view listener_name) = 0; - - virtual bool PreventSleep() = 0; - virtual bool AllowSleep() = 0; - - // Returns UTF-8 encoded localized device name depending on device type. - std::string GetDeviceTypeName() const { - // TODO(b/230132370): return localized device name. - switch (GetDeviceType()) { - case api::DeviceInfo::DeviceType::kPhone: - return "Phone"; - case api::DeviceInfo::DeviceType::kTablet: - return "Tablet"; - case api::DeviceInfo::DeviceType::kLaptop: - return "PC"; - default: - return "Unknown"; - } - } -}; - -} // namespace nearby - -#endif // PLATFORM_PUBLIC_DEVICE_INFO_H_ diff --git a/internal/platform/device_info_impl.cc b/internal/platform/device_info_impl.cc deleted file mode 100644 index 91c04021..00000000 --- a/internal/platform/device_info_impl.cc +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2021 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. - -#include "internal/platform/device_info_impl.h" - -#include -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/base/file_path.h" -#include "internal/base/files.h" -#include "internal/platform/implementation/device_info.h" - -namespace nearby { - -std::string DeviceInfoImpl::GetOsDeviceName() const { - std::optional device_name = device_info_impl_->GetOsDeviceName(); - if (device_name.has_value()) { - return *device_name; - } - - return "unknown"; -} - -api::DeviceInfo::DeviceType DeviceInfoImpl::GetDeviceType() const { - return device_info_impl_->GetDeviceType(); -} - -api::DeviceInfo::OsType DeviceInfoImpl::GetOsType() const { - return device_info_impl_->GetOsType(); -} - -FilePath DeviceInfoImpl::GetDownloadPath() const { - return device_info_impl_->GetDownloadPath(); -} - -FilePath DeviceInfoImpl::GetAppDataPath() const { - return device_info_impl_->GetLocalAppDataPath(FilePath()); -} - -FilePath DeviceInfoImpl::GetTemporaryPath() const { - return device_info_impl_->GetTemporaryPath(); -} - -FilePath DeviceInfoImpl::GetLogPath() const { - return device_info_impl_->GetLogPath(); -} - -std::optional DeviceInfoImpl::GetAvailableDiskSpaceInBytes( - const FilePath& path) const { - return Files::GetAvailableDiskSpaceInBytes(path); -} - -bool DeviceInfoImpl::IsScreenLocked() const { - return device_info_impl_->IsScreenLocked(); -} - -void DeviceInfoImpl::RegisterScreenLockedListener( - absl::string_view listener_name, - std::function callback) { - device_info_impl_->RegisterScreenLockedListener(listener_name, callback); -} - -void DeviceInfoImpl::UnregisterScreenLockedListener( - absl::string_view listener_name) { - device_info_impl_->UnregisterScreenLockedListener(listener_name); -} - -bool DeviceInfoImpl::PreventSleep() { - return device_info_impl_->PreventSleep(); -} - -bool DeviceInfoImpl::AllowSleep() { return device_info_impl_->AllowSleep(); } - -} // namespace nearby diff --git a/internal/platform/device_info_impl.h b/internal/platform/device_info_impl.h deleted file mode 100644 index fc5ba6fe..00000000 --- a/internal/platform/device_info_impl.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2021 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 PLATFORM_PUBLIC_DEVICE_INFO_IMPL_H_ -#define PLATFORM_PUBLIC_DEVICE_INFO_IMPL_H_ - -#include -#include -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/base/file_path.h" -#include "internal/platform/device_info.h" -#include "internal/platform/implementation/device_info.h" -#include "internal/platform/implementation/platform.h" - -namespace nearby { - -class DeviceInfoImpl : public DeviceInfo { - public: - DeviceInfoImpl() - : device_info_impl_(api::ImplementationPlatform::CreateDeviceInfo()) {} - - std::string GetOsDeviceName() const override; - api::DeviceInfo::DeviceType GetDeviceType() const override; - api::DeviceInfo::OsType GetOsType() const override; - - FilePath GetDownloadPath() const override; - FilePath GetAppDataPath() const override; - FilePath GetTemporaryPath() const override; - FilePath GetLogPath() const override; - - std::optional GetAvailableDiskSpaceInBytes( - const FilePath& path) const override; - - bool IsScreenLocked() const override; - void RegisterScreenLockedListener( - absl::string_view listener_name, - std::function callback) override; - void UnregisterScreenLockedListener(absl::string_view listener_name) override; - - bool PreventSleep() override; - bool AllowSleep() override; - - private: - std::unique_ptr device_info_impl_; -}; -} // namespace nearby - -#endif // PLATFORM_PUBLIC_DEVICE_INFO_IMPL_H_ diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index d6092802..225e78c7 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -54,6 +54,7 @@ cc_library( ], deps = [ "//internal/base:file_path", + "//internal/base:files", "//internal/crypto_cros", "//internal/platform:base", "//internal/platform:mac_address", @@ -151,6 +152,7 @@ cc_library( "//location/nearby/analytics/cpp:__subpackages__", "//location/nearby/apps/better_together/plugins/preferences_native:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", + "//sharing/internal/impl/common:__subpackages__", ], deps = [ ":comm", diff --git a/internal/platform/implementation/device_info.h b/internal/platform/implementation/device_info.h index 4426ef7d..89d937d6 100644 --- a/internal/platform/implementation/device_info.h +++ b/internal/platform/implementation/device_info.h @@ -15,12 +15,14 @@ #ifndef PLATFORM_API_DEVICE_INFO_H_ #define PLATFORM_API_DEVICE_INFO_H_ +#include #include #include #include #include "absl/strings/string_view.h" #include "internal/base/file_path.h" +#include "internal/base/files.h" namespace nearby { namespace api { @@ -29,6 +31,23 @@ class DeviceInfo { public: enum class ScreenStatus { kUndetermined = 0, kLocked, kUnlocked }; enum class DeviceType { kUnknown = 0, kPhone, kTablet, kLaptop }; + template + void AbslStringify(Sink& sink, DeviceType device_type) { + switch (device_type) { + case DeviceType::kUnknown: + sink.Append("Unknown"); + return; + case DeviceType::kPhone: + sink.Append("Phone"); + return; + case DeviceType::kTablet: + sink.Append("Tablet"); + return; + case DeviceType::kLaptop: + sink.Append("PC"); + return; + } + } enum class OsType { kUnknown = 0, kAndroid, @@ -51,6 +70,11 @@ class DeviceInfo { virtual FilePath GetTemporaryPath() const = 0; virtual FilePath GetLogPath() const = 0; + virtual std::optional GetAvailableDiskSpaceInBytes( + const FilePath& path) const { + return Files::GetAvailableDiskSpaceInBytes(path); + }; + // Monitor screen status virtual bool IsScreenLocked() const = 0; virtual void RegisterScreenLockedListener( diff --git a/internal/test/fake_device_info.h b/internal/test/fake_device_info.h index 22d491da..f79476f1 100644 --- a/internal/test/fake_device_info.h +++ b/internal/test/fake_device_info.h @@ -27,14 +27,15 @@ #include "absl/strings/string_view.h" #include "internal/base/file_path.h" #include "internal/base/files.h" -#include "internal/platform/device_info.h" #include "internal/platform/implementation/device_info.h" namespace nearby { -class FakeDeviceInfo : public DeviceInfo { +class FakeDeviceInfo : public api::DeviceInfo { public: - std::string GetOsDeviceName() const override { return device_name_; } + std::optional GetOsDeviceName() const override { + return device_name_; + } api::DeviceInfo::DeviceType GetDeviceType() const override { return device_type_; @@ -46,8 +47,10 @@ class FakeDeviceInfo : public DeviceInfo { return download_path_; } - FilePath GetAppDataPath() const override { - return app_data_path_; + FilePath GetLocalAppDataPath(FilePath sub_path) const override { + FilePath path = app_data_path_; + path.append(sub_path); + return path; } FilePath GetTemporaryPath() const override { return temp_path_; } diff --git a/internal/test/fake_device_info_test.cc b/internal/test/fake_device_info_test.cc index 4e7c936e..5c2e8fb2 100644 --- a/internal/test/fake_device_info_test.cc +++ b/internal/test/fake_device_info_test.cc @@ -51,13 +51,16 @@ TEST(FakeDeviceInfo, GetDownloadPath) { Files::GetTemporaryDirectory().append(FilePath("test"))); } -TEST(FakeDeviceInfo, GetAppDataPath) { +TEST(FakeDeviceInfo, GetLocalAppDataPath) { FakeDeviceInfo device_info; - EXPECT_EQ(device_info.GetAppDataPath(), Files::GetTemporaryDirectory()); + EXPECT_EQ(device_info.GetLocalAppDataPath(FilePath("abc")), + Files::GetTemporaryDirectory().append(FilePath("abc"))); device_info.SetAppDataPath( Files::GetTemporaryDirectory().append(FilePath("test"))); - EXPECT_EQ(device_info.GetAppDataPath(), - Files::GetTemporaryDirectory().append(FilePath("test"))); + EXPECT_EQ(device_info.GetLocalAppDataPath(FilePath("def")), + Files::GetTemporaryDirectory() + .append(FilePath("test")) + .append(FilePath("def"))); } TEST(FakeDeviceInfo, GetTemporaryPath) { @@ -76,7 +79,8 @@ TEST(FakeDeviceInfo, GetAvailableDiskSpaceInBytes) { device_info.SetTemporaryPath(FilePath("temp")); device_info.SetAvailableDiskSpaceInBytes(device_info.GetDownloadPath(), 10); - device_info.SetAvailableDiskSpaceInBytes(device_info.GetAppDataPath(), 100); + device_info.SetAvailableDiskSpaceInBytes( + device_info.GetLocalAppDataPath(FilePath()), 100); device_info.SetAvailableDiskSpaceInBytes(device_info.GetTemporaryPath(), 1000); @@ -84,7 +88,8 @@ TEST(FakeDeviceInfo, GetAvailableDiskSpaceInBytes) { device_info.GetAvailableDiskSpaceInBytes(device_info.GetDownloadPath()), 10); EXPECT_EQ( - device_info.GetAvailableDiskSpaceInBytes(device_info.GetAppDataPath()), + device_info.GetAvailableDiskSpaceInBytes( + device_info.GetLocalAppDataPath(FilePath())), 100); EXPECT_EQ( device_info.GetAvailableDiskSpaceInBytes(device_info.GetTemporaryPath()), diff --git a/sharing/BUILD b/sharing/BUILD index 4de4b542..b5974de2 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -258,12 +258,10 @@ cc_library( srcs = ["nearby_connection_impl.cc"], hdrs = ["nearby_connection_impl.h"], deps = [ - ":connection_types", ":types", - "//internal/platform:types", + "//internal/platform/implementation:types", "//sharing/internal/public:logging", "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/strings", "@com_google_absl//absl/synchronization", ], ) @@ -303,8 +301,6 @@ cc_library( hdrs = ["nearby_sharing_util.h"], deps = [ ":types", - "//internal/base:file_path", - "//internal/platform:types", "//proto:sharing_enums_cc_proto", "//sharing/certificates", "//sharing/common:enum", @@ -382,6 +378,7 @@ cc_library( "//internal/analytics:event_logger", "//internal/base", "//internal/base:file_path", + "//internal/base:files", "//internal/flags:nearby_flags", "//internal/network:url", "//internal/platform:base", diff --git a/sharing/internal/api/BUILD b/sharing/internal/api/BUILD index 1a09ee39..4087190d 100644 --- a/sharing/internal/api/BUILD +++ b/sharing/internal/api/BUILD @@ -42,6 +42,7 @@ cc_library( "//internal/base:file_path", "//internal/platform:mac_address", "//internal/platform:types", + "//internal/platform/implementation:types", "//location/nearby/sharing/lib/account:account_manager", "//location/nearby/sharing/lib/sync:sync_binding_prefs_cc_proto", "//sharing/proto:share_cc_proto", @@ -71,16 +72,10 @@ cc_library( "//internal/base:file_path", "//internal/platform:mac_address", "//internal/platform:types", + "//internal/platform/implementation:types", "//location/nearby/sharing/lib/account:account_manager", - "//sharing/analytics", - "//sharing/internal/public:logging", - "//sharing/proto:share_cc_proto", - "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", - "@com_google_absl//absl/synchronization", "@com_google_absl//absl/types:span", "@com_google_googletest//:gtest_for_library_testonly", ], diff --git a/sharing/internal/api/mock_sharing_platform.h b/sharing/internal/api/mock_sharing_platform.h index d9e5df2a..34dbe0cf 100644 --- a/sharing/internal/api/mock_sharing_platform.h +++ b/sharing/internal/api/mock_sharing_platform.h @@ -23,7 +23,7 @@ #include "gmock/gmock.h" #include "absl/strings/string_view.h" #include "internal/base/file_path.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "internal/platform/task_runner.h" #include "sharing/internal/api/app_info.h" #include "sharing/internal/api/bluetooth_adapter.h" @@ -72,7 +72,7 @@ class MockSharingPlatform : public SharingPlatform { MOCK_METHOD(AccountManager&, GetAccountManager, (), (override)); MOCK_METHOD(TaskRunner&, GetDefaultTaskRunner, (), (override)); - MOCK_METHOD(nearby::DeviceInfo&, GetDeviceInfo, (), (override)); + MOCK_METHOD(nearby::api::DeviceInfo&, GetDeviceInfo, (), (override)); MOCK_METHOD(std::unique_ptr, CreatePublicCertificateDatabase, (const FilePath& database_path), (override)); diff --git a/sharing/internal/api/sharing_platform.h b/sharing/internal/api/sharing_platform.h index a65ac38f..c795002e 100644 --- a/sharing/internal/api/sharing_platform.h +++ b/sharing/internal/api/sharing_platform.h @@ -22,7 +22,7 @@ #include "location/nearby/sharing/lib/account/account_manager.h" #include "absl/strings/string_view.h" #include "internal/base/file_path.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "internal/platform/task_runner.h" #include "sharing/internal/api/app_info.h" #include "sharing/internal/api/bluetooth_adapter.h" @@ -65,7 +65,7 @@ class SharingPlatform { virtual PreferenceManager& GetPreferenceManager() = 0; virtual AccountManager& GetAccountManager() = 0; virtual TaskRunner& GetDefaultTaskRunner() = 0; - virtual nearby::DeviceInfo& GetDeviceInfo() = 0; + virtual nearby::api::DeviceInfo& GetDeviceInfo() = 0; virtual std::unique_ptr CreatePublicCertificateDatabase(const FilePath& database_path) = 0; diff --git a/sharing/local_device_data/BUILD b/sharing/local_device_data/BUILD index 3dbd73cb..22930d93 100644 --- a/sharing/local_device_data/BUILD +++ b/sharing/local_device_data/BUILD @@ -30,7 +30,6 @@ cc_library( visibility = ["//visibility:public"], deps = [ "//internal/base", - "//internal/platform:types", "//internal/platform/implementation:types", "//location/nearby/sharing/lib/account:account_manager", "//sharing/common:enum", diff --git a/sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc b/sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc index ad53f866..e3ab98b2 100644 --- a/sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc +++ b/sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc @@ -23,9 +23,8 @@ #include "location/nearby/sharing/lib/account/account_manager.h" #include "absl/memory/memory.h" +#include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" -#include "absl/strings/substitute.h" -#include "internal/platform/device_info.h" #include "internal/platform/implementation/device_info.h" #include "sharing/common/nearby_share_enums.h" #include "sharing/internal/api/preference_manager.h" @@ -42,8 +41,6 @@ namespace { using ::nearby::api::DeviceInfo; using ::nearby::sharing::api::PreferenceManager; -constexpr absl::string_view kDefaultDeviceName = "$0\'s $1"; - // Returns a truncated version of |name| that is |max_length| characters long. // For example, name="Reallylongname" with max_length=9 will return "Really...". // name="Reallylongname" with max_length=20 will return "Reallylongname". @@ -71,7 +68,7 @@ NearbyShareLocalDeviceDataManagerImpl::Factory* std::unique_ptr NearbyShareLocalDeviceDataManagerImpl::Factory::Create( PreferenceManager& preference_manager, - AccountManager& account_manager, nearby::DeviceInfo& device_info) { + AccountManager& account_manager, nearby::api::DeviceInfo& device_info) { if (test_factory_) { return test_factory_->CreateInstance(); } @@ -90,7 +87,7 @@ NearbyShareLocalDeviceDataManagerImpl::Factory::~Factory() = default; NearbyShareLocalDeviceDataManagerImpl::NearbyShareLocalDeviceDataManagerImpl( PreferenceManager& preference_manager, AccountManager& account_manager, - nearby::DeviceInfo& device_info) + nearby::api::DeviceInfo& device_info) : preference_manager_(preference_manager), account_manager_(account_manager), device_info_(device_info) {} @@ -147,20 +144,24 @@ std::string NearbyShareLocalDeviceDataManagerImpl::GetDefaultDeviceName() if (os_type == DeviceInfo::OsType::kMacOS || os_type == DeviceInfo::OsType::kIos || !account.has_value() || account->given_name.empty()) { - std::string device_name = device_info_.GetOsDeviceName(); + std::string device_name = + device_info_.GetOsDeviceName().value_or("unknown"); return GetTruncatedName(device_name, kNearbyShareDeviceNameMaxLength); } std::string given_name = account->given_name; - std::string device_type = device_info_.GetDeviceTypeName(); - uint64_t untruncated_length = - absl::Substitute(kDefaultDeviceName, given_name, device_type).length(); + DeviceInfo::DeviceType device_type = device_info_.GetDeviceType(); + std::string device_name = absl::StrCat(given_name, "'s ", device_type); + uint64_t untruncated_length = device_name.length(); + if (untruncated_length <= kNearbyShareDeviceNameMaxLength) { + return device_name; + } uint64_t overflow_length = untruncated_length - kNearbyShareDeviceNameMaxLength; std::string truncated_name = GetTruncatedName(given_name, given_name.length() - overflow_length); - return absl::Substitute(kDefaultDeviceName, truncated_name, device_type); + return absl::StrCat(truncated_name, "'s ", device_type); } } // namespace nearby::sharing diff --git a/sharing/local_device_data/nearby_share_local_device_data_manager_impl.h b/sharing/local_device_data/nearby_share_local_device_data_manager_impl.h index 5231babb..7df292b0 100644 --- a/sharing/local_device_data/nearby_share_local_device_data_manager_impl.h +++ b/sharing/local_device_data/nearby_share_local_device_data_manager_impl.h @@ -20,7 +20,7 @@ #include "location/nearby/sharing/lib/account/account_manager.h" #include "absl/strings/string_view.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "sharing/common/nearby_share_enums.h" #include "sharing/internal/api/preference_manager.h" #include "sharing/local_device_data/nearby_share_local_device_data_manager.h" @@ -40,7 +40,7 @@ class NearbyShareLocalDeviceDataManagerImpl public: static std::unique_ptr Create( nearby::sharing::api::PreferenceManager& preference_manager, - AccountManager& account_manager, nearby::DeviceInfo& device_info); + AccountManager& account_manager, nearby::api::DeviceInfo& device_info); static void SetFactoryForTesting(Factory* test_factory); protected: @@ -61,7 +61,7 @@ class NearbyShareLocalDeviceDataManagerImpl private: NearbyShareLocalDeviceDataManagerImpl( nearby::sharing::api::PreferenceManager& preference_manager, - AccountManager& account_manager, nearby::DeviceInfo& device_info); + AccountManager& account_manager, nearby::api::DeviceInfo& device_info); DeviceNameValidationResult ValidateDeviceName(absl::string_view name); @@ -73,7 +73,7 @@ class NearbyShareLocalDeviceDataManagerImpl nearby::sharing::api::PreferenceManager& preference_manager_; AccountManager& account_manager_; - nearby::DeviceInfo& device_info_; + nearby::api::DeviceInfo& device_info_; }; } // namespace nearby::sharing diff --git a/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc b/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc index 047f7182..3aa66539 100644 --- a/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc +++ b/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc @@ -109,11 +109,11 @@ class NearbyShareLocalDeviceDataManagerImplTest } std::string GetDeviceName() const { - return fake_device_info_.GetOsDeviceName(); + return fake_device_info_.GetOsDeviceName().value_or("unknown"); } - std::string GetDeviceTypeName() const { - return fake_device_info_.GetDeviceTypeName(); + nearby::FakeDeviceInfo::DeviceType GetDeviceType() const { + return fake_device_info_.GetDeviceType(); } protected: @@ -138,7 +138,7 @@ TEST_F(NearbyShareLocalDeviceDataManagerImplTest, DefaultDeviceName) { fake_account_manager().SetAccount(account); EXPECT_EQ(absl::Substitute(kDefaultDeviceName, kFakeGivenName, - GetDeviceTypeName()), + GetDeviceType()), manager()->GetDeviceName()); // Make sure that when we use a given name that is very long we truncate @@ -152,7 +152,7 @@ TEST_F(NearbyShareLocalDeviceDataManagerImplTest, SetDeviceName) { CreateManager(); std::string expected_default_device_name = - absl::Substitute(kDefaultDeviceName, kFakeGivenName, GetDeviceTypeName()); + absl::Substitute(kDefaultDeviceName, kFakeGivenName, GetDeviceType()); EXPECT_EQ(manager()->GetDeviceName(), expected_default_device_name); EXPECT_TRUE(notifications().empty()); diff --git a/sharing/nearby_connection_impl.cc b/sharing/nearby_connection_impl.cc index 42ab97eb..eecca33d 100644 --- a/sharing/nearby_connection_impl.cc +++ b/sharing/nearby_connection_impl.cc @@ -22,12 +22,12 @@ #include #include "absl/synchronization/mutex.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "sharing/internal/public/logging.h" namespace nearby::sharing { -NearbyConnectionImpl::NearbyConnectionImpl(nearby::DeviceInfo& device_info) +NearbyConnectionImpl::NearbyConnectionImpl(nearby::api::DeviceInfo& device_info) : device_info_(device_info) { if (!device_info_.PreventSleep()) { LOG(WARNING) << __func__ << ":Failed to prevent device sleep."; diff --git a/sharing/nearby_connection_impl.h b/sharing/nearby_connection_impl.h index 35725791..090bf9eb 100644 --- a/sharing/nearby_connection_impl.h +++ b/sharing/nearby_connection_impl.h @@ -23,7 +23,7 @@ #include "absl/base/thread_annotations.h" #include "absl/synchronization/mutex.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "sharing/nearby_connection.h" namespace nearby::sharing { @@ -32,7 +32,7 @@ class NearbyConnectionsManager; class NearbyConnectionImpl : public NearbyConnection { public: - explicit NearbyConnectionImpl(nearby::DeviceInfo& device_info); + explicit NearbyConnectionImpl(nearby::api::DeviceInfo& device_info); ~NearbyConnectionImpl() override; // NearbyConnection: @@ -46,7 +46,7 @@ class NearbyConnectionImpl : public NearbyConnection { void WriteMessage(std::vector bytes) ABSL_LOCKS_EXCLUDED(mutex_); private: - nearby::DeviceInfo& device_info_; + nearby::api::DeviceInfo& device_info_; absl::Mutex mutex_; std::function> bytes)> read_callback_ diff --git a/sharing/nearby_connections_manager_factory.cc b/sharing/nearby_connections_manager_factory.cc index 31816390..9f0d40e3 100644 --- a/sharing/nearby_connections_manager_factory.cc +++ b/sharing/nearby_connections_manager_factory.cc @@ -17,7 +17,7 @@ #include #include "internal/analytics/event_logger.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "internal/platform/task_runner.h" #include "sharing/internal/public/context.h" #include "sharing/nearby_connections_manager.h" @@ -29,7 +29,7 @@ namespace nearby::sharing { std::unique_ptr NearbyConnectionsManagerFactory::CreateConnectionsManager( nearby::TaskRunner* connections_callback_task_runner, Context* context, - nearby::DeviceInfo& device_info, + nearby::api::DeviceInfo& device_info, nearby::analytics::EventLogger* event_logger) { return std::make_unique( connections_callback_task_runner, context, diff --git a/sharing/nearby_connections_manager_factory.h b/sharing/nearby_connections_manager_factory.h index f22da1ef..bb45b9c7 100644 --- a/sharing/nearby_connections_manager_factory.h +++ b/sharing/nearby_connections_manager_factory.h @@ -18,7 +18,7 @@ #include #include "internal/analytics/event_logger.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "internal/platform/task_runner.h" #include "sharing/internal/public/context.h" #include "sharing/nearby_connections_manager.h" @@ -33,7 +33,7 @@ class NearbyConnectionsManagerFactory { // that NearbySharingService is running on. static std::unique_ptr CreateConnectionsManager( nearby::TaskRunner* connections_callback_task_runner, Context* context, - nearby::DeviceInfo& device_info, + nearby::api::DeviceInfo& device_info, nearby::analytics::EventLogger* event_logger = nullptr); private: diff --git a/sharing/nearby_connections_manager_impl.cc b/sharing/nearby_connections_manager_impl.cc index 20b6e1ef..f7154f69 100644 --- a/sharing/nearby_connections_manager_impl.cc +++ b/sharing/nearby_connections_manager_impl.cc @@ -32,7 +32,7 @@ #include "absl/types/span.h" #include "internal/base/file_path.h" #include "internal/flags/nearby_flags.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "internal/platform/mutex_lock.h" #include "internal/platform/task_runner.h" #include "sharing/advertisement.h" @@ -150,7 +150,8 @@ std::string PayloadStatusToString(PayloadStatus status) { NearbyConnectionsManagerImpl::NearbyConnectionsManagerImpl( TaskRunner* connections_callback_task_runner, Context* context, - ConnectivityManager& connectivity_manager, nearby::DeviceInfo& device_info, + ConnectivityManager& connectivity_manager, + nearby::api::DeviceInfo& device_info, std::unique_ptr nearby_connections_service) : connections_callback_task_runner_(connections_callback_task_runner), context_(context), diff --git a/sharing/nearby_connections_manager_impl.h b/sharing/nearby_connections_manager_impl.h index 0de7d791..bf9ce1e8 100644 --- a/sharing/nearby_connections_manager_impl.h +++ b/sharing/nearby_connections_manager_impl.h @@ -27,7 +27,7 @@ #include "absl/container/flat_hash_set.h" #include "absl/strings/string_view.h" #include "internal/base/file_path.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "internal/platform/mutex.h" #include "internal/platform/task_runner.h" #include "internal/platform/timer.h" @@ -49,7 +49,7 @@ class NearbyConnectionsManagerImpl : public NearbyConnectionsManager { explicit NearbyConnectionsManagerImpl( nearby::TaskRunner* connections_callback_task_runner, Context* context, nearby::ConnectivityManager& connectivity_manager, - nearby::DeviceInfo& device_info, + nearby::api::DeviceInfo& device_info, std::unique_ptr nearby_connections_service); ~NearbyConnectionsManagerImpl() override; NearbyConnectionsManagerImpl(const NearbyConnectionsManagerImpl&) = delete; @@ -146,7 +146,7 @@ class NearbyConnectionsManagerImpl : public NearbyConnectionsManager { nearby::TaskRunner* const connections_callback_task_runner_; Context* const context_; nearby::ConnectivityManager& connectivity_manager_; - nearby::DeviceInfo& device_info_; + nearby::api::DeviceInfo& device_info_; // Nearby Connections Manager is called from different threads and may have // multiple calls to the class from one thread. To avoid deadlock and access diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 8e53dbef..4f0c3086 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -49,7 +49,6 @@ #include "internal/flags/nearby_flags.h" #include "internal/network/url.h" #include "internal/platform/clock.h" -#include "internal/platform/device_info.h" #include "internal/platform/implementation/device_info.h" #include "internal/platform/task_runner.h" #include "proto/sharing_enums.pb.h" @@ -281,7 +280,7 @@ NearbySharingServiceImpl::NearbySharingServiceImpl( is_shutting_down_ = std::make_unique(false); FilePath profile_path = - device_info_.GetAppDataPath().append(FilePath(kProfileRelativePath)); + device_info_.GetLocalAppDataPath(FilePath(kProfileRelativePath)); certificate_manager_ = NearbyShareCertificateManagerImpl::Factory::Create( context_, sharing_platform, local_device_data_manager_.get(), @@ -2692,15 +2691,16 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( session.session_id(), session.share_target(), /*referrer_package=*/std::nullopt, session.os_type()); - if (IsOutOfStorage(device_info_, save_path, - session.attachment_container().GetStorageSize())) { + std::optional available_storage = + device_info_.GetAvailableDiskSpaceInBytes(save_path); + if (available_storage.has_value() && + *available_storage <= session.attachment_container().GetStorageSize()) { Fail(session, TransferMetadata::Status::kNotEnoughSpace); LOG(WARNING) << __func__ << ": Not enough space on the receiver. We have informed " << session.share_target().id; return; } - OnStorageCheckCompleted(session); } diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index 5a0a2fca..e0c04146 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -39,7 +39,7 @@ #include "absl/time/time.h" #include "absl/types/span.h" #include "internal/platform/clock.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "internal/platform/task_runner.h" #include "proto/sharing_enums.pb.h" #include "sharing/advertisement.h" @@ -425,7 +425,7 @@ class NearbySharingServiceImpl // Used to run nearby sharing service APIs. std::unique_ptr service_thread_; Context* const context_; - nearby::DeviceInfo& device_info_; + nearby::api::DeviceInfo& device_info_; nearby::sharing::api::PreferenceManager& preference_manager_; AccountManager& account_manager_; // Used to create analytics events. diff --git a/sharing/nearby_sharing_settings.cc b/sharing/nearby_sharing_settings.cc index 9a189aed..8d894727 100644 --- a/sharing/nearby_sharing_settings.cc +++ b/sharing/nearby_sharing_settings.cc @@ -26,7 +26,7 @@ #include "absl/synchronization/mutex.h" #include "absl/time/time.h" #include "internal/platform/clock.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "proto/sharing_enums.pb.h" #include "sharing/analytics/analytics_recorder.h" #include "sharing/common/nearby_share_enums.h" @@ -69,8 +69,8 @@ ShowNotificationStatus GetNotificationStatus( } // namespace NearbyShareSettings::NearbyShareSettings( - Context* context, nearby::Clock* clock, nearby::DeviceInfo& device_info, - PreferenceManager& preference_manager, + Context* context, nearby::Clock* clock, + nearby::api::DeviceInfo& device_info, PreferenceManager& preference_manager, NearbyShareLocalDeviceDataManager* local_device_data_manager, analytics::AnalyticsRecorder* analytics_recorder) : context_(context), diff --git a/sharing/nearby_sharing_settings.h b/sharing/nearby_sharing_settings.h index 09fa7016..665d8f97 100644 --- a/sharing/nearby_sharing_settings.h +++ b/sharing/nearby_sharing_settings.h @@ -28,7 +28,7 @@ #include "absl/time/time.h" #include "internal/base/observer_list.h" #include "internal/platform/clock.h" -#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "proto/sharing_enums.pb.h" #include "sharing/analytics/analytics_recorder.h" #include "sharing/common/nearby_share_enums.h" @@ -138,7 +138,8 @@ class NearbyShareSettings }; NearbyShareSettings( - Context* context, nearby::Clock* clock, nearby::DeviceInfo& device_info, + Context* context, nearby::Clock* clock, + nearby::api::DeviceInfo& device_info, nearby::sharing::api::PreferenceManager& preference_manager, NearbyShareLocalDeviceDataManager* local_device_data_manager, analytics::AnalyticsRecorder* analytics_recorder = nullptr); @@ -220,7 +221,7 @@ class NearbyShareSettings mutable absl::Mutex mutex_; Context* context_; nearby::Clock* const clock_; - nearby::DeviceInfo& device_info_; + nearby::api::DeviceInfo& device_info_; nearby::sharing::api::PreferenceManager& preference_manager_; NearbyShareLocalDeviceDataManager* const local_device_data_manager_; // Used to create analytics events. diff --git a/sharing/nearby_sharing_util.cc b/sharing/nearby_sharing_util.cc index 1fed0e12..06c38de2 100644 --- a/sharing/nearby_sharing_util.cc +++ b/sharing/nearby_sharing_util.cc @@ -14,10 +14,7 @@ #include "sharing/nearby_sharing_util.h" -#include #include -#include -#include #include #include #include @@ -26,8 +23,6 @@ #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" -#include "internal/base/file_path.h" -#include "internal/platform/device_info.h" #include "proto/sharing_enums.pb.h" #include "sharing/advertisement.h" #include "sharing/certificates/nearby_share_decrypted_public_certificate.h" @@ -115,16 +110,4 @@ std::string GetDeviceId( return std::string(endpoint_id); } -bool IsOutOfStorage(DeviceInfo& device_info, FilePath file_path, - int64_t storage_required) { - std::optional available_storage = - device_info.GetAvailableDiskSpaceInBytes(file_path); - - if (!available_storage.has_value()) { - return false; - } - - return *available_storage <= storage_required; -} - } // namespace nearby::sharing diff --git a/sharing/nearby_sharing_util.h b/sharing/nearby_sharing_util.h index bcc4c90d..d2b2df59 100644 --- a/sharing/nearby_sharing_util.h +++ b/sharing/nearby_sharing_util.h @@ -21,23 +21,13 @@ #include #include "absl/strings/string_view.h" -#include "internal/platform/device_info.h" #include "proto/sharing_enums.pb.h" -#include "internal/base/file_path.h" #include "sharing/advertisement.h" #include "sharing/certificates/nearby_share_decrypted_public_certificate.h" #include "sharing/common/nearby_share_enums.h" namespace nearby::sharing { -// Checks whether having enough disk space for required storage. -// -// device_info - Nearby Share DeviceInfo -// file_path - The path is to store sharing contents. -// storage_required - required storage space. -bool IsOutOfStorage(nearby::DeviceInfo& device_info, FilePath file_path, - int64_t storage_required); - // Decodes certificate to find MAC address encoded in it. std::optional> GetBluetoothMacAddressFromCertificate( const NearbyShareDecryptedPublicCertificate& certificate); From c7a8361639a4b236f7997110bb479d5e24b6e9ee Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Tue, 31 Mar 2026 00:00:08 -0700 Subject: [PATCH 034/151] Continue scanning even when peripherals are connected. PiperOrigin-RevId: 892142072 --- .../apple/Mediums/BLE/GNCBLEMedium.m | 35 +++++-------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m index e2d3defc..0fe0caca 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.m @@ -89,9 +89,6 @@ static NSError *AlreadyScanningError() { // The block to call when the BLE connection times out. dispatch_block_t _connectionTimeoutBlock; - - // The set of connected peripherals. - NSMutableSet *_connectedPeripherals; } - (instancetype)init { @@ -127,7 +124,6 @@ static NSError *AlreadyScanningError() { _scanningServiceUUIDs = [NSMutableArray array]; _l2capStreamCompletionHandlers = [NSMutableDictionary dictionary]; _l2capPSM = 0; - _connectedPeripherals = [NSMutableSet set]; } return self; } @@ -387,26 +383,17 @@ static NSError *AlreadyScanningError() { // then back on. This will be called anytime the central manager's state changes, so // @c scanForPeripheralsWithServices:options: will be called anytime state transitions back to // powered on. - if (_centralManager.state != CBManagerStatePoweredOn) { - return; - } - - // If there are any connected peripherals, stop scanning to avoid high interrupt load on the - // Bluetooth controller, which can cause system-level crashes (XPC connection invalid). - if (_connectedPeripherals.count > 0 || _scanningServiceUUIDs.count == 0) { + if (_centralManager.state == CBManagerStatePoweredOn && _scanningServiceUUIDs.count > 0) { + // Stop scanning just in case something outside of this class is already scanning. [_centralManager stopScan]; - return; + [_centralManager + scanForPeripheralsWithServices:_scanningServiceUUIDs + // Nearby relies on the existence of an advertisement for endpoint + // discovery/lost events, so we must set this key to keep the stream + // of duplicate delegate events flowing. This has adverse effect on + // battery life, but currently necessary. + options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES}]; } - - // Stop scanning just in case something outside of this class is already scanning. - [_centralManager stopScan]; - [_centralManager - scanForPeripheralsWithServices:_scanningServiceUUIDs - // Nearby relies on the existence of an advertisement for endpoint - // discovery/lost events, so we must set this key to keep the stream - // of duplicate delegate events flowing. This has adverse effect on - // battery life, but currently necessary. - options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES}]; } - (NSDictionary *)decodeAdvertisementData: @@ -535,8 +522,6 @@ static NSError *AlreadyScanningError() { didConnectPeripheral:(id)peripheral { dispatch_assert_queue(_queue); [self cancelConnectionTimeout]; - [_connectedPeripherals addObject:peripheral.identifier]; - [self updateScanningState]; if (_l2capPSM > 0) { [self internalOpenL2CAPChannel:peripheral]; @@ -583,8 +568,6 @@ static NSError *AlreadyScanningError() { didDisconnectPeripheral:(id)peripheral error:(nullable NSError *)error { dispatch_assert_queue(_queue); - [_connectedPeripherals removeObject:peripheral.identifier]; - [self updateScanningState]; GNCGATTDisconnectionHandler handler = _gattDisconnectionHandlers[peripheral.identifier]; _gattDisconnectionHandlers[peripheral.identifier] = nil; From ac46c3670c2527816f543ce99502f46778b83710 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 31 Mar 2026 15:15:23 -0700 Subject: [PATCH 035/151] Remove obsolete code. PiperOrigin-RevId: 892563700 --- .../windows/bluetooth_classic_medium.cc | 26 ++-- .../platform/implementation/windows/utils.cc | 132 +----------------- .../platform/implementation/windows/utils.h | 46 ++---- .../implementation/windows/utils_test.cc | 66 --------- .../implementation/windows/wifi_lan_medium.cc | 1 + .../windows/wifi_lan_server_socket.cc | 27 +++- 6 files changed, 50 insertions(+), 248 deletions(-) diff --git a/internal/platform/implementation/windows/bluetooth_classic_medium.cc b/internal/platform/implementation/windows/bluetooth_classic_medium.cc index 7dbaf96a..87a80ffd 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_medium.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_medium.cc @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -39,7 +40,6 @@ #include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.Collections.h" #include "internal/platform/implementation/windows/generated/winrt/base.h" #include "internal/platform/implementation/windows/utils.h" -#include "internal/platform/implementation/windows/wifi_lan.h" #include "internal/platform/logging.h" #include "internal/platform/mac_address.h" @@ -72,6 +72,16 @@ constexpr wchar_t kBluetoothSelector[] = L"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}" L"\""; +// The Id of the Service Name SDP attribute +constexpr uint16_t SdpServiceNameAttributeId = 0x100; + +// The SDP Type of the Service Name SDP attribute. +// The first byte in the SDP Attribute encodes the SDP Attribute Type as +// follows: +// - the Attribute Type size in the least significant 3 bits, +// - the SDP Attribute Type value in the most significant 5 bits. +constexpr char SdpServiceNameAttributeType = (4 << 3) | 5; + void DumpDeviceInformation( const IMapView& properties) { if (!kEnableDumpDeviceInfomation) { @@ -462,17 +472,17 @@ bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requested_service) { } auto attributes = requested_service.GetSdpRawAttributesAsync().get(); - if (!attributes.HasKey(Constants::SdpServiceNameAttributeId)) { + if (!attributes.HasKey(SdpServiceNameAttributeId)) { LOG(ERROR) << __func__ << ": Missing SdpServiceNameAttributeId."; return false; } - auto attribute_reader = DataReader::FromBuffer( - attributes.Lookup(Constants::SdpServiceNameAttributeId)); + auto attribute_reader = + DataReader::FromBuffer(attributes.Lookup(SdpServiceNameAttributeId)); auto attribute_type = attribute_reader.ReadByte(); - if (attribute_type != Constants::SdpServiceNameAttributeType) { + if (attribute_type != SdpServiceNameAttributeType) { LOG(ERROR) << __func__ << ": Missing SdpServiceNameAttributeType."; return false; } @@ -958,7 +968,7 @@ bool BluetoothClassicMedium::InitializeServiceSdpAttributes( auto sdp_writer = DataWriter(); // Write the Service Name Attribute. - sdp_writer.WriteByte(Constants::SdpServiceNameAttributeType); + sdp_writer.WriteByte(SdpServiceNameAttributeType); // The length of the UTF-8 encoded Service Name SDP Attribute. sdp_writer.WriteByte(service_name.size()); @@ -968,8 +978,8 @@ bool BluetoothClassicMedium::InitializeServiceSdpAttributes( sdp_writer.WriteString(winrt::to_hstring(service_name)); // Set the SDP Attribute on the RFCOMM Service Provider. - rfcomm_provider.SdpRawAttributes().Insert( - Constants::SdpServiceNameAttributeId, sdp_writer.DetachBuffer()); + rfcomm_provider.SdpRawAttributes().Insert(SdpServiceNameAttributeId, + sdp_writer.DetachBuffer()); return true; } catch (...) { diff --git a/internal/platform/implementation/windows/utils.cc b/internal/platform/implementation/windows/utils.cc index 62fa4562..ff166f7d 100644 --- a/internal/platform/implementation/windows/utils.cc +++ b/internal/platform/implementation/windows/utils.cc @@ -16,9 +16,6 @@ // clang-format off #include -#include -#include -#include #include #include // clang-format on @@ -33,9 +30,6 @@ #include // Nearby connections headers -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/implementation/crypto.h" #include "internal/platform/implementation/windows/string_utils.h" #include "internal/platform/logging.h" #include "internal/platform/uuid.h" @@ -44,127 +38,8 @@ #include "winrt/base.h" namespace nearby::windows { -namespace { -void AddIpUnicastAddresses(IP_ADAPTER_UNICAST_ADDRESS* unicast_addresses, - std::vector& addresses) { - std::string address; - while (unicast_addresses != nullptr) { - DWORD size = INET6_ADDRSTRLEN; // Max IP address length. - address.resize(size); - if (WSAAddressToStringA(unicast_addresses->Address.lpSockaddr, - unicast_addresses->Address.iSockaddrLength, - /*lpProtocolInfo=*/nullptr, address.data(), - &size) != 0) { - LOG(ERROR) << __func__ << ": Cannot convert address to string."; - continue; - } - address.resize(size); - addresses.push_back(address); - unicast_addresses = unicast_addresses->Next; - } -} - -void GetIpAddresses(int family, std::vector& wifi_addresses, - std::vector& ethernet_addresses, - std::vector& other_addresses) { - static constexpr int kDefaultBufferSize = 15 * 1024; // default to 15K buffer - static constexpr int kMaxBufferSize = - 45 * 1024; // Try to increase buffer 2 times. - static constexpr ULONG kDefaultFlags = - GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME; - ULONG buffer_size = 0; - // A string to own the memory for IP_ADAPTER_ADDRESSES. - std::string address_buffer; - ULONG error_code = ERROR_NO_DATA; - IP_ADAPTER_ADDRESSES* addresses = nullptr; - do { - buffer_size += kDefaultBufferSize; - address_buffer.reserve(buffer_size); - addresses = reinterpret_cast(address_buffer.data()); - error_code = GetAdaptersAddresses( - family, kDefaultFlags, /*reserved=*/nullptr, addresses, &buffer_size); - } while (error_code == ERROR_BUFFER_OVERFLOW && - buffer_size <= kMaxBufferSize); - if (error_code != ERROR_NO_DATA && error_code != NO_ERROR) { - LOG(ERROR) << __func__ - << ": Cannot get adapter addresses. Error code: " << error_code; - return; - } - if (error_code == ERROR_NO_DATA) { - LOG(INFO) << __func__ << ": No IPv4 addresses found."; - return; - } - IP_ADAPTER_ADDRESSES* next_address = addresses; - while (next_address != nullptr) { - if (next_address->OperStatus == IfOperStatusUp) { - if (next_address->IfType == IF_TYPE_ETHERNET_CSMACD) { - VLOG(1) << "Found ethernet adater: " << next_address->AdapterName - << " index: " << next_address->IfIndex - << " v6 index: " << next_address->Ipv6IfIndex; - AddIpUnicastAddresses(next_address->FirstUnicastAddress, - ethernet_addresses); - } else if (next_address->IfType == IF_TYPE_IEEE80211) { - VLOG(1) << "Found wifi adapter: " << next_address->AdapterName - << " index: " << next_address->IfIndex - << " v6 index: " << next_address->Ipv6IfIndex; - AddIpUnicastAddresses(next_address->FirstUnicastAddress, - wifi_addresses); - } else if (next_address->IfType != IF_TYPE_SOFTWARE_LOOPBACK) { - // Skip loopback interfaces. - VLOG(1) << "Found other adapter: " << next_address->AdapterName; - AddIpUnicastAddresses(next_address->FirstUnicastAddress, - other_addresses); - } - } - next_address = next_address->Next; - } -} - -} // namespace - -std::string ipaddr_4bytes_to_dotdecimal_string( - absl::string_view ipaddr_4bytes) { - if (ipaddr_4bytes.size() != 4) { - return {}; - } - - in_addr address; - address.S_un.S_un_b.s_b1 = ipaddr_4bytes[0]; - address.S_un.S_un_b.s_b2 = ipaddr_4bytes[1]; - address.S_un.S_un_b.s_b3 = ipaddr_4bytes[2]; - address.S_un.S_un_b.s_b4 = ipaddr_4bytes[3]; - char* ipv4_address = inet_ntoa(address); - if (ipv4_address == nullptr) { - return {}; - } - - return std::string(ipv4_address); -} - -std::string ipaddr_dotdecimal_to_4bytes_string(std::string ipv4_s) { - if (ipv4_s.empty()) { - return {}; - } - - in_addr address; - address.S_un.S_addr = inet_addr(ipv4_s.c_str()); - char ipv4_b[5]; - ipv4_b[0] = address.S_un.S_un_b.s_b1; - ipv4_b[1] = address.S_un.S_un_b.s_b2; - ipv4_b[2] = address.S_un.S_un_b.s_b3; - ipv4_b[3] = address.S_un.S_un_b.s_b4; - ipv4_b[4] = 0; - - return std::string(ipv4_b, 4); -} - -std::vector GetIpv4Addresses() { - std::vector result; - GetIpAddresses(AF_INET, result, result, result); - return result; -} +using winrt::Windows::Foundation::IInspectable; Uuid winrt_guid_to_nearby_uuid(const ::winrt::guid& guid) { int64_t data1 = guid.Data1; @@ -209,11 +84,6 @@ bool is_nearby_uuid_equal_to_winrt_guid(const Uuid& uuid, return uuid == winrt_guid_to_nearby_uuid(guid); } -ByteArray Sha256(absl::string_view input, size_t size) { - ByteArray hash = nearby::Crypto::Sha256(input); - return ByteArray{hash.data(), size}; -} - bool InspectableReader::ReadBoolean(IInspectable inspectable) { if (inspectable == nullptr) { return false; diff --git a/internal/platform/implementation/windows/utils.h b/internal/platform/implementation/windows/utils.h index 52483dd9..b3910c6a 100644 --- a/internal/platform/implementation/windows/utils.h +++ b/internal/platform/implementation/windows/utils.h @@ -23,8 +23,6 @@ #include #include -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" #include "internal/platform/uuid.h" #include "winrt/Windows.Foundation.h" #include "winrt/base.h" @@ -32,17 +30,6 @@ namespace nearby { namespace windows { -using winrt::Windows::Foundation::IInspectable; - -std::string ipaddr_4bytes_to_dotdecimal_string(absl::string_view ipaddr_4bytes); -std::string ipaddr_dotdecimal_to_4bytes_string(std::string ipv4_s); - -// Helpers to windows platform -ByteArray Sha256(absl::string_view input, size_t size); - -// Reads the IPv4 addresses -std::vector GetIpv4Addresses(); - // Help methods to convert between Uuid and winrt::guid Uuid winrt_guid_to_nearby_uuid(const ::winrt::guid& guid); winrt::guid nearby_uuid_to_winrt_guid(Uuid uuid); @@ -57,31 +44,18 @@ std::optional GetDnsHostName(); // Returns true if the system has an Intel Wi-Fi adapter. bool IsIntelWifiAdapter(); -namespace Constants { -// The Id of the Service Name SDP attribute -const uint16_t SdpServiceNameAttributeId = 0x100; - -// The SDP Type of the Service Name SDP attribute. -// The first byte in the SDP Attribute encodes the SDP Attribute Type as -// follows: -// - the Attribute Type size in the least significant 3 bits, -// - the SDP Attribute Type value in the most significant 5 bits. -const char SdpServiceNameAttributeType = (4 << 3) | 5; - -// Possible values for the adapter type. Refer to: -// https://learn.microsoft.com/en-us/windows/win32/api/iptypes/ns-iptypes-ip_adapter_info -const uint16_t kInterfaceTypeEthernet = 6; -const uint16_t kInterfaceTypeWifi = 71; -} // namespace Constants - class InspectableReader { public: - static bool ReadBoolean(IInspectable inspectable); - static uint16_t ReadUint16(IInspectable inspectable); - static uint32_t ReadUint32(IInspectable inspectable); - static std::string ReadString(IInspectable inspectable); - static std::vector ReadStringArray(IInspectable inspectable); - static GUID ReadGuid(IInspectable inspectable); + static bool ReadBoolean(winrt::Windows::Foundation::IInspectable inspectable); + static uint16_t ReadUint16( + winrt::Windows::Foundation::IInspectable inspectable); + static uint32_t ReadUint32( + winrt::Windows::Foundation::IInspectable inspectable); + static std::string ReadString( + winrt::Windows::Foundation::IInspectable inspectable); + static std::vector ReadStringArray( + winrt::Windows::Foundation::IInspectable inspectable); + static GUID ReadGuid(winrt::Windows::Foundation::IInspectable inspectable); }; } // namespace windows diff --git a/internal/platform/implementation/windows/utils_test.cc b/internal/platform/implementation/windows/utils_test.cc index 54bb7bea..5ee19153 100644 --- a/internal/platform/implementation/windows/utils_test.cc +++ b/internal/platform/implementation/windows/utils_test.cc @@ -24,8 +24,6 @@ #include #include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" #include "internal/platform/implementation/windows/string_utils.h" #include "internal/platform/logging.h" #include "internal/platform/uuid.h" @@ -38,62 +36,8 @@ namespace { using ::winrt::Windows::Foundation::IInspectable; using ::winrt::Windows::Foundation::PropertyValue; -constexpr absl::string_view kIpDotdecimal{"192.168.1.37"}; -constexpr char kIp4Bytes[] = {(char)192, (char)168, (char)1, (char)37}; - } // namespace -TEST(UtilsTests, Ip4BytesToDotdecimal) { - std::string result = - ipaddr_4bytes_to_dotdecimal_string(absl::string_view(kIp4Bytes, 4)); - - EXPECT_EQ(result, kIpDotdecimal); -} - -TEST(UtilsTests, Ip4BytesToDotdecimalInvalid) { - std::string result = ipaddr_4bytes_to_dotdecimal_string(absl::string_view()); - EXPECT_TRUE(result.empty()); -} - -TEST(UtilsTests, IpDotdecimalTo4Bytes) { - std::string result = - ipaddr_dotdecimal_to_4bytes_string(std::string(kIpDotdecimal)); - - EXPECT_EQ(result, std::string(kIp4Bytes, 4)); -} - -TEST(UtilsTests, IpDotdecimalTo4BytesEmpty) { - std::string result = ipaddr_dotdecimal_to_4bytes_string(""); - EXPECT_TRUE(result.empty()); -} - -TEST(UtilsTests, IpDotdecimalTo4BytesInvalid) { - std::string result = ipaddr_dotdecimal_to_4bytes_string("192.168.1.256"); - // inet_addr returns INADDR_NONE for invalid address. - char expected[] = {(char)255, (char)255, (char)255, (char)255}; - EXPECT_EQ(result, std::string(expected, 4)); -} - -TEST(UtilsTests, Sha256) { - std::string input = "Hello World"; - // sha256("Hello World") - const char expected_sha256[] = { - (char)0xa5, (char)0x91, (char)0xa6, (char)0xd4, (char)0x0b, (char)0xf4, - (char)0x20, (char)0x40, (char)0x4a, (char)0x01, (char)0x17, (char)0x33, - (char)0xcf, (char)0xb7, (char)0xb1, (char)0x90, (char)0xd6, (char)0x2c, - (char)0x65, (char)0xbf, (char)0x0b, (char)0xcd, (char)0xa3, (char)0x2b, - (char)0x57, (char)0xb2, (char)0x77, (char)0xd9, (char)0xad, (char)0x9f, - (char)0x14, (char)0x6e}; - - ByteArray result = Sha256(input, 32); - EXPECT_EQ(result.size(), 32); - EXPECT_EQ(memcmp(result.data(), expected_sha256, 32), 0); - - result = Sha256(input, 16); - EXPECT_EQ(result.size(), 16); - EXPECT_EQ(memcmp(result.data(), expected_sha256, 16), 0); -} - TEST(UtilsTests, ConvertBetweenWinrtGuidAndNearbyUuidSuccessfully) { Uuid uuid(0x123e4567e89b12d3, 0xa456426614174000); winrt::guid guid("{123e4567-e89b-12d3-a456-426614174000}"); @@ -157,16 +101,6 @@ TEST(UtilsTests, InspectableReader_ReadStringArray) { std::invalid_argument); } -TEST(UtilsTests, GetIpv4Addresses) { - LOG(ERROR) << "GetIpv4Addresses"; - std::vector addresses = GetIpv4Addresses(); - EXPECT_FALSE(addresses.empty()); - for (const auto& address : addresses) { - LOG(ERROR) << "address: " << address; - } - LOG(ERROR) << "GetIpv4Addresses done"; -} - TEST(UtilsTests, GetDnsHostName) { std::optional host_name = GetDnsHostName(); ASSERT_TRUE(host_name.has_value()); diff --git a/internal/platform/implementation/windows/wifi_lan_medium.cc b/internal/platform/implementation/windows/wifi_lan_medium.cc index f7ab9504..01200bef 100644 --- a/internal/platform/implementation/windows/wifi_lan_medium.cc +++ b/internal/platform/implementation/windows/wifi_lan_medium.cc @@ -64,6 +64,7 @@ using ::winrt::Windows::Devices::Enumeration::DeviceInformationKind; using ::winrt::Windows::Devices::Enumeration::DeviceInformationUpdate; using ::winrt::Windows::Devices::Enumeration::DeviceWatcher; using ::winrt::Windows::Foundation::Collections::IMapView; +using ::winrt::Windows::Foundation::IInspectable; using ::winrt::Windows::Networking::Connectivity::NetworkInformation; // mDNS text attributes diff --git a/internal/platform/implementation/windows/wifi_lan_server_socket.cc b/internal/platform/implementation/windows/wifi_lan_server_socket.cc index 81a39950..ea09e691 100644 --- a/internal/platform/implementation/windows/wifi_lan_server_socket.cc +++ b/internal/platform/implementation/windows/wifi_lan_server_socket.cc @@ -24,22 +24,35 @@ #include "internal/platform/exception.h" #include "internal/platform/implementation/wifi_lan.h" #include "internal/platform/implementation/windows/nearby_server_socket.h" +#include "internal/platform/implementation/windows/network_info.h" #include "internal/platform/implementation/windows/socket_address.h" -#include "internal/platform/implementation/windows/utils.h" #include "internal/platform/implementation/windows/wifi_lan.h" #include "internal/platform/logging.h" +#include "internal/platform/service_address.h" namespace nearby::windows { -// Returns the first IP address. +// Returns the first IPv4 address. std::string WifiLanServerSocket::GetIPAddress() const { // Just pick an IP address from the list of available addresses. - std::vector ip_addresses = GetIpv4Addresses(); - if (ip_addresses.empty()) { - LOG(ERROR) << "No IP addresses found."; - return ""; + const NetworkInfo& network_info = NetworkInfo::GetNetworkInfo(); + for (const NetworkInfo::InterfaceInfo& net_interface : + network_info.GetInterfaces()) { + if (net_interface.type != InterfaceType::kWifi && + net_interface.type != InterfaceType::kEthernet) { + continue; + } + for (const SocketAddress& v4_address : net_interface.ipv4_addresses) { + // Ignore link local addresses. + if (v4_address.IsV4LinkLocal()) { + continue; + } + ServiceAddress service_address = v4_address.ToServiceAddress(0); + return std::string(service_address.address.begin(), + service_address.address.end()); + } } - return ipaddr_dotdecimal_to_4bytes_string(ip_addresses.front()); + return ""; } // Blocks until either: From 1d3ebd484b578fbb3ff7125d824e5205f4b3d1e7 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 1 Apr 2026 11:38:27 -0700 Subject: [PATCH 036/151] internal PiperOrigin-RevId: 893035142 --- sharing/fake_nearby_sharing_service.cc | 20 ++++++++++++++++++++ sharing/fake_nearby_sharing_service.h | 6 +++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/sharing/fake_nearby_sharing_service.cc b/sharing/fake_nearby_sharing_service.cc index 42538323..c5975af4 100644 --- a/sharing/fake_nearby_sharing_service.cc +++ b/sharing/fake_nearby_sharing_service.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include "location/nearby/sharing/lib/sync/sync_manager.h" #include "absl/functional/any_invocable.h" @@ -165,6 +166,14 @@ void FakeNearbySharingService::Cancel( status_codes_callback(StatusCodes::kOk); } +void FakeNearbySharingService::InitiatePairing( + int64_t share_target_id, service::proto::BindingRequest::Type binding_type, + absl::AnyInvocable + status_codes_callback) { + initiate_pairing_callbacks_[share_target_id] = + std::move(status_codes_callback); +} + std::string FakeNearbySharingService::Dump() const { return ""; } NearbyShareSettings* FakeNearbySharingService::GetSettings() { return nullptr; } @@ -281,5 +290,16 @@ void FakeNearbySharingService::FireShareTargetLost(ShareTarget share_target) { } } +void FakeNearbySharingService::FireInitiatePairingResult( + int64_t share_target_id, StatusCodes status) { + auto it = initiate_pairing_callbacks_.find(share_target_id); + if (it == initiate_pairing_callbacks_.end()) { + return; + } + auto callback = std::move(it->second); + initiate_pairing_callbacks_.erase(it); + std::move(callback)(status); +} + } // namespace sharing } // namespace nearby diff --git a/sharing/fake_nearby_sharing_service.h b/sharing/fake_nearby_sharing_service.h index db47f7b1..4cd22969 100644 --- a/sharing/fake_nearby_sharing_service.h +++ b/sharing/fake_nearby_sharing_service.h @@ -121,7 +121,7 @@ class FakeNearbySharingService : public NearbySharingService { int64_t share_target_id, service::proto::BindingRequest::Type binding_type, absl::AnyInvocable - status_codes_callback) override {} + status_codes_callback) override; std::string Dump() const override; bool IsBluetoothPresent() const override { return true; } @@ -180,6 +180,7 @@ class FakeNearbySharingService : public NearbySharingService { void FireShareTargetDiscovered(ShareTarget share_target); void FireShareTargetUpdated(ShareTarget share_target); void FireShareTargetLost(ShareTarget share_target); + void FireInitiatePairingResult(int64_t share_target_id, StatusCodes status); private: ObserverList observers_; @@ -202,6 +203,9 @@ class FakeNearbySharingService : public NearbySharingService { FakeNearbyIdentityClient identity_rpc_client_; std::unique_ptr sync_manager_; std::unique_ptr outgoing_targets_manager_; + absl::flat_hash_map> + initiate_pairing_callbacks_; }; } // namespace sharing From a405436f4485528a73cf445c9f08c2147540766d Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Wed, 1 Apr 2026 18:26:31 -0700 Subject: [PATCH 037/151] [Nearby] Optimize NWFramework socket reads and writes for performance and memory. I PiperOrigin-RevId: 893210612 --- .../apple/Mediums/WiFiCommon/BUILD | 2 +- .../Mediums/WiFiCommon/GNCNWFrameworkSocket.h | 21 ++++++++ ...meworkSocket.m => GNCNWFrameworkSocket.mm} | 49 +++++++++++++++++++ .../apple/Mediums/WiFiCommon/Tests/BUILD | 2 +- ...cketTest.m => GNCNWFrameworkSocketTest.mm} | 35 +++++++++++++ 5 files changed, 107 insertions(+), 2 deletions(-) rename internal/platform/implementation/apple/Mediums/WiFiCommon/{GNCNWFrameworkSocket.m => GNCNWFrameworkSocket.mm} (69%) rename internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/{GNCNWFrameworkSocketTest.m => GNCNWFrameworkSocketTest.mm} (71%) diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/BUILD b/internal/platform/implementation/apple/Mediums/WiFiCommon/BUILD index 43313086..59dfe33c 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/BUILD +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/BUILD @@ -32,7 +32,7 @@ objc_library( "GNCNWFramework.m", "GNCNWFrameworkError.m", "GNCNWFrameworkServerSocket.m", - "GNCNWFrameworkSocket.m", + "GNCNWFrameworkSocket.mm", "GNCNWListenerImpl.m", "GNCNWParameters.m", ], diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h b/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h index 4336418c..5ce0e67e 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h @@ -15,6 +15,12 @@ #import #import +#ifdef __cplusplus +#include +#include +#endif + + @protocol GNCNWConnection; @interface GNCNWFrameworkSocket : NSObject @@ -44,6 +50,21 @@ */ - (nullable NSData *)readMaxLength:(NSUInteger)length error:(NSError **_Nullable)error; +/** + * Reads the requested amount of bytes from the connection and converts it to a string. + * + * Blocks execution until the bytes have been read or an error occurs. + * + * @param length The number of bytes to read. + * @param[out] error Error that will be populated on failure. A read may return non-nil data along + * with an error. This normally happens if the data read is shorter than the + * requested length. + */ +#ifdef __cplusplus +- (std::optional)readStringWithMaxLength:(NSUInteger)length + error:(NSError **_Nullable)error; +#endif + /** * Writes the given data to the connection. * diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.m b/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.mm similarity index 69% rename from internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.m rename to internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.mm index 76d6c601..d9c2ed3c 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.m +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.mm @@ -17,6 +17,9 @@ #import #import +#include +#include + #import "internal/platform/implementation/apple/Log/GNCLogger.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWConnection.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkError.h" @@ -85,6 +88,52 @@ static const NSTimeInterval kConnectionWriteTimeout = 5.0; // 5 seconds timeout return blockResult; } +- (std::optional)readStringWithMaxLength:(NSUInteger)length error:(NSError **)error { + if (!self.connection) { + if (error) { + *error = [NSError errorWithDomain:GNCNWFrameworkErrorDomain + code:GNCNWFrameworkErrorUnknown + userInfo:nil]; + } + return std::nullopt; + } + + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block std::string resultString; + __block NSError *blockError = nil; + __block BOOL contentReceived = NO; + + [self.connection + receiveMessageWithMinLength:(uint32_t)length + maxLength:(uint32_t)length + completionHandler:^(dispatch_data_t _Nullable content, + nw_content_context_t _Nullable context, bool isComplete, + nw_error_t _Nullable receiveError) { + if (receiveError) { + blockError = (__bridge_transfer NSError *)nw_error_copy_cf_error(receiveError); + } + if (content) { + contentReceived = YES; + // OPTIMIZATION: Copy directly from dispatch_data_t into std::string + resultString.reserve(dispatch_data_get_size(content)); + dispatch_data_apply(content, ^bool(dispatch_data_t region, size_t offset, + const void *buffer, size_t size) { + resultString.append((const char *)buffer, size); + return true; + }); + } + dispatch_semaphore_signal(semaphore); + }]; + + // Block the current thread until the network callback completes. + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + + if (error != nil) { + *error = blockError; + } + return (!contentReceived) ? std::nullopt : std::make_optional(std::move(resultString)); +} + - (BOOL)write:(NSData *)data error:(NSError **)error { if (!self.connection) { if (error) { diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/BUILD b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/BUILD index 57afaee9..240daf0d 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/BUILD +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/BUILD @@ -57,7 +57,7 @@ objc_library( "GNCNWBrowserImplTest.m", "GNCNWConnectionImplTest.m", "GNCNWFrameworkServerSocketTest.m", - "GNCNWFrameworkSocketTest.m", + "GNCNWFrameworkSocketTest.mm", "GNCNWFrameworkTest.m", "GNCNWListenerImplTest.m", "GNCNWParametersTest.m", diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCNWFrameworkSocketTest.m b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCNWFrameworkSocketTest.mm similarity index 71% rename from internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCNWFrameworkSocketTest.m rename to internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCNWFrameworkSocketTest.mm index e194a0f4..a7856bd5 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCNWFrameworkSocketTest.m +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCNWFrameworkSocketTest.mm @@ -17,6 +17,9 @@ #import #import +#include +#include + #import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWConnection.h" NS_ASSUME_NONNULL_BEGIN @@ -75,6 +78,38 @@ NS_ASSUME_NONNULL_BEGIN XCTAssertNil(error); } +- (void)testReadStringWithMaxLength_Success { + NSError *error = nil; + NSString *testString = @"testData"; + NSData *testData = [testString dataUsingEncoding:NSUTF8StringEncoding]; + dispatch_data_t dispatchData = dispatch_data_create(testData.bytes, testData.length, dispatch_get_main_queue(), ^{}); + _fakeConnection.dataToReceive = dispatchData; + + std::optional receivedString = [_socket readStringWithMaxLength:testData.length error:&error]; + + XCTAssertTrue(receivedString.has_value()); + XCTAssertEqualObjects(@(receivedString.value().c_str()), testString); + XCTAssertNil(error); +} + +- (void)testReadStringWithMaxLength_Error { + NSError *error = nil; + _fakeConnection.simulateReceiveFailure = YES; + + std::optional receivedString = [_socket readStringWithMaxLength:10 error:&error]; + + XCTAssertFalse(receivedString.has_value()); + XCTAssertNil(error); // Fake doesn't produce an NSError +} + +- (void)testReadStringWithMaxLength_Zero { + NSError *error = nil; + std::optional receivedString = [_socket readStringWithMaxLength:0 error:&error]; + + XCTAssertFalse(receivedString.has_value()); + XCTAssertNil(error); +} + - (void)testWrite_Success { NSError *error = nil; NSString *testString = @"testData"; From ca8e83e3e86caeeb6998fede1515191dfdea5b7d Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 2 Apr 2026 14:25:03 -0700 Subject: [PATCH 038/151] Automated Code Change PiperOrigin-RevId: 893702079 --- .../implementation/mediums/ble/instant_on_lost_manager.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/connections/implementation/mediums/ble/instant_on_lost_manager.cc b/connections/implementation/mediums/ble/instant_on_lost_manager.cc index 6fd17c46..8a477d21 100644 --- a/connections/implementation/mediums/ble/instant_on_lost_manager.cc +++ b/connections/implementation/mediums/ble/instant_on_lost_manager.cc @@ -206,10 +206,7 @@ bool InstantOnLostManager::StartInstantOnLostAdvertisement() { StopOnLostAdvertising(); - if (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kDisableInstantOnLostOnBleWithoutExtended) && - !ble_medium_.IsExtendedAdvertisementsAvailable()) { + if (!ble_medium_.IsExtendedAdvertisementsAvailable()) { LOG(WARNING) << __func__ << ": Disabling instant on lost on BLE without extended advertising."; From 79a05eb4825cd0bfc75a361599a646c9fa1c1d55 Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 3 Apr 2026 22:03:49 -0700 Subject: [PATCH 039/151] internal changes PiperOrigin-RevId: 894402536 --- sharing/proto/wire_format.proto | 45 +++------------------------------ 1 file changed, 3 insertions(+), 42 deletions(-) diff --git a/sharing/proto/wire_format.proto b/sharing/proto/wire_format.proto index d20329c3..57ec2660 100644 --- a/sharing/proto/wire_format.proto +++ b/sharing/proto/wire_format.proto @@ -183,7 +183,7 @@ message Frame { optional V1Frame v1 = 2; } -// NEXT_ID=10 +// NEXT_ID=9 message V1Frame { enum FrameType { UNKNOWN_FRAME_TYPE = 0; @@ -196,8 +196,7 @@ message V1Frame { CANCEL = 6; // No longer used. PROGRESS_UPDATE = 7; - FILE_SYNC = 8; - BINDINGS = 9; + BINDINGS = 8; } optional FrameType type = 1; @@ -209,8 +208,7 @@ message V1Frame { optional PairedKeyResultFrame paired_key_result = 5; optional CertificateInfoFrame certificate_info = 6 [deprecated = true]; optional ProgressUpdateFrame progress_update = 7 [deprecated = true]; - optional SyncFrame file_sync = 8; - optional BindingFrame bindings = 9; + optional BindingFrame bindings = 8; } // An introduction packet sent by the sending side. Contains a list of files @@ -245,43 +243,6 @@ message ProgressUpdateFrame { optional bool start_transfer = 2; } -// A packet for file sync messages. -// NEXT_ID=3 -message SyncFrame { - oneof content { - SyncHandshake handshake = 1; - SyncConfig config = 2; - } -} - -// A packet for file sync handshake messages. -// NEXT_ID=1 -message SyncHandshake {} - -// A packet for file sync config messages. -// NEXT_ID=2 -message SyncConfig { - repeated SyncFolder folders = 1; -} - -// A packet for file sync folder messages. -// NEXT_ID=5 -message SyncFolder { - // An identifier of the folder for the pair of source and target devices to - // uniquely identify it among all folders that are being synced. - optional string id = 1; - // Human readable name of the folder. - optional string label = 2; - // A randomly generated id when the index is created. Regenerate when the - // index is reset. - optional int32 index_id = 3; - // The maximum sequence number of the folder. Each number represents an update - // to a file in the folder. Sequence numbers are only valid within the scope - // of a valid index_id. If an index is reset, all sequence numbers need to be - // regenerated, including max_sequence. - optional int64 max_sequence = 4; -} - // Messages used to create pair bindings between devices. // An initiator device requests a new bindingId from the BE using the // InitiateBinding rpc. This new bindingId is passed to the peer device using From 1bc6346601c440e29918bad47b3248da8d872eb0 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Sun, 5 Apr 2026 07:17:49 -0700 Subject: [PATCH 040/151] [Nearby] Optimize NWFramework socket reads and writes for performance and memory. II PiperOrigin-RevId: 894923575 --- .../flags/nearby_connections_feature_flags.h | 3 ++ .../apple/Flags/GNCFeatureFlags.h | 3 ++ .../apple/Flags/GNCFeatureFlags.mm | 5 ++ .../apple/Mediums/WiFiCommon/Tests/BUILD | 2 +- ...rkSocket.m => GNCFakeNWFrameworkSocket.mm} | 19 +++++++ .../apple/Tests/GNCAwdlMediumTest.mm | 51 +++++++++++++++++++ .../apple/Tests/GNCWifiHotspotMediumTest.mm | 33 +++++++++++- .../apple/Tests/GNCWifiLanMediumTest.mm | 39 ++++++++++++++ .../platform/implementation/apple/awdl.mm | 21 ++++++-- .../implementation/apple/wifi_hotspot.mm | 24 ++++++--- .../platform/implementation/apple/wifi_lan.mm | 21 ++++++-- 11 files changed, 202 insertions(+), 19 deletions(-) rename internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/{GNCFakeNWFrameworkSocket.m => GNCFakeNWFrameworkSocket.mm} (72%) diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h index e26b11e1..f1a6e16a 100644 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -111,6 +111,9 @@ constexpr auto kEnableSharedPeripheralManager = // 4. auto-resume 5. non-distance-constraint-recovery 6. payload_ack constexpr auto kSafeToDisconnectVersion = flags::Flag(kConfigPackage, "45425841", 0); +// Enable/Disable single copy read/write for input/output buffers. +constexpr auto kEnableSingleCopy = + flags::Flag(kConfigPackage, "45775979", true); } // namespace nearby_connections_feature } // namespace config_package_nearby diff --git a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h index e31a9b94..10d1a7c4 100644 --- a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h +++ b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h @@ -32,4 +32,7 @@ /** Checks whether shared peripheral manager is enabled in the Nearby Connections SDK. */ @property(nonatomic, class, readonly) BOOL sharedPeripheralManagerEnabled; +/** Checks whether single copy read/write is enabled in the Nearby Connections SDK. */ +@property(nonatomic, class, readonly) BOOL singleCopyEnabled; + @end diff --git a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm index 1955a263..0166e4c4 100644 --- a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm +++ b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm @@ -48,4 +48,9 @@ kEnableSharedPeripheralManager); } ++ (BOOL)singleCopyEnabled { + return nearby::NearbyFlags::GetInstance().GetBoolFlag( + nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy); +} + @end diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/BUILD b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/BUILD index 240daf0d..5aaa96ad 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/BUILD +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/BUILD @@ -29,7 +29,7 @@ objc_library( "GNCFakeNWConnection.m", "GNCFakeNWFramework.m", "GNCFakeNWFrameworkServerSocket.m", - "GNCFakeNWFrameworkSocket.m", + "GNCFakeNWFrameworkSocket.mm", "GNCFakeNWListener.m", ], hdrs = [ diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.m b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.mm similarity index 72% rename from internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.m rename to internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.mm index 6bdaf67c..cbf9b8c1 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.m +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.mm @@ -44,6 +44,25 @@ return [NSData data]; } +- (std::optional)readStringWithMaxLength:(NSUInteger)length error:(NSError **)error { + if (self.readError) { + if (error) *error = self.readError; + return std::nullopt; + } + if (self.dataToRead) { + NSData *data = self.dataToRead; + self.dataToRead = nil; + NSUInteger actualLength = MIN(length, data.length); + if (data.length > actualLength) { + self.dataToRead = + [data subdataWithRange:NSMakeRange(actualLength, data.length - actualLength)]; + } + NSData *returnData = [data subdataWithRange:NSMakeRange(0, actualLength)]; + return std::string((const char *)returnData.bytes, returnData.length); + } + return std::string(); +} + - (BOOL)write:(NSData *)data error:(NSError **)error { if (self.writeError) { if (error) { diff --git a/internal/platform/implementation/apple/Tests/GNCAwdlMediumTest.mm b/internal/platform/implementation/apple/Tests/GNCAwdlMediumTest.mm index 4ea125a8..0ba4ba69 100644 --- a/internal/platform/implementation/apple/Tests/GNCAwdlMediumTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCAwdlMediumTest.mm @@ -18,6 +18,9 @@ #include +#include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "internal/flags/nearby_flags.h" + #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFramework.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWConnection.h" @@ -45,6 +48,7 @@ static const int kTestPort = 1234; - (void)tearDown { _awdlMedium.reset(); + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); [super tearDown]; } @@ -128,6 +132,10 @@ static const int kTestPort = 1234; } - (void)testSocketAndStream { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + ::nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy, + false); + // Create a server socket. std::unique_ptr serverSocket = _awdlMedium->ListenForService(kTestPort); @@ -167,6 +175,49 @@ static const int kTestPort = 1234; XCTAssertTrue(fakeServerSocket.isClosed); } +- (void)testSocketAndStream_SingleCopyEnabled { + // Enable the flag. + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + ::nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy, + true); + + // Create a server socket. + std::unique_ptr serverSocket = + _awdlMedium->ListenForService(kTestPort); + XCTAssertTrue(serverSocket != nullptr); + + GNCFakeNWFrameworkServerSocket* fakeServerSocket = + (GNCFakeNWFrameworkServerSocket*)_fakeNWFramework.serverSockets[0]; + GNCFakeNWConnection* connection = [[GNCFakeNWConnection alloc] init]; + GNCFakeNWFrameworkSocket* fakeSocket = + [[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection]; + fakeServerSocket.socketToReturnOnAccept = fakeSocket; + + // Accept a client socket. + std::unique_ptr clientSocket = serverSocket->Accept(); + XCTAssertTrue(clientSocket != nullptr); + + // Test input stream with optimized single-copy read. + nearby::InputStream& inputStream = clientSocket->GetInputStream(); + fakeSocket.dataToRead = [@"optimized awdl data" dataUsingEncoding:NSUTF8StringEncoding]; + // "optimized awdl data" is 19 bytes. + nearby::ExceptionOr readData = inputStream.Read(19); + + XCTAssertTrue(readData.ok()); + XCTAssertEqual(std::string(readData.result()), "optimized awdl data"); + + // Test output stream. + nearby::OutputStream& outputStream = clientSocket->GetOutputStream(); + absl::string_view writeData("write data"); + XCTAssertTrue(outputStream.Write(writeData).Ok()); + XCTAssertEqualObjects(fakeSocket.writtenData, + [@"write data" dataUsingEncoding:NSUTF8StringEncoding]); + + // Clean up. + XCTAssertTrue(clientSocket->Close().Ok()); + XCTAssertTrue(serverSocket->Close().Ok()); +} + - (void)testServerSocketGetIPAddress { // Create a server socket. std::unique_ptr serverSocket = diff --git a/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm b/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm index 59687ab1..51a02995 100644 --- a/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm @@ -19,8 +19,11 @@ #include +#include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "internal/flags/nearby_flags.h" #include "internal/platform/byte_array.h" #include "internal/platform/exception.h" + #import "internal/platform/implementation/apple/Mediums/CoreLocation/CLLocationManager/Fake/CLLocationManagerFake.h" #import "internal/platform/implementation/apple/Mediums/Hotspot/GNCHotspotMedium.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h" @@ -59,8 +62,8 @@ const char kIPAddress[] = "192.168.1.2"; _medium.locationManager = _fakeLocationManager; _hotspotMedium = std::make_unique(_medium); _service_address = { - .address = {static_cast(192), static_cast(168), 1, 2}, - .port = 1234, + .address = {static_cast(192), static_cast(168), 1, 2}, + .port = 1234, }; } @@ -98,6 +101,10 @@ const char kIPAddress[] = "192.168.1.2"; } - (void)testInputStreamRead { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + ::nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy, + false); + nearby::CancellationFlag cancellationFlag; std::unique_ptr socket = _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); @@ -110,6 +117,28 @@ const char kIPAddress[] = "192.168.1.2"; XCTAssertTrue(readData.ok()); XCTAssertEqual(readData.result().size(), 4); XCTAssertEqual(strncmp(readData.result().data(), "Test", 4), 0); + + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); +} + +- (void)testInputStreamRead_SingleCopyEnabled { + // Enable the flag + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + ::nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy, + true); + + nearby::CancellationFlag cancellationFlag; + std::unique_ptr socket = + _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); + GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject; + fakeSocket.dataToRead = [@"HotspotOpt" dataUsingEncoding:NSUTF8StringEncoding]; + + nearby::ExceptionOr readData = socket->GetInputStream().Read(10); + + XCTAssertTrue(readData.ok()); + XCTAssertEqual(std::string(readData.result()), "HotspotOpt"); + + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); } - (void)testInputStreamClose { diff --git a/internal/platform/implementation/apple/Tests/GNCWifiLanMediumTest.mm b/internal/platform/implementation/apple/Tests/GNCWifiLanMediumTest.mm index 1d581fb2..9e01cfb5 100644 --- a/internal/platform/implementation/apple/Tests/GNCWifiLanMediumTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCWifiLanMediumTest.mm @@ -18,6 +18,9 @@ #include +#include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "internal/flags/nearby_flags.h" + #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFramework.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWConnection.h" @@ -118,6 +121,10 @@ } - (void)testSocketAndStream { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + ::nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy, + false); + // Create a server socket. std::unique_ptr serverSocket = _wifiLanMedium->ListenForService(1234); @@ -155,6 +162,38 @@ // Test closing the server socket. XCTAssertTrue(serverSocket->Close().Ok()); XCTAssertTrue(fakeServerSocket.isClosed); + // Reset the flag. + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); +} + +- (void)testSocketAndStream_SingleCopyEnabled { + // Enable the flag + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + ::nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy, + true); + + // Create a server socket and accept a client. + std::unique_ptr serverSocket = + _wifiLanMedium->ListenForService(1234); + GNCFakeNWFrameworkServerSocket* fakeServerSocket = + (GNCFakeNWFrameworkServerSocket*)_fakeNWFramework.serverSockets[0]; + GNCFakeNWConnection* connection = [[GNCFakeNWConnection alloc] init]; + GNCFakeNWFrameworkSocket* fakeSocket = + [[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection]; + fakeServerSocket.socketToReturnOnAccept = fakeSocket; + + std::unique_ptr clientSocket = serverSocket->Accept(); + nearby::InputStream& inputStream = clientSocket->GetInputStream(); + + // Test optimized single-copy read. + fakeSocket.dataToRead = [@"optimized data" dataUsingEncoding:NSUTF8StringEncoding]; + nearby::ExceptionOr readData = inputStream.Read(14); + + XCTAssertTrue(readData.ok()); + XCTAssertEqual(std::string(readData.result()), "optimized data"); + + // Reset the flag. + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); } - (void)testServerSocketGetIPAddress { diff --git a/internal/platform/implementation/apple/awdl.mm b/internal/platform/implementation/apple/awdl.mm index f23b61b5..15eaafb1 100644 --- a/internal/platform/implementation/apple/awdl.mm +++ b/internal/platform/implementation/apple/awdl.mm @@ -19,6 +19,7 @@ #include #include +#import "internal/platform/implementation/apple/Flags/GNCFeatureFlags.h" #import "internal/platform/implementation/apple/Log/GNCLogger.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFramework.h" @@ -35,12 +36,22 @@ AwdlInputStream::AwdlInputStream(GNCNWFrameworkSocket* socket) : socket_(socket) ExceptionOr AwdlInputStream::Read(std::int64_t size) { NSError* error = nil; - NSData* data = [socket_ readMaxLength:size error:&error]; - if (data == nil) { - GNCLoggerError(@"Error reading socket: %@", error); - return {Exception::kIo}; + if (GNCFeatureFlags.singleCopyEnabled) { + auto result = [socket_ readStringWithMaxLength:size error:&error]; + if (!result.has_value()) { + GNCLoggerError(@"Error reading socket: %@", error); + return {Exception::kIo}; + } + // OPTIMIZATION: Zero-copy transfer from std::string to ByteArray + return ExceptionOr{ByteArray(std::move(result.value()))}; + } else { + NSData* data = [socket_ readMaxLength:size error:&error]; + if (data == nil) { + GNCLoggerError(@"Error reading socket: %@", error); + return {Exception::kIo}; + } + return ExceptionOr{ByteArray((const char*)data.bytes, data.length)}; } - return ExceptionOr{ByteArray((const char*)data.bytes, data.length)}; } Exception AwdlInputStream::Close() { diff --git a/internal/platform/implementation/apple/wifi_hotspot.mm b/internal/platform/implementation/apple/wifi_hotspot.mm index 0ec2e846..79b08bb5 100644 --- a/internal/platform/implementation/apple/wifi_hotspot.mm +++ b/internal/platform/implementation/apple/wifi_hotspot.mm @@ -23,6 +23,8 @@ #include #include "internal/base/masker.h" #include "internal/platform/cancellation_flag_listener.h" + +#import "internal/platform/implementation/apple/Flags/GNCFeatureFlags.h" #import "internal/platform/implementation/apple/Log/GNCLogger.h" #import "internal/platform/implementation/apple/Mediums/Hotspot/GNCHotspotMedium.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h" @@ -43,12 +45,22 @@ WifiHotspotInputStream::WifiHotspotInputStream(GNCNWFrameworkSocket* socket) : s ExceptionOr WifiHotspotInputStream::Read(std::int64_t size) { NSError* error = nil; - NSData* data = [socket_ readMaxLength:size error:&error]; - if (data == nil) { - GNCLoggerError(@"Error reading socket: %@", error); - return {Exception::kIo}; + if (GNCFeatureFlags.singleCopyEnabled) { + auto result = [socket_ readStringWithMaxLength:size error:&error]; + if (!result.has_value()) { + GNCLoggerError(@"Error reading socket: %@", error); + return {Exception::kIo}; + } + // OPTIMIZATION: Zero-copy transfer from std::string to ByteArray + return ExceptionOr{ByteArray(std::move(result.value()))}; + } else { + NSData* data = [socket_ readMaxLength:size error:&error]; + if (data == nil) { + GNCLoggerError(@"Error reading socket: %@", error); + return {Exception::kIo}; + } + return ExceptionOr{ByteArray((const char*)data.bytes, data.length)}; } - return ExceptionOr{ByteArray((const char*)data.bytes, data.length)}; } Exception WifiHotspotInputStream::Close() { @@ -150,7 +162,7 @@ std::unique_ptr WifiHotspotMedium::ConnectToService( } // 4 bytes IP address format. NSData* host_ip_address = [NSData dataWithBytes:service_address.address.data() - length:service_address.address.size()]; + length:service_address.address.size()]; host = [GNCIPv4Address addressFromData:host_ip_address]; GNCLoggerInfo(@"Connect to Hotspot host server: %@", [host dottedRepresentation]); diff --git a/internal/platform/implementation/apple/wifi_lan.mm b/internal/platform/implementation/apple/wifi_lan.mm index 5f57ba52..70474b95 100644 --- a/internal/platform/implementation/apple/wifi_lan.mm +++ b/internal/platform/implementation/apple/wifi_lan.mm @@ -19,6 +19,7 @@ #include #include +#import "internal/platform/implementation/apple/Flags/GNCFeatureFlags.h" #import "internal/platform/implementation/apple/Log/GNCLogger.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h" #import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFramework.h" @@ -35,12 +36,22 @@ WifiLanInputStream::WifiLanInputStream(GNCNWFrameworkSocket* socket) : socket_(s ExceptionOr WifiLanInputStream::Read(std::int64_t size) { NSError* error = nil; - NSData* data = [socket_ readMaxLength:size error:&error]; - if (data == nil) { - GNCLoggerError(@"Error reading socket: %@", error); - return {Exception::kIo}; + if (GNCFeatureFlags.singleCopyEnabled) { + auto result = [socket_ readStringWithMaxLength:size error:&error]; + if (!result.has_value()) { + GNCLoggerError(@"Error reading socket: %@", error); + return {Exception::kIo}; + } + // OPTIMIZATION: Zero-copy transfer from std::string to ByteArray + return ExceptionOr{ByteArray(std::move(result.value()))}; + } else { + NSData* data = [socket_ readMaxLength:size error:&error]; + if (data == nil) { + GNCLoggerError(@"Error reading socket: %@", error); + return {Exception::kIo}; + } + return ExceptionOr{ByteArray((const char*)data.bytes, data.length)}; } - return ExceptionOr{ByteArray((const char*)data.bytes, data.length)}; } Exception WifiLanInputStream::Close() { From b382cdb022180bca18631dda21e6fa74a61db169 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Sun, 5 Apr 2026 07:50:13 -0700 Subject: [PATCH 041/151] [Nearby] Optimize NWFramework socket reads and writes for performance and memory. III PiperOrigin-RevId: 894930585 --- .../Mediums/WiFiCommon/GNCNWFrameworkError.h | 1 + .../Mediums/WiFiCommon/GNCNWFrameworkSocket.h | 11 +++++ .../WiFiCommon/GNCNWFrameworkSocket.mm | 46 ++++++++++++++++++- .../Tests/GNCNWFrameworkSocketTest.mm | 23 ++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkError.h b/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkError.h index 1893dbd6..df429dd8 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkError.h +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkError.h @@ -26,4 +26,5 @@ typedef NS_ERROR_ENUM(GNCNWFrameworkErrorDomain, GNCNWFrameworkError){ GNCNWFrameworkErrorUnknown, GNCNWFrameworkErrorTimedOut, GNCNWFrameworkErrorDuplicateDiscovererForServiceType, + GNCNWFrameworkErrorNotConnected, }; diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h b/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h index 5ce0e67e..a13b2774 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h @@ -75,6 +75,17 @@ */ - (BOOL)write:(NSData *)data error:(NSError **_Nullable)error; +/** + * Writes raw bytes to the connection. + * + * @param bytes The buffer to write. + * @param length The number of bytes to write. + * @param error Error that will be populated on failure. + */ +- (BOOL)writeBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **_Nullable)error; + /** * Gracefully closes the connection to remote endpoint. * diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.mm b/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.mm index d9c2ed3c..001fe2e0 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.mm +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.mm @@ -92,7 +92,7 @@ static const NSTimeInterval kConnectionWriteTimeout = 5.0; // 5 seconds timeout if (!self.connection) { if (error) { *error = [NSError errorWithDomain:GNCNWFrameworkErrorDomain - code:GNCNWFrameworkErrorUnknown + code:GNCNWFrameworkErrorNotConnected userInfo:nil]; } return std::nullopt; @@ -185,6 +185,50 @@ static const NSTimeInterval kConnectionWriteTimeout = 5.0; // 5 seconds timeout return signaled && blockSuccess; } +- (BOOL)writeBytes:(const void *)bytes length:(NSUInteger)length error:(NSError **)error { + if (!self.connection) { + if (error) { + *error = [NSError errorWithDomain:GNCNWFrameworkErrorDomain + code:GNCNWFrameworkErrorNotConnected + userInfo:nil]; + } + return NO; + } + + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + + __block NSError *blockError = nil; + + // OPTIMIZATION: Use DISPATCH_DATA_DESTRUCTOR_DEFAULT to perform a + // single copy into a GCD-managed buffer. No NSData required. + // TODO: edwinwu - Investigate to see if it is worth to make it zero-copy by replacing + // DISPATCH_DATA_DESTRUCTOR_DEFAULT with a custom empty destructor: + // dispatch_data_t dispatchData = dispatch_data_create(bytes, length, nil, ^{ + // // Zero-copy: ownership remains with the caller. + // }); + dispatch_data_t dispatchData = + dispatch_data_create(bytes, length, nil, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + + [self.connection sendData:dispatchData + context:NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT + isComplete:NO + completionHandler:^(nw_error_t _Nullable sendError) { + if (sendError) { + blockError = (__bridge_transfer NSError *)nw_error_copy_cf_error(sendError); + } + dispatch_semaphore_signal(semaphore); + }]; + + // Wait until signaled or the 5-second timeout passes + intptr_t waitResult = dispatch_semaphore_wait( + semaphore, + dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kConnectionWriteTimeout * NSEC_PER_SEC))); + if (error != nil) { + *error = blockError; + } + return (waitResult == 0) && (blockError == nil); +} + - (void)close { [_connection cancel]; _connection = nil; diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCNWFrameworkSocketTest.mm b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCNWFrameworkSocketTest.mm index a7856bd5..bce7847b 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCNWFrameworkSocketTest.mm +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCNWFrameworkSocketTest.mm @@ -132,6 +132,28 @@ NS_ASSUME_NONNULL_BEGIN XCTAssertFalse(result); } +- (void)testWriteBytes_Success { + NSError *error = nil; + NSString *testString = @"testData"; + NSData *testData = [testString dataUsingEncoding:NSUTF8StringEncoding]; + + BOOL result = [_socket writeBytes:testData.bytes length:testData.length error:&error]; + + XCTAssertTrue(result); + XCTAssertNil(error); +} + +- (void)testWriteBytes_Error { + NSError *error = nil; + NSString *testString = @"testData"; + NSData *testData = [testString dataUsingEncoding:NSUTF8StringEncoding]; + _fakeConnection.simulateSendFailure = YES; + + BOOL result = [_socket writeBytes:testData.bytes length:testData.length error:&error]; + + XCTAssertFalse(result); +} + - (void)testClose { XCTAssertFalse(_fakeConnection.cancelCalled); [_socket close]; @@ -140,6 +162,7 @@ NS_ASSUME_NONNULL_BEGIN NSError *error = nil; XCTAssertNil([_socket readMaxLength:10 error:&error]); XCTAssertFalse([_socket write:[NSData data] error:&error]); + XCTAssertFalse([_socket writeBytes:"test" length:4 error:&error]); } @end From a570c9df8faf4464225f81890f46e9925f4c3484 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Sun, 5 Apr 2026 09:16:56 -0700 Subject: [PATCH 042/151] [Nearby] Optimize NWFramework socket reads and writes for performance and memory. IV PiperOrigin-RevId: 894952159 --- .../Tests/GNCFakeNWFrameworkSocket.mm | 11 +++++++ .../apple/Tests/GNCAwdlMediumTest.mm | 33 +++++++++++++++++++ .../apple/Tests/GNCWifiHotspotMediumTest.mm | 27 +++++++++++++++ .../apple/Tests/GNCWifiLanMediumTest.mm | 33 +++++++++++++++++++ .../platform/implementation/apple/awdl.mm | 10 +++++- .../implementation/apple/wifi_hotspot.mm | 10 +++++- .../platform/implementation/apple/wifi_lan.mm | 10 +++++- 7 files changed, 131 insertions(+), 3 deletions(-) diff --git a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.mm b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.mm index cbf9b8c1..38428fb6 100644 --- a/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.mm +++ b/internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.mm @@ -74,6 +74,17 @@ return YES; } +- (BOOL)writeBytes:(const void *)bytes length:(NSUInteger)length error:(NSError **)error { + if (self.writeError) { + if (error) { + *error = self.writeError; + } + return NO; + } + [self.writtenData appendBytes:bytes length:length]; + return YES; +} + - (void)close { self.isClosed = YES; } diff --git a/internal/platform/implementation/apple/Tests/GNCAwdlMediumTest.mm b/internal/platform/implementation/apple/Tests/GNCAwdlMediumTest.mm index 0ba4ba69..6eeec152 100644 --- a/internal/platform/implementation/apple/Tests/GNCAwdlMediumTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCAwdlMediumTest.mm @@ -246,6 +246,39 @@ static const int kTestPort = 1234; XCTAssertTrue(serverSocket->Close().Ok()); } +- (void)testOutputStreamWrite_SingleCopyEnabled { + // Enable the flag. + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + ::nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy, + true); + + // Create a server socket and accept a client. + std::unique_ptr serverSocket = + _awdlMedium->ListenForService(kTestPort); + GNCFakeNWFrameworkServerSocket* fakeServerSocket = + (GNCFakeNWFrameworkServerSocket*)_fakeNWFramework.serverSockets[0]; + GNCFakeNWConnection* connection = [[GNCFakeNWConnection alloc] init]; + GNCFakeNWFrameworkSocket* fakeSocket = + [[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection]; + fakeServerSocket.socketToReturnOnAccept = fakeSocket; + std::unique_ptr clientSocket = serverSocket->Accept(); + XCTAssertTrue(clientSocket != nullptr); + + // Test output stream. + nearby::OutputStream& outputStream = clientSocket->GetOutputStream(); + absl::string_view writeData("optimized write data"); + XCTAssertTrue(outputStream.Write(writeData).Ok()); + XCTAssertEqualObjects(fakeSocket.writtenData, + [@"optimized write data" dataUsingEncoding:NSUTF8StringEncoding]); + + // Clean up. + XCTAssertTrue(clientSocket->Close().Ok()); + XCTAssertTrue(serverSocket->Close().Ok()); + + // Reset the flag. + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); +} + - (void)testOutputStreamClose { // Create a server socket and accept a client. std::unique_ptr serverSocket = diff --git a/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm b/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm index 51a02995..8c2e7803 100644 --- a/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm @@ -154,6 +154,10 @@ const char kIPAddress[] = "192.168.1.2"; } - (void)testOutputStreamWrite { + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + ::nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy, + false); + nearby::CancellationFlag cancellationFlag; std::unique_ptr socket = _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); @@ -165,6 +169,29 @@ const char kIPAddress[] = "192.168.1.2"; XCTAssertTrue(writeResult.Ok()); XCTAssertEqualObjects(fakeSocket.writtenData, data); + + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); +} + +- (void)testOutputStreamWrite_SingleCopyEnabled { + // Enable the flag + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + ::nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy, + true); + + nearby::CancellationFlag cancellationFlag; + std::unique_ptr socket = + _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); + GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject; + NSData *data = [@"TestDataOpt" dataUsingEncoding:NSUTF8StringEncoding]; + absl::string_view data_str(reinterpret_cast(data.bytes), data.length); + + nearby::Exception writeResult = socket->GetOutputStream().Write(data_str); + + XCTAssertTrue(writeResult.Ok()); + XCTAssertEqualObjects(fakeSocket.writtenData, data); + + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); } - (void)testSocketClose { diff --git a/internal/platform/implementation/apple/Tests/GNCWifiLanMediumTest.mm b/internal/platform/implementation/apple/Tests/GNCWifiLanMediumTest.mm index 9e01cfb5..fd633d60 100644 --- a/internal/platform/implementation/apple/Tests/GNCWifiLanMediumTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCWifiLanMediumTest.mm @@ -224,6 +224,39 @@ XCTAssertTrue(serverSocket->Close().Ok()); } +- (void)testOutputStreamWrite_SingleCopyEnabled { + // Enable the flag + nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( + ::nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy, + true); + + // Create a server socket and accept a client. + std::unique_ptr serverSocket = + _wifiLanMedium->ListenForService(1234); + GNCFakeNWFrameworkServerSocket* fakeServerSocket = + (GNCFakeNWFrameworkServerSocket*)_fakeNWFramework.serverSockets[0]; + GNCFakeNWConnection* connection = [[GNCFakeNWConnection alloc] init]; + GNCFakeNWFrameworkSocket* fakeSocket = + [[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection]; + fakeServerSocket.socketToReturnOnAccept = fakeSocket; + + std::unique_ptr clientSocket = serverSocket->Accept(); + nearby::OutputStream& outputStream = clientSocket->GetOutputStream(); + + // Test optimized single-copy write. + absl::string_view writeData("optimized data"); + XCTAssertTrue(outputStream.Write(writeData).Ok()); + XCTAssertEqualObjects(fakeSocket.writtenData, + [@"optimized data" dataUsingEncoding:NSUTF8StringEncoding]); + + // Clean up. + XCTAssertTrue(clientSocket->Close().Ok()); + XCTAssertTrue(serverSocket->Close().Ok()); + + // Reset the flag. + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); +} + - (void)testOutputStreamClose { // Create a server socket and accept a client. std::unique_ptr serverSocket = diff --git a/internal/platform/implementation/apple/awdl.mm b/internal/platform/implementation/apple/awdl.mm index 15eaafb1..8720d1e9 100644 --- a/internal/platform/implementation/apple/awdl.mm +++ b/internal/platform/implementation/apple/awdl.mm @@ -66,7 +66,15 @@ AwdlOutputStream::AwdlOutputStream(GNCNWFrameworkSocket* socket) : socket_(socke Exception AwdlOutputStream::Write(absl::string_view data) { NSError* error = nil; - BOOL result = [socket_ write:[NSData dataWithBytes:data.data() length:data.size()] error:&error]; + BOOL result = NO; + + if (GNCFeatureFlags.singleCopyEnabled) { + // OPTIMIZATION: Write raw bytes directly, avoiding NSData creation. + result = [socket_ writeBytes:data.data() length:data.size() error:&error]; + } else { + result = [socket_ write:[NSData dataWithBytes:data.data() length:data.size()] error:&error]; + } + if (!result) { GNCLoggerError(@"Error writing socket: %@", error); return {Exception::kIo}; diff --git a/internal/platform/implementation/apple/wifi_hotspot.mm b/internal/platform/implementation/apple/wifi_hotspot.mm index 79b08bb5..d2772330 100644 --- a/internal/platform/implementation/apple/wifi_hotspot.mm +++ b/internal/platform/implementation/apple/wifi_hotspot.mm @@ -75,7 +75,15 @@ WifiHotspotOutputStream::WifiHotspotOutputStream(GNCNWFrameworkSocket* socket) : Exception WifiHotspotOutputStream::Write(absl::string_view data) { NSError* error = nil; - BOOL result = [socket_ write:[NSData dataWithBytes:data.data() length:data.size()] error:&error]; + BOOL result = NO; + + if (GNCFeatureFlags.singleCopyEnabled) { + // OPTIMIZATION: Write raw bytes directly, avoiding NSData creation. + result = [socket_ writeBytes:data.data() length:data.size() error:&error]; + } else { + result = [socket_ write:[NSData dataWithBytes:data.data() length:data.size()] error:&error]; + } + if (!result) { GNCLoggerError(@"Error writing socket: %@", error); return {Exception::kIo}; diff --git a/internal/platform/implementation/apple/wifi_lan.mm b/internal/platform/implementation/apple/wifi_lan.mm index 70474b95..984d44de 100644 --- a/internal/platform/implementation/apple/wifi_lan.mm +++ b/internal/platform/implementation/apple/wifi_lan.mm @@ -66,7 +66,15 @@ WifiLanOutputStream::WifiLanOutputStream(GNCNWFrameworkSocket* socket) : socket_ Exception WifiLanOutputStream::Write(absl::string_view data) { NSError* error = nil; - BOOL result = [socket_ write:[NSData dataWithBytes:data.data() length:data.size()] error:&error]; + BOOL result = NO; + + if (GNCFeatureFlags.singleCopyEnabled) { + // OPTIMIZATION: Write raw bytes directly, avoiding NSData creation. + result = [socket_ writeBytes:data.data() length:data.size() error:&error]; + } else { + result = [socket_ write:[NSData dataWithBytes:data.data() length:data.size()] error:&error]; + } + if (!result) { GNCLoggerError(@"Error writing socket: %@", error); return {Exception::kIo}; From cae29fe15adc90a6f9adb34b72d3c907c08a0e3f Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Mon, 6 Apr 2026 20:33:07 -0700 Subject: [PATCH 043/151] The GNCMWaitForConnection utility is updated to allow specifying a target dispatch queue. PiperOrigin-RevId: 895632592 --- .../apple/Mediums/BLE/GNCMBleUtils.h | 6 +++-- .../apple/Mediums/BLE/GNCMBleUtils.mm | 9 ++++--- .../Mediums/BLE/Tests/GNCMBleUtilsTest.m | 25 ++++++++++++++++--- .../implementation/apple/ble_medium.mm | 4 +-- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCMBleUtils.h b/internal/platform/implementation/apple/Mediums/BLE/GNCMBleUtils.h index d5bc59d6..38bba6e2 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCMBleUtils.h +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCMBleUtils.h @@ -90,9 +90,11 @@ NSData *_Nullable GNCMGenerateBLEL2CAPPacket(GNCMBLEL2CAPCommand command, NSData /** * Calls the completion handler with (a) YES if the GNSSocket connected, or (b) NO if it failed to - * connect for any reason. The completion handler is called on the main queue. + * connect for any reason. The completion handler is called on the given queue. If the queue is nil, + * the completion handler is called on the main queue. */ -void GNCMWaitForConnection(GNSSocket *socket, GNCMBoolHandler completion); +void GNCMWaitForConnection(GNSSocket *socket, dispatch_queue_t _Nullable queue, + GNCMBoolHandler completion); #ifdef __cplusplus } // extern "C" diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCMBleUtils.mm b/internal/platform/implementation/apple/Mediums/BLE/GNCMBleUtils.mm index 6c1c518d..c582ff11 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCMBleUtils.mm +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCMBleUtils.mm @@ -235,18 +235,20 @@ NSData *_Nullable GNCMGenerateBLEL2CAPPacket(GNCMBLEL2CAPCommand command, NSData @end -void GNCMWaitForConnection(GNSSocket *socket, GNCMBoolHandler completion) { +void GNCMWaitForConnection(GNSSocket *socket, dispatch_queue_t _Nullable queue, + GNCMBoolHandler completion) { // This function passes YES to the completion when the socket has successfully connected, and // otherwise passes NO to the completion after a timeout of several seconds. We shouldn't retain // the completion after it's been called, so store it in a __block variable and nil it out once // the socket has connected. __block GNCMBoolHandler completionRef = completion; + dispatch_queue_t targetQueue = queue ?: dispatch_get_main_queue(); // The delegate listens for the socket connection callbacks. It's retained by the block passed to // dispatch_after below, so it will live long enough to do its job. GNCMBleSocketDelegate *delegate = [GNCMBleSocketDelegate delegateWithConnectedHandler:^(BOOL didConnect) { - dispatch_async(dispatch_get_main_queue(), ^{ + dispatch_async(targetQueue, ^{ if (completionRef) completionRef(didConnect); completionRef = nil; }); @@ -254,9 +256,10 @@ void GNCMWaitForConnection(GNSSocket *socket, GNCMBoolHandler completion) { socket.delegate = delegate; dispatch_after( dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kBleSocketConnectionTimeout * NSEC_PER_SEC)), - dispatch_get_main_queue(), ^{ + targetQueue, ^{ (void)delegate; // make sure it's retained until the timeout if (completionRef) completionRef(NO); + completionRef = nil; }); } diff --git a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCMBleUtilsTest.m b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCMBleUtilsTest.m index b1c08d95..11ca0c50 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCMBleUtilsTest.m +++ b/internal/platform/implementation/apple/Mediums/BLE/Tests/GNCMBleUtilsTest.m @@ -131,7 +131,7 @@ static const NSTimeInterval kWaitForConnectionTimeout = 6.0; // Allow for the 5 GNCFakeSocket *fakeSocket = [[GNCFakeSocket alloc] init]; XCTestExpectation *expectation = [self expectationWithDescription:@"Connection success"]; - GNCMWaitForConnection((GNSSocket *)fakeSocket, ^(BOOL flag) { + GNCMWaitForConnection((GNSSocket *)fakeSocket, nil, ^(BOOL flag) { XCTAssertTrue(flag); [expectation fulfill]; }); @@ -142,12 +142,31 @@ static const NSTimeInterval kWaitForConnectionTimeout = 6.0; // Allow for the 5 [self waitForExpectationsWithTimeout:kTimeout handler:nil]; } +- (void)testWaitForConnection_CustomQueue { + GNCFakeSocket *fakeSocket = [[GNCFakeSocket alloc] init]; + dispatch_queue_t customQueue = dispatch_queue_create("com.google.nearby.testQueue", DISPATCH_QUEUE_SERIAL); + + XCTestExpectation *expectation = [self expectationWithDescription:@"Connection success on custom queue"]; + GNCMWaitForConnection((GNSSocket *)fakeSocket, customQueue, ^(BOOL flag) { + XCTAssertTrue(flag); + // Verify that we are on the custom queue + const char *label = dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL); + XCTAssertEqual(strcmp(label, "com.google.nearby.testQueue"), 0); + [expectation fulfill]; + }); + + // Simulate the connection callback + [fakeSocket simulateSocketDidConnect]; + + [self waitForExpectationsWithTimeout:kTimeout handler:nil]; +} + - (void)testWaitForConnection_Failure_Disconnect { GNCFakeSocket *fakeSocket = [[GNCFakeSocket alloc] init]; XCTestExpectation *expectation = [self expectationWithDescription:@"Connection failed on disconnect"]; - GNCMWaitForConnection((GNSSocket *)fakeSocket, ^(BOOL flag) { + GNCMWaitForConnection((GNSSocket *)fakeSocket, nil, ^(BOOL flag) { XCTAssertFalse(flag); [expectation fulfill]; }); @@ -164,7 +183,7 @@ static const NSTimeInterval kWaitForConnectionTimeout = 6.0; // Allow for the 5 XCTestExpectation *expectation = [self expectationWithDescription:@"Connection failed on timeout"]; - GNCMWaitForConnection((GNSSocket *)fakeSocket, ^(BOOL flag) { + GNCMWaitForConnection((GNSSocket *)fakeSocket, nil, ^(BOOL flag) { XCTAssertFalse(flag); [expectation fulfill]; }); diff --git a/internal/platform/implementation/apple/ble_medium.mm b/internal/platform/implementation/apple/ble_medium.mm index afefac0b..6a1d676f 100644 --- a/internal/platform/implementation/apple/ble_medium.mm +++ b/internal/platform/implementation/apple/ble_medium.mm @@ -465,7 +465,7 @@ std::unique_ptr BleMedium::OpenServerSocket( initWithBleServiceUUID:[CBUUID UUIDWithString:kWeaveServiceUUID] addPairingCharacteristic:NO shouldAcceptSocketHandler:^BOOL(GNSSocket *socket) { - GNCMWaitForConnection(socket, ^(BOOL didConnect) { + GNCMWaitForConnection(socket, nil, ^(BOOL didConnect) { GNCMBleConnection *connection = [GNCMBleConnection connectionWithSocket:socket // This must be nil as the advertiser even though we @@ -603,7 +603,7 @@ std::unique_ptr BleMedium::Connect( dispatch_semaphore_signal(semaphore); return; } - GNCMWaitForConnection(nssocket, ^(BOOL didConnect) { + GNCMWaitForConnection(nssocket, nil, ^(BOOL didConnect) { if (!didConnect) { dispatch_semaphore_signal(semaphore); return; From 4b5e42ad71a92c2b05820dd30e000658408d5286 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Mon, 6 Apr 2026 20:49:34 -0700 Subject: [PATCH 044/151] Fix potential deadlock and use-after-free in BleServerSocket on Apple. PiperOrigin-RevId: 895638821 --- .../flags/nearby_connections_feature_flags.h | 3 + .../apple/Flags/GNCFeatureFlags.h | 3 + .../apple/Flags/GNCFeatureFlags.mm | 6 + .../apple/Tests/ble_medium_test.mm | 101 +++++++++++++++-- .../implementation/apple/ble_medium.h | 12 ++ .../implementation/apple/ble_medium.mm | 107 +++++++++++++++++- 6 files changed, 222 insertions(+), 10 deletions(-) diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h index f1a6e16a..070062e1 100644 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -114,6 +114,9 @@ constexpr auto kSafeToDisconnectVersion = // Enable/Disable single copy read/write for input/output buffers. constexpr auto kEnableSingleCopy = flags::Flag(kConfigPackage, "45775979", true); +// When true, fix the BleServerSocket deadlock/use-after-free (b/494335036). +constexpr auto kFixBleServerSocketDeadlock = + flags::Flag(kConfigPackage, "45775192", true); } // namespace nearby_connections_feature } // namespace config_package_nearby diff --git a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h index 10d1a7c4..52c59b64 100644 --- a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h +++ b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.h @@ -35,4 +35,7 @@ /** Checks whether single copy read/write is enabled in the Nearby Connections SDK. */ @property(nonatomic, class, readonly) BOOL singleCopyEnabled; +/** Checks whether BLE server socket deadlock is fixed in the Nearby Connections SDK. */ +@property(nonatomic, class, readonly) BOOL fixBleServerSocketDeadlockEnabled; + @end diff --git a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm index 0166e4c4..e00328c3 100644 --- a/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm +++ b/internal/platform/implementation/apple/Flags/GNCFeatureFlags.mm @@ -53,4 +53,10 @@ nearby::connections::config_package_nearby::nearby_connections_feature::kEnableSingleCopy); } ++ (BOOL)fixBleServerSocketDeadlockEnabled { + return nearby::NearbyFlags::GetInstance().GetBoolFlag( + nearby::connections::config_package_nearby::nearby_connections_feature:: + kFixBleServerSocketDeadlock); +} + @end diff --git a/internal/platform/implementation/apple/Tests/ble_medium_test.mm b/internal/platform/implementation/apple/Tests/ble_medium_test.mm index ff4f688a..f8e53d2e 100644 --- a/internal/platform/implementation/apple/Tests/ble_medium_test.mm +++ b/internal/platform/implementation/apple/Tests/ble_medium_test.mm @@ -23,6 +23,7 @@ #include #include +#import "internal/platform/implementation/apple/Flags/GNCFeatureFlags.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEMedium.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheral.h" #import "internal/platform/implementation/apple/Mediums/BLE/Sockets/Source/Central/GNSCentralManager.h" @@ -32,10 +33,11 @@ #import "internal/platform/implementation/apple/Mediums/BLE/Sockets/Source/Shared/GNSSocket.h" #import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEMedium+Testing.h" #import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeBLEGATTServer.h" -#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeCentralManager.h" -#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h" #import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeBLEMedium.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeCentralManager.h" #import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheral.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h" +#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakeSocket.h" #include "internal/platform/implementation/apple/ble_utils.h" #include "internal/platform/implementation/ble.h" #import "third_party/objective_c/ocmock/v3/Source/OCMock/OCMock.h" @@ -51,6 +53,9 @@ class BleMediumPeer { static void SetSocketPeripheralManager(BleMedium *ble_medium, GNSPeripheralManager *manager) { ble_medium->socketPeripheralManager_ = manager; } + static GNSPeripheralServiceManager *GetSocketPeripheralServiceManager(BleMedium *ble_medium) { + return ble_medium->socketPeripheralServiceManager_; + } }; } // namespace apple @@ -74,8 +79,8 @@ static const char *const kTestServiceID = "TestServiceID"; GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init]; GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init]; _fakeGNCBLEMedium = [[GNCFakeBLEMedium alloc] initWithCentralManager:fakeCentralManager - peripheralManager:fakePeripheralManager - queue:dispatch_get_main_queue()]; + peripheralManager:fakePeripheralManager + queue:dispatch_get_main_queue()]; _medium = std::make_unique((GNCBLEMedium *)_fakeGNCBLEMedium); } @@ -229,8 +234,8 @@ static const char *const kTestServiceID = "TestServiceID"; #pragma mark - GATT Server Tests - (void)testStartGattServer_Success { - _fakeGNCBLEMedium.fakeGATTServer = - [[GNCFakeBLEGATTServer alloc] initWithPeripheralManager:nil queue:nil]; + _fakeGNCBLEMedium.fakeGATTServer = [[GNCFakeBLEGATTServer alloc] initWithPeripheralManager:nil + queue:nil]; auto gatt_server = _medium->StartGattServer({}); XCTAssertNotEqual(gatt_server.get(), nullptr); @@ -474,7 +479,10 @@ static const char *const kTestServiceID = "TestServiceID"; #pragma mark - Server Socket Tests -- (void)testOpenServerSocket_Success { +- (void)testOpenServerSocket_Success_LegacyPath { + id mockFeatureFlags = OCMClassMock([GNCFeatureFlags class]); + OCMStub([mockFeatureFlags fixBleServerSocketDeadlockEnabled]).andReturn(NO); + id mockPeripheralManager = OCMClassMock([GNSPeripheralManager class]); OCMStub([mockPeripheralManager addPeripheralServiceManager:[OCMArg any] bleServiceAddedCompletion:[OCMArg any]]) @@ -487,6 +495,85 @@ static const char *const kTestServiceID = "TestServiceID"; auto server_socket = _medium->OpenServerSocket(kTestServiceID); XCTAssertNotEqual(server_socket.get(), nullptr); + + GNSPeripheralServiceManager *serviceManager = + nearby::apple::BleMediumPeer::GetSocketPeripheralServiceManager(_medium.get()); + XCTAssertNotNil(serviceManager); +} + +- (void)testOpenServerSocket_Success_OptimizedPath { + id mockFeatureFlags = OCMClassMock([GNCFeatureFlags class]); + OCMStub([mockFeatureFlags fixBleServerSocketDeadlockEnabled]).andReturn(YES); + + id mockPeripheralManager = OCMClassMock([GNSPeripheralManager class]); + OCMStub([mockPeripheralManager addPeripheralServiceManager:[OCMArg any] + bleServiceAddedCompletion:[OCMArg any]]) + .andDo(^(GNSPeripheralManager *localSelf, GNSPeripheralServiceManager *manager, + void (^completion)(NSError *error)) { + completion(nil); + }); + nearby::apple::BleMediumPeer::SetSocketPeripheralManager(_medium.get(), mockPeripheralManager); + + auto server_socket = _medium->OpenServerSocket(kTestServiceID); + + XCTAssertNotEqual(server_socket.get(), nullptr); + + GNSPeripheralServiceManager *serviceManager = + nearby::apple::BleMediumPeer::GetSocketPeripheralServiceManager(_medium.get()); + XCTAssertNotNil(serviceManager); +} + +- (void)testOpenServerSocket_OptimizedPath_AcceptSocketAfterClose { + id mockFeatureFlags = OCMClassMock([GNCFeatureFlags class]); + OCMStub([mockFeatureFlags fixBleServerSocketDeadlockEnabled]).andReturn(YES); + + id mockPeripheralManager = OCMClassMock([GNSPeripheralManager class]); + OCMStub([mockPeripheralManager addPeripheralServiceManager:[OCMArg any] + bleServiceAddedCompletion:[OCMArg any]]) + .andDo(^(GNSPeripheralManager *localSelf, GNSPeripheralServiceManager *manager, + void (^completion)(NSError *error)) { + completion(nil); + }); + nearby::apple::BleMediumPeer::SetSocketPeripheralManager(_medium.get(), mockPeripheralManager); + + auto server_socket = _medium->OpenServerSocket(kTestServiceID); + XCTAssertNotEqual(server_socket.get(), nullptr); + __block BOOL (^capturedHandler)(GNSSocket *) = nil; + id mockServiceManagerClass = OCMClassMock([GNSPeripheralServiceManager class]); + OCMStub([mockServiceManagerClass alloc]).andReturn(mockServiceManagerClass); + OCMStub([mockServiceManagerClass initWithBleServiceUUID:[OCMArg any] + addPairingCharacteristic:NO + shouldAcceptSocketHandler:[OCMArg any]]) + .andDo(^(NSInvocation *invocation) { + BOOL (^handler)(GNSSocket *); + [invocation getArgument:&handler atIndex:4]; + capturedHandler = handler; + }) + .andReturn(mockServiceManagerClass); + + auto server_socket_for_handler_capture = _medium->OpenServerSocket(kTestServiceID); + XCTAssertNotEqual(server_socket_for_handler_capture.get(), nullptr); + XCTAssertNotNil(capturedHandler); + + // Invoke the shouldAcceptSocketHandler with a fake socket. + GNCFakeSocket *fakeSocket = [[GNCFakeSocket alloc] init]; + BOOL result = capturedHandler((GNSSocket *)fakeSocket); + XCTAssertTrue(result); + + // Close the server_socket. This triggers the close notifier, setting server_socket_ptr_ to null. + server_socket_for_handler_capture->Close(); + + // Now simulate the connection completing. It should safely ignore the connection because + // server_socket_ptr_ is null, preventing use-after-free or deadlocks. + [fakeSocket simulateSocketDidConnect]; + + // Since we use dispatch_async internally for connection callback, give it a small amount of time + // to process so we know it didn't crash. + XCTestExpectation *expectation2 = [self expectationWithDescription:@"Wait for async execution"]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [expectation2 fulfill]; + }); + [self waitForExpectations:@[ expectation2 ] timeout:1.0]; } - (void)testOpenServerSocket_Failure { diff --git a/internal/platform/implementation/apple/ble_medium.h b/internal/platform/implementation/apple/ble_medium.h index 7c052c43..7bbf2856 100644 --- a/internal/platform/implementation/apple/ble_medium.h +++ b/internal/platform/implementation/apple/ble_medium.h @@ -207,6 +207,13 @@ class BleMedium : public api::ble::BleMedium { NSDictionary *service_data); NSDate *GetLastTimestampToCleanExpiredAdvertisementPackets(); + // Opens a BLE server socket based on service ID with deadlock safety. + std::unique_ptr OpenServerSocketWithDeadlockSafety( + const std::string &service_id); + + // Opens a BLE server socket based on service ID using the legacy implementation. + std::unique_ptr OpenServerSocketLegacy(const std::string &service_id); + // The executor for handling callbacks. apple::SingleThreadExecutor callback_executor_; @@ -237,6 +244,11 @@ class BleMedium : public api::ble::BleMedium { // callback. api::ble::BleMedium::ScanningCallback scanning_cb_; + // Used for the BleServerSocket. + absl::Mutex server_socket_mutex_; + BleServerSocket *server_socket_ptr_ ABSL_GUARDED_BY(server_socket_mutex_) = nullptr; + + // Used for the L2CAP server socket. absl::Mutex l2cap_server_socket_mutex_; BleL2capServerSocket *l2cap_server_socket_ptr_ = nullptr; diff --git a/internal/platform/implementation/apple/ble_medium.mm b/internal/platform/implementation/apple/ble_medium.mm index 6a1d676f..27a65563 100644 --- a/internal/platform/implementation/apple/ble_medium.mm +++ b/internal/platform/implementation/apple/ble_medium.mm @@ -448,23 +448,117 @@ std::unique_ptr BleMedium::ConnectToGattServer( // TODO(b/293336684): Old Weave code that need to be deleted once shared Weave is complete. std::unique_ptr BleMedium::OpenServerSocket( const std::string &service_id) { + if (GNCFeatureFlags.fixBleServerSocketDeadlockEnabled) { + return OpenServerSocketWithDeadlockSafety(service_id); + } else { + return OpenServerSocketLegacy(service_id); + } +} + +std::unique_ptr BleMedium::OpenServerSocketWithDeadlockSafety( + const std::string &service_id) { auto server_socket = std::make_unique(); - __block auto server_socket_ptr = server_socket.get(); if (socketPeripheralManager_ == nil) { socketPeripheralManager_ = [[GNSPeripheralManager alloc] initWithAdvertisedName:nil restoreIdentifier:nil]; } - if (socketPeripheralManager_ == nil) { GNCLoggerError(@"Failed to create peripheral manager."); return nullptr; } + // Fix for b/494335036 (Registry + Background Queue) + { + absl::MutexLock lock(server_socket_mutex_); + server_socket_ptr_ = server_socket.get(); + } + server_socket->SetCloseNotifier([this]() { + absl::MutexLock lock(server_socket_mutex_); + server_socket_ptr_ = nullptr; + }); + socketPeripheralServiceManager_ = [[GNSPeripheralServiceManager alloc] initWithBleServiceUUID:[CBUUID UUIDWithString:kWeaveServiceUUID] addPairingCharacteristic:NO shouldAcceptSocketHandler:^BOOL(GNSSocket *socket) { + // Optimized Path: Use background queue and registry validation. + GNCMWaitForConnection(socket, connection_callback_queue_, ^(BOOL didConnect) { + GNCMBleConnection *connection = + [GNCMBleConnection connectionWithSocket:socket + serviceID:nil + expectedIntroPacket:YES + callbackQueue:connection_callback_queue_]; + + auto socket_wrapper = std::make_unique(connection); + socket_wrapper->SetCloseNotifier( + [socketPeripheralManager = socketPeripheralManager_, + serviceUUID = socketPeripheralServiceManager_.serviceUUID]() { + [socketPeripheralManager + removePeripheralServiceManagerForServiceUUID:serviceUUID + bleServiceRemovedCompletion:^(NSError *_Nullable error) { + GNCLoggerInfo(@"BleSocket is removed peripheral manager."); + }]; + }); + + connection.connectionHandlers = socket_wrapper->GetInputStream().GetConnectionHandlers(); + + // Fix: Verify the BleServerSocket still exists before calling Connect(). + // This prevents the use-after-free/deadlock reported in b/494335036. + absl::MutexLock lock(server_socket_mutex_); + if (server_socket_ptr_) { + server_socket_ptr_->Connect(std::move(socket_wrapper)); + GNCLoggerInfo(@"BleServerSocket is created with connection"); + } else { + GNCLoggerWarning(@"BleServerSocket was destroyed; ignoring connection."); + } + }); + return YES; + }]; + + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block NSError *blockError = nil; + [socketPeripheralManager_ addPeripheralServiceManager:socketPeripheralServiceManager_ + bleServiceAddedCompletion:^(NSError *error) { + if (error != nil) { + GNCLoggerError(@"Failed to add Weave service: %@", error); + blockError = error; + } + dispatch_semaphore_signal(semaphore); + }]; + [socketPeripheralManager_ start]; + dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, kApiTimeoutInSeconds * NSEC_PER_SEC); + if (dispatch_semaphore_wait(semaphore, timeout) != 0) { + GNCLoggerError(@"OpenServerSocket operation timed out."); + return nullptr; + } + if (blockError != nil) { + return nullptr; + } + return std::move(server_socket); +} + +std::unique_ptr BleMedium::OpenServerSocketLegacy( + const std::string &service_id) { + auto server_socket = std::make_unique(); + + if (socketPeripheralManager_ == nil) { + socketPeripheralManager_ = [[GNSPeripheralManager alloc] initWithAdvertisedName:nil + restoreIdentifier:nil]; + } + if (socketPeripheralManager_ == nil) { + GNCLoggerError(@"Failed to create peripheral manager."); + return nullptr; + } + + // Raw pointer for closure capture in the legacy path (risks use-after-free). + BleServerSocket *server_socket_ptr = server_socket.get(); + + socketPeripheralServiceManager_ = [[GNSPeripheralServiceManager alloc] + initWithBleServiceUUID:[CBUUID UUIDWithString:kWeaveServiceUUID] + addPairingCharacteristic:NO + shouldAcceptSocketHandler:^BOOL(GNSSocket *socket) { + // Legacy Path: Verbatim copy of original code (blocks Main Thread). GNCMWaitForConnection(socket, nil, ^(BOOL didConnect) { GNCMBleConnection *connection = [GNCMBleConnection connectionWithSocket:socket @@ -603,7 +697,14 @@ std::unique_ptr BleMedium::Connect( dispatch_semaphore_signal(semaphore); return; } - GNCMWaitForConnection(nssocket, nil, ^(BOOL didConnect) { + + // Suggestion: Use the connection callback queue instead of nil + dispatch_queue_t targetQueue = + GNCFeatureFlags.fixBleServerSocketDeadlockEnabled + ? connection_callback_queue_ + : nil; + + GNCMWaitForConnection(nssocket, targetQueue, ^(BOOL didConnect) { if (!didConnect) { dispatch_semaphore_signal(semaphore); return; From 6914be41544ee12e5ad2e8f1d65f72f1a80df752 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 8 Apr 2026 15:15:01 -0700 Subject: [PATCH 045/151] internal changes PiperOrigin-RevId: 896726878 --- sharing/flags/generated/nearby_sharing_feature_flags.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sharing/flags/generated/nearby_sharing_feature_flags.h b/sharing/flags/generated/nearby_sharing_feature_flags.h index 71b1295a..6cead2ee 100755 --- a/sharing/flags/generated/nearby_sharing_feature_flags.h +++ b/sharing/flags/generated/nearby_sharing_feature_flags.h @@ -83,6 +83,9 @@ constexpr auto kUpdateTrack = // Timeout between displays of the conflict banner. constexpr auto kConflictBannerTimeout = flags::Flag(kConfigPackage, "45668886", 604800); +// When true, enables the backup feature. +constexpr auto kEnableBackup = + flags::Flag(kConfigPackage, "45776229", false); // Enable a persistent BETA label. constexpr auto kEnableBetaLabel = flags::Flag(kConfigPackage, "45662570", true); @@ -115,6 +118,7 @@ inline absl::btree_map&> GetBoolFlags() { {45762616, kEnableFileSync}, {45673628, kEnableWifiHotspotForHpRealtekDevices}, {45683539, kUseAlternateServiceUuidForDiscovery}, + {45776229, kEnableBackup}, {45662570, kEnableBetaLabel}, {45661130, kEnableConflictBanner}, {45720206, kEnableFlutterHooks}, From db72ebcaa490d4269c17812b1bfb80b7dbd9afa4 Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 8 Apr 2026 19:51:04 -0700 Subject: [PATCH 046/151] Automated Code Change PiperOrigin-RevId: 896829185 --- internal/crypto/BUILD | 2 -- internal/crypto_cros/BUILD | 2 -- .../platform/implementation/apple/Mediums/BLE/Sockets/BUILD | 6 ------ .../BLE/Sockets/Source/Peripheral/GNSPeripheralManager.m | 2 +- 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/internal/crypto/BUILD b/internal/crypto/BUILD index 68558128..2f96db1a 100644 --- a/internal/crypto/BUILD +++ b/internal/crypto/BUILD @@ -44,8 +44,6 @@ cc_test( srcs = ["ed25519_unittest.cc"], copts = [ "-DUNIT_TEST", - "-Wno-inconsistent-missing-override", - "-Wno-non-virtual-dtor", "-Ithird_party", ], deps = [ diff --git a/internal/crypto_cros/BUILD b/internal/crypto_cros/BUILD index 3f61a913..d1a06ea1 100644 --- a/internal/crypto_cros/BUILD +++ b/internal/crypto_cros/BUILD @@ -99,8 +99,6 @@ cc_test( ], copts = [ "-DUNIT_TEST", - "-Wno-inconsistent-missing-override", - "-Wno-non-virtual-dtor", "-Ithird_party", ], deps = [ diff --git a/internal/platform/implementation/apple/Mediums/BLE/Sockets/BUILD b/internal/platform/implementation/apple/Mediums/BLE/Sockets/BUILD index 97954b96..0146d5a8 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/Sockets/BUILD +++ b/internal/platform/implementation/apple/Mediums/BLE/Sockets/BUILD @@ -30,9 +30,6 @@ objc_library( ]) + [ "Source/GNSCentral.h", ], - copts = [ - "-Wno-enum-compare", # TODO(b/418286948): Remove this when the error is fixed. - ], deps = [ ":Shared", "//internal/platform/implementation/apple/Log:GNCLogger", @@ -51,9 +48,6 @@ objc_library( ]) + [ "Source/GNSPeripheral.h", ], - copts = [ - "-Wno-enum-compare", # TODO(b/418286948): Remove this when the error is fixed. - ], deps = [ ":Shared", "//internal/platform/implementation/apple/Log:GNCLogger", diff --git a/internal/platform/implementation/apple/Mediums/BLE/Sockets/Source/Peripheral/GNSPeripheralManager.m b/internal/platform/implementation/apple/Mediums/BLE/Sockets/Source/Peripheral/GNSPeripheralManager.m index d58d1759..af6e7e8b 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/Sockets/Source/Peripheral/GNSPeripheralManager.m +++ b/internal/platform/implementation/apple/Mediums/BLE/Sockets/Source/Peripheral/GNSPeripheralManager.m @@ -371,7 +371,7 @@ static NSTimeInterval gKBTCrashLoopMaxTimeBetweenResetting = 15.f; } - (void)updateBTCrashLoopHeuristic { - NSAssert(_cbPeripheralManager.state == CBCentralManagerStateResetting, @"Unexpected CB state %@", + NSAssert(_cbPeripheralManager.state == CBManagerStateResetting, @"Unexpected CB state %@", CBManagerStateString(_cbPeripheralManager.state)); NSDate *now = [NSDate date]; if ([now timeIntervalSinceDate:_btCrashLastResettingDate] > From aaa458dd22b5e1d7149e019133637c662cbc6e1a Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 9 Apr 2026 12:47:00 -0700 Subject: [PATCH 047/151] internal PiperOrigin-RevId: 897253283 --- sharing/nearby_sharing_settings.cc | 11 +++++++++ sharing/nearby_sharing_settings.h | 5 ++++ sharing/nearby_sharing_settings_test.cc | 32 +++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/sharing/nearby_sharing_settings.cc b/sharing/nearby_sharing_settings.cc index 8d894727..baf1118e 100644 --- a/sharing/nearby_sharing_settings.cc +++ b/sharing/nearby_sharing_settings.cc @@ -48,6 +48,7 @@ using ::nearby::sharing::api::PreferenceManager; using ::nearby::sharing::proto::DataUsage; using ::nearby::sharing::proto::DeviceVisibility; using ::nearby::sharing::proto::FastInitiationNotificationState; +using ::nearby::sharing::sync::SyncBindingPrefs; constexpr absl::string_view kPreferencesObserverName = "nearby-sharing-settings"; @@ -186,6 +187,16 @@ std::string NearbyShareSettings::GetCustomSavePath() const { PrefNames::kCustomSavePath, device_info_.GetDownloadPath().ToString()); } +SyncBindingPrefs NearbyShareSettings::GetSyncBindingPrefs() const { + return preference_manager_.GetSyncBindingValue().value_or( + SyncBindingPrefs()); +} + +void NearbyShareSettings::SetSyncBindingPrefs( + const SyncBindingPrefs& prefs) { + preference_manager_.SetSyncBindingValue(prefs); +} + bool NearbyShareSettings::IsDisabledByPolicy() const { return false; } void NearbyShareSettings::AddSettingsObserver(Observer* observer) { diff --git a/sharing/nearby_sharing_settings.h b/sharing/nearby_sharing_settings.h index 665d8f97..f0793bae 100644 --- a/sharing/nearby_sharing_settings.h +++ b/sharing/nearby_sharing_settings.h @@ -22,6 +22,7 @@ #include #include +#include "location/nearby/sharing/lib/sync/sync_binding_prefs.pb.h" #include "absl/base/thread_annotations.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" @@ -161,6 +162,10 @@ class NearbyShareSettings std::string GetCustomSavePath() const; + nearby::sharing::sync::SyncBindingPrefs GetSyncBindingPrefs() const; + void SetSyncBindingPrefs( + const nearby::sharing::sync::SyncBindingPrefs& prefs); + // Returns true if the feature is disabled by policy. bool IsDisabledByPolicy() const; diff --git a/sharing/nearby_sharing_settings_test.cc b/sharing/nearby_sharing_settings_test.cc index 531e4ed7..e11e22a1 100644 --- a/sharing/nearby_sharing_settings_test.cc +++ b/sharing/nearby_sharing_settings_test.cc @@ -19,6 +19,8 @@ #include #include +#include "gmock/gmock.h" +#include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/base/thread_annotations.h" #include "absl/strings/string_view.h" @@ -43,6 +45,7 @@ namespace { using ::nearby::sharing::proto::DataUsage; using ::nearby::sharing::proto::DeviceVisibility; using ::nearby::sharing::proto::FastInitiationNotificationState; +using ::protobuf_matchers::EqualsProto; constexpr char kDefaultDeviceName[] = "Josh's Chromebook"; @@ -386,6 +389,35 @@ TEST_F(NearbyShareSettingsTest, SetVisibilityWithExpirationTooLong) { EXPECT_LT(absl::AbsDuration(time_diff), absl::Seconds(1)); } +TEST_F(NearbyShareSettingsTest, GetSyncBindingPrefs_NoBindings) { + EXPECT_THAT(settings()->GetSyncBindingPrefs(), + EqualsProto(sync::SyncBindingPrefs::default_instance())); +} + +TEST_F(NearbyShareSettingsTest, GetSyncBindingPerfs_Success) { + sync::SyncBindingPrefs sync_binding_prefs; + sync_binding_prefs.add_sync_bindings()->set_binding_id("binding_id"); + sync_binding_prefs.add_sync_bindings()->set_source_name("source_name"); + sync_binding_prefs.add_sync_bindings()->set_destination_directory( + "destination_name"); + preference_manager_.SetSyncBindingValue(sync_binding_prefs); + EXPECT_THAT(settings()->GetSyncBindingPrefs(), + EqualsProto(sync_binding_prefs)); +} + +TEST_F(NearbyShareSettingsTest, SetSyncBindingPerfs_Success) { + sync::SyncBindingPrefs sync_binding_prefs; + sync_binding_prefs.add_sync_bindings()->set_binding_id("binding_id"); + sync_binding_prefs.add_sync_bindings()->set_source_name("source_name"); + sync_binding_prefs.add_sync_bindings()->set_destination_directory( + "destination_name"); + settings()->SetSyncBindingPrefs(sync_binding_prefs); + auto sync_binding_value = preference_manager_.GetSyncBindingValue(); + ASSERT_TRUE(sync_binding_value.has_value()); + EXPECT_THAT(sync_binding_value.value(), + EqualsProto(sync_binding_prefs)); +} + TEST(NearbyShareVisibilityTest, RestoresFallbackVisibility_ExpiredTimer) { // Create Nearby Share settings dependencies. FakeContext context; From 0ab62e579e5c15d6e094d1141bae0372203247e0 Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 9 Apr 2026 13:24:09 -0700 Subject: [PATCH 048/151] Automated Code Change PiperOrigin-RevId: 897272170 --- .../ble/discovered_peripheral_tracker.cc | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/connections/implementation/mediums/ble/discovered_peripheral_tracker.cc b/connections/implementation/mediums/ble/discovered_peripheral_tracker.cc index 4eda44c6..6639dd4a 100644 --- a/connections/implementation/mediums/ble/discovered_peripheral_tracker.cc +++ b/connections/implementation/mediums/ble/discovered_peripheral_tracker.cc @@ -247,20 +247,11 @@ bool DiscoveredPeripheralTracker::HandleOnLostAdvertisementLocked( BlePeripheral lost_peripheral = it.second.peripheral; lost_peripheral.SetId(ByteArray(gatt_advertisement)); if (gatt_advertisement.IsValid()) { - if (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableScanningForInstantOnLost)) { - AddInstantLostAdvertisement(it.second.advertisement_header); - discovery_cb_it->second.discovered_peripheral_callback - .instant_lost_cb(lost_peripheral, it.second.service_id, - gatt_advertisement.GetData(), - gatt_advertisement.IsFastAdvertisement()); - } else { - discovery_cb_it->second.discovered_peripheral_callback - .peripheral_lost_cb(lost_peripheral, it.second.service_id, - gatt_advertisement.GetData(), - gatt_advertisement.IsFastAdvertisement()); - } + AddInstantLostAdvertisement(it.second.advertisement_header); + discovery_cb_it->second.discovered_peripheral_callback + .instant_lost_cb(lost_peripheral, it.second.service_id, + gatt_advertisement.GetData(), + gatt_advertisement.IsFastAdvertisement()); LOG(INFO) << __func__ << ": OnLost triggered for service_id " << it.second.service_id; } From ef166b65342083ef16669a91248e69d6306a3785 Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 9 Apr 2026 18:57:12 -0700 Subject: [PATCH 049/151] [TTX] Include a bit to indicate the TTX PiperOrigin-RevId: 897415417 --- sharing/proto/wire_format.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/sharing/proto/wire_format.proto b/sharing/proto/wire_format.proto index 57ec2660..b0db8294 100644 --- a/sharing/proto/wire_format.proto +++ b/sharing/proto/wire_format.proto @@ -219,6 +219,7 @@ message IntroductionFrame { UNKNOWN = 0; NEARBY_SHARE = 1; REMOTE_COPY = 2; + TAP_TO_SHARE = 9; } repeated FileMetadata file_metadata = 1; From 26efd91ff4c2c36b5f9691ffd88342a9f517111b Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Thu, 9 Apr 2026 22:52:26 -0700 Subject: [PATCH 050/151] Introduce factory patterns for BLE managers in BleMedium. PiperOrigin-RevId: 897492346 --- .../apple/Tests/ble_medium_test.mm | 67 +++++++++++++++---- .../implementation/apple/ble_medium.h | 9 +++ .../implementation/apple/ble_medium.mm | 42 +++++++----- 3 files changed, 89 insertions(+), 29 deletions(-) diff --git a/internal/platform/implementation/apple/Tests/ble_medium_test.mm b/internal/platform/implementation/apple/Tests/ble_medium_test.mm index f8e53d2e..491ee93f 100644 --- a/internal/platform/implementation/apple/Tests/ble_medium_test.mm +++ b/internal/platform/implementation/apple/Tests/ble_medium_test.mm @@ -47,11 +47,13 @@ namespace apple { class BleMediumPeer { public: - static void SetSocketCentralManager(BleMedium *ble_medium, GNSCentralManager *manager) { - ble_medium->socketCentralManager_ = manager; + static void SetPeripheralManagerFactory(BleMedium *ble_medium, + BleMedium::PeripheralManagerFactory factory) { + ble_medium->peripheral_manager_factory_ = std::move(factory); } - static void SetSocketPeripheralManager(BleMedium *ble_medium, GNSPeripheralManager *manager) { - ble_medium->socketPeripheralManager_ = manager; + static void SetCentralManagerFactory(BleMedium *ble_medium, + BleMedium::CentralManagerFactory factory) { + ble_medium->central_manager_factory_ = std::move(factory); } static GNSPeripheralServiceManager *GetSocketPeripheralServiceManager(BleMedium *ble_medium) { return ble_medium->socketPeripheralServiceManager_; @@ -88,6 +90,28 @@ static const char *const kTestServiceID = "TestServiceID"; [super tearDown]; } +- (void)testOpenServerSocket_UsesFactoryForInitialization { + __block BOOL factoryWasCalled = NO; + id mockPeripheralManager = OCMClassMock([GNSPeripheralManager class]); + OCMStub([mockPeripheralManager addPeripheralServiceManager:[OCMArg any] + bleServiceAddedCompletion:[OCMArg any]]) + .andDo(^(GNSPeripheralManager *localSelf, GNSPeripheralServiceManager *manager, + void (^completion)(NSError *error)) { + completion(nil); + }); + + nearby::apple::BleMediumPeer::SetPeripheralManagerFactory(_medium.get(), ^() { + factoryWasCalled = YES; + return mockPeripheralManager; + }); + + // This call should trigger the factory inside BleMedium. + auto server_socket = _medium->OpenServerSocket(kTestServiceID); + + XCTAssertTrue(factoryWasCalled, @"BleMedium should have requested the manager from the factory."); + XCTAssertNotEqual(server_socket.get(), nullptr); +} + #pragma mark - Advertising Tests - (void)testStartAdvertising_Success { @@ -431,7 +455,9 @@ static const char *const kTestServiceID = "TestServiceID"; id mockCentralManager = OCMClassMock([GNSCentralManager class]); OCMStub([mockCentralManager retrieveCentralPeerWithIdentifier:fakePeripheral.identifier]) .andReturn(nil); - nearby::apple::BleMediumPeer::SetSocketCentralManager(_medium.get(), mockCentralManager); + nearby::apple::BleMediumPeer::SetCentralManagerFactory(_medium.get(), ^(CBUUID *uuid) { + return mockCentralManager; + }); auto socket = _medium->Connect(kTestServiceID, nearby::api::ble::TxPowerLevel::kUltraLow, fakePeripheral.identifier.hash, nullptr); @@ -469,7 +495,9 @@ static const char *const kTestServiceID = "TestServiceID"; id mockCentralManager = OCMClassMock([GNSCentralManager class]); OCMStub([mockCentralManager retrieveCentralPeerWithIdentifier:fakePeripheral.identifier]) .andReturn(mockCentralPeerManager); - nearby::apple::BleMediumPeer::SetSocketCentralManager(_medium.get(), mockCentralManager); + nearby::apple::BleMediumPeer::SetCentralManagerFactory(_medium.get(), ^(CBUUID *uuid) { + return mockCentralManager; + }); auto socket = _medium->Connect(kTestServiceID, nearby::api::ble::TxPowerLevel::kUltraLow, fakePeripheral.identifier.hash, nullptr); @@ -490,7 +518,9 @@ static const char *const kTestServiceID = "TestServiceID"; void (^completion)(NSError *error)) { completion(nil); }); - nearby::apple::BleMediumPeer::SetSocketPeripheralManager(_medium.get(), mockPeripheralManager); + nearby::apple::BleMediumPeer::SetPeripheralManagerFactory(_medium.get(), ^() { + return mockPeripheralManager; + }); auto server_socket = _medium->OpenServerSocket(kTestServiceID); @@ -512,7 +542,9 @@ static const char *const kTestServiceID = "TestServiceID"; void (^completion)(NSError *error)) { completion(nil); }); - nearby::apple::BleMediumPeer::SetSocketPeripheralManager(_medium.get(), mockPeripheralManager); + nearby::apple::BleMediumPeer::SetPeripheralManagerFactory(_medium.get(), ^() { + return mockPeripheralManager; + }); auto server_socket = _medium->OpenServerSocket(kTestServiceID); @@ -534,7 +566,9 @@ static const char *const kTestServiceID = "TestServiceID"; void (^completion)(NSError *error)) { completion(nil); }); - nearby::apple::BleMediumPeer::SetSocketPeripheralManager(_medium.get(), mockPeripheralManager); + nearby::apple::BleMediumPeer::SetPeripheralManagerFactory(_medium.get(), ^() { + return mockPeripheralManager; + }); auto server_socket = _medium->OpenServerSocket(kTestServiceID); XCTAssertNotEqual(server_socket.get(), nullptr); @@ -570,9 +604,10 @@ static const char *const kTestServiceID = "TestServiceID"; // Since we use dispatch_async internally for connection callback, give it a small amount of time // to process so we know it didn't crash. XCTestExpectation *expectation2 = [self expectationWithDescription:@"Wait for async execution"]; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [expectation2 fulfill]; - }); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + [expectation2 fulfill]; + }); [self waitForExpectations:@[ expectation2 ] timeout:1.0]; } @@ -584,7 +619,9 @@ static const char *const kTestServiceID = "TestServiceID"; void (^completion)(NSError *error)) { completion([NSError errorWithDomain:@"test" code:0 userInfo:nil]); }); - nearby::apple::BleMediumPeer::SetSocketPeripheralManager(_medium.get(), mockPeripheralManager); + nearby::apple::BleMediumPeer::SetPeripheralManagerFactory(_medium.get(), ^() { + return mockPeripheralManager; + }); auto server_socket = _medium->OpenServerSocket(kTestServiceID); @@ -599,7 +636,9 @@ static const char *const kTestServiceID = "TestServiceID"; void (^completion)(NSError *error)){ // Do not call completion to simulate timeout. }); - nearby::apple::BleMediumPeer::SetSocketPeripheralManager(_medium.get(), mockPeripheralManager); + nearby::apple::BleMediumPeer::SetPeripheralManagerFactory(_medium.get(), ^() { + return mockPeripheralManager; + }); auto server_socket = _medium->OpenServerSocket(kTestServiceID); diff --git a/internal/platform/implementation/apple/ble_medium.h b/internal/platform/implementation/apple/ble_medium.h index 7bbf2856..28438113 100644 --- a/internal/platform/implementation/apple/ble_medium.h +++ b/internal/platform/implementation/apple/ble_medium.h @@ -21,6 +21,7 @@ #import +#include #include #include #include @@ -50,6 +51,10 @@ class BleMedium : public api::ble::BleMedium { friend class BleMediumPeer; public: + // Define factory types for managers. + using PeripheralManagerFactory = std::function; + using CentralManagerFactory = std::function; + BleMedium(); // For testing only. explicit BleMedium(GNCBLEMedium *medium); @@ -217,6 +222,10 @@ class BleMedium : public api::ble::BleMedium { // The executor for handling callbacks. apple::SingleThreadExecutor callback_executor_; + // Factories for lazy initialization + PeripheralManagerFactory peripheral_manager_factory_ = nullptr; + CentralManagerFactory central_manager_factory_ = nullptr; + GNCBLEMedium *medium_; PeripheralsMap peripherals_; diff --git a/internal/platform/implementation/apple/ble_medium.mm b/internal/platform/implementation/apple/ble_medium.mm index 27a65563..dcb1d19f 100644 --- a/internal/platform/implementation/apple/ble_medium.mm +++ b/internal/platform/implementation/apple/ble_medium.mm @@ -193,7 +193,11 @@ std::unique_ptr BleMedium::StartScanning( peripherals_.Clear(); ClearAdvertisementPacketsMap(); - socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUID]; + if (central_manager_factory_) { + socketCentralManager_ = central_manager_factory_(serviceUUID); + } else { + socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUID]; + } [socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUID ]]; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); @@ -247,7 +251,11 @@ bool BleMedium::StartScanning(const Uuid &service_uuid, api::ble::TxPowerLevel t peripherals_.Clear(); ClearAdvertisementPacketsMap(); - socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUID]; + if (central_manager_factory_) { + socketCentralManager_ = central_manager_factory_(serviceUUID); + } else { + socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUID]; + } [socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUID ]]; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); @@ -294,7 +302,11 @@ bool BleMedium::StartMultipleServicesScanning(const std::vector &service_u peripherals_.Clear(); ClearAdvertisementPacketsMap(); - socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUIDs[0]]; + if (central_manager_factory_) { + socketCentralManager_ = central_manager_factory_(serviceUUIDs[0]); + } else { + socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUIDs[0]]; + } [socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUIDs[0] ]]; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); @@ -460,12 +472,12 @@ std::unique_ptr BleMedium::OpenServerSocketWithDeadlo auto server_socket = std::make_unique(); if (socketPeripheralManager_ == nil) { - socketPeripheralManager_ = [[GNSPeripheralManager alloc] initWithAdvertisedName:nil - restoreIdentifier:nil]; - } - if (socketPeripheralManager_ == nil) { - GNCLoggerError(@"Failed to create peripheral manager."); - return nullptr; + if (peripheral_manager_factory_) { + socketPeripheralManager_ = peripheral_manager_factory_(); + } else { + socketPeripheralManager_ = [[GNSPeripheralManager alloc] initWithAdvertisedName:nil + restoreIdentifier:nil]; + } } // Fix for b/494335036 (Registry + Background Queue) @@ -543,12 +555,12 @@ std::unique_ptr BleMedium::OpenServerSocketLegacy( auto server_socket = std::make_unique(); if (socketPeripheralManager_ == nil) { - socketPeripheralManager_ = [[GNSPeripheralManager alloc] initWithAdvertisedName:nil - restoreIdentifier:nil]; - } - if (socketPeripheralManager_ == nil) { - GNCLoggerError(@"Failed to create peripheral manager."); - return nullptr; + if (peripheral_manager_factory_) { + socketPeripheralManager_ = peripheral_manager_factory_(); + } else { + socketPeripheralManager_ = [[GNSPeripheralManager alloc] initWithAdvertisedName:nil + restoreIdentifier:nil]; + } } // Raw pointer for closure capture in the legacy path (risks use-after-free). From bd66643160d45007f8050978de33a89531f97bb6 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Fri, 10 Apr 2026 09:57:45 -0700 Subject: [PATCH 051/151] Implement single-copy optimizations for BLE/L2CAP sockets. PiperOrigin-RevId: 897745906 --- .../implementation/apple/ble_l2cap_socket.mm | 109 +++++++++++---- .../implementation/apple/ble_socket.mm | 129 +++++++++++++----- 2 files changed, 175 insertions(+), 63 deletions(-) diff --git a/internal/platform/implementation/apple/ble_l2cap_socket.mm b/internal/platform/implementation/apple/ble_l2cap_socket.mm index e44c6728..3cf2f2a3 100644 --- a/internal/platform/implementation/apple/ble_l2cap_socket.mm +++ b/internal/platform/implementation/apple/ble_l2cap_socket.mm @@ -14,9 +14,11 @@ #import "internal/platform/implementation/apple/ble_l2cap_socket.h" +#import "internal/platform/implementation/apple/Flags/GNCFeatureFlags.h" #import "internal/platform/implementation/apple/Log/GNCLogger.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPConnection.h" #import "internal/platform/implementation/apple/utils.h" + #include "internal/platform/implementation/ble.h" namespace nearby { @@ -52,40 +54,81 @@ BleL2capInputStream::~BleL2capInputStream() { } ExceptionOr BleL2capInputStream::Read(std::int64_t size) { - // Block until either (a) the connection has been closed, (b) we have enough data to return. - NSData *dataToReturn; - [condition_ lock]; - while (true) { - // Check if the stream has been closed or severed. - if (!newDataPackets_) break; + if (GNCFeatureFlags.singleCopyEnabled) { + std::string dataToReturn; + bool success = false; - if (newDataPackets_.count > 0) { - // Add the packet data to the accumulated data. - for (NSData *data in newDataPackets_) { - if (data.length > 0) { - [accumulatedData_ appendData:data]; + [condition_ lock]; + while (true) { + // Check if the stream has been closed or severed. + if (!newDataPackets_) break; + + if (newDataPackets_.count > 0) { + // Add the packet data to the accumulated data. + for (NSData *data in newDataPackets_) { + if (data.length > 0) { + [accumulatedData_ appendData:data]; + } } + [newDataPackets_ removeAllObjects]; } - [newDataPackets_ removeAllObjects]; + + if (accumulatedData_.length > 0) { + std::int64_t sizeToReturn = + (accumulatedData_.length < size) ? accumulatedData_.length : size; + NSRange range = NSMakeRange(0, (NSUInteger)sizeToReturn); + + // Copy bytes directly into std::string, avoiding [NSData subdataWithRange:] + dataToReturn.assign((const char *)accumulatedData_.bytes, sizeToReturn); + [accumulatedData_ replaceBytesInRange:range withBytes:nil length:0]; + + success = true; + break; + } + [condition_ wait]; } + [condition_ unlock]; - if (accumulatedData_.length > 0) { - // Return up to |size| bytes of the data. - std::int64_t sizeToReturn = (accumulatedData_.length < size) ? accumulatedData_.length : size; - NSRange range = NSMakeRange(0, (NSUInteger)sizeToReturn); - dataToReturn = [accumulatedData_ subdataWithRange:range]; - [accumulatedData_ replaceBytesInRange:range withBytes:nil length:0]; - break; + if (success) { + // OPTIMIZATION: Zero-copy transfer from std::string to ByteArray + return ExceptionOr{ByteArray(std::move(dataToReturn))}; + } else { + return ExceptionOr{Exception::kIo}; } - - [condition_ wait]; - } - [condition_ unlock]; - - if (dataToReturn) { - return ExceptionOr{ByteArray((const char *)dataToReturn.bytes, dataToReturn.length)}; } else { - return ExceptionOr{Exception::kIo}; + // Legacy Path + NSData *dataToReturn; + [condition_ lock]; + while (true) { + if (!newDataPackets_) break; + + if (newDataPackets_.count > 0) { + for (NSData *data in newDataPackets_) { + if (data.length > 0) { + [accumulatedData_ appendData:data]; + } + } + [newDataPackets_ removeAllObjects]; + } + + if (accumulatedData_.length > 0) { + std::int64_t sizeToReturn = + (accumulatedData_.length < size) ? accumulatedData_.length : size; + NSRange range = NSMakeRange(0, (NSUInteger)sizeToReturn); + dataToReturn = [accumulatedData_ subdataWithRange:range]; + [accumulatedData_ replaceBytesInRange:range withBytes:nil length:0]; + break; + } + [condition_ wait]; + } + [condition_ unlock]; + + if (dataToReturn) { + return ExceptionOr{ + ByteArray((const char *)dataToReturn.bytes, dataToReturn.length)}; + } else { + return ExceptionOr{Exception::kIo}; + } } } @@ -111,7 +154,17 @@ Exception BleL2capOutputStream::Write(absl::string_view data) { return {Exception::kIo}; } - NSMutableData *packet = [NSMutableData dataWithBytes:data.data() length:data.size()]; + NSData *packet; + if (GNCFeatureFlags.singleCopyEnabled) { + // OPTIMIZATION: Use DISPATCH_DATA_DESTRUCTOR_DEFAULT to perform a + // single copy into a GCD-managed buffer. No NSData required. + dispatch_data_t dispatchData = + dispatch_data_create(data.data(), data.size(), nil, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + // dispatch_data_t is toll-free bridged to NSData + packet = (NSData *)dispatchData; + } else { + packet = [NSMutableData dataWithBytes:data.data() length:data.size()]; + } // Send the data, blocking until the completion handler is called. __block BOOL isComplete = NO; diff --git a/internal/platform/implementation/apple/ble_socket.mm b/internal/platform/implementation/apple/ble_socket.mm index e34eb9e1..3ea6daf2 100644 --- a/internal/platform/implementation/apple/ble_socket.mm +++ b/internal/platform/implementation/apple/ble_socket.mm @@ -14,13 +14,13 @@ #import "internal/platform/implementation/apple/ble_socket.h" -#include "internal/platform/implementation/ble.h" - +#import "internal/platform/implementation/apple/Flags/GNCFeatureFlags.h" #import "internal/platform/implementation/apple/Mediums/BLE/GNCMBleConnection.h" #import "internal/platform/implementation/apple/ble_peripheral.h" #import "internal/platform/implementation/apple/ble_utils.h" #import "internal/platform/implementation/apple/utils.h" +#include "internal/platform/implementation/ble.h" // TODO(b/293336684): Remove this file when shared Weave is complete. namespace nearby { @@ -55,45 +55,94 @@ BleInputStream::~BleInputStream() { } ExceptionOr BleInputStream::Read(std::int64_t size) { - // Block until either (a) the connection has been closed, (b) we have enough data to return. - NSData *dataToReturn; - [condition_ lock]; - while (true) { - // Check if the stream has been closed or severed. - if (!newDataPackets_) break; + if (GNCFeatureFlags.singleCopyEnabled) { + std::string dataToReturn; + bool success = false; - if (newDataPackets_.count > 0) { - // Add the packet data to the accumulated data. - for (NSData *data in newDataPackets_) { - if (data.length > 0) { - [accumulatedData_ appendData:data]; + [condition_ lock]; + while (true) { + // Check if the stream has been closed or severed. + if (!newDataPackets_) break; + + if (newDataPackets_.count > 0) { + // Add the packet data to the accumulated data. + for (NSData *data in newDataPackets_) { + if (data.length > 0) { + [accumulatedData_ appendData:data]; + } } + [newDataPackets_ removeAllObjects]; } - [newDataPackets_ removeAllObjects]; + + if ((size == -1) && (accumulatedData_.length > 0)) { + // Return all of the data. + dataToReturn.assign((const char *)accumulatedData_.bytes, accumulatedData_.length); + accumulatedData_ = [NSMutableData data]; + success = true; + break; + } else if (accumulatedData_.length > 0) { + // Return up to |size| bytes of the data. + std::int64_t sizeToReturn = + (accumulatedData_.length < size) ? accumulatedData_.length : size; + NSRange range = NSMakeRange(0, (NSUInteger)sizeToReturn); + // Copy bytes directly into std::string, avoiding [NSData subdataWithRange:] + dataToReturn.assign((const char *)accumulatedData_.bytes, sizeToReturn); + [accumulatedData_ replaceBytesInRange:range withBytes:nil length:0]; + success = true; + break; + } + + [condition_ wait]; } + [condition_ unlock]; - if ((size == -1) && (accumulatedData_.length > 0)) { - // Return all of the data. - dataToReturn = accumulatedData_; - accumulatedData_ = [NSMutableData data]; - break; - } else if (accumulatedData_.length > 0) { - // Return up to |size| bytes of the data. - std::int64_t sizeToReturn = (accumulatedData_.length < size) ? accumulatedData_.length : size; - NSRange range = NSMakeRange(0, (NSUInteger)sizeToReturn); - dataToReturn = [accumulatedData_ subdataWithRange:range]; - [accumulatedData_ replaceBytesInRange:range withBytes:nil length:0]; - break; + if (success) { + // OPTIMIZATION: Zero-copy transfer from std::string to ByteArray + return ExceptionOr{ByteArray(std::move(dataToReturn))}; + } else { + return ExceptionOr{Exception::kIo}; } - - [condition_ wait]; - } - [condition_ unlock]; - - if (dataToReturn) { - return ExceptionOr(ByteArrayFromNSData(dataToReturn)); } else { - return ExceptionOr{Exception::kIo}; + // Legacy path + NSData *dataToReturn; + [condition_ lock]; + while (true) { + // Check if the stream has been closed or severed. + if (!newDataPackets_) break; + + if (newDataPackets_.count > 0) { + for (NSData *data in newDataPackets_) { + if (data.length > 0) { + [accumulatedData_ appendData:data]; + } + } + [newDataPackets_ removeAllObjects]; + } + + if ((size == -1) && (accumulatedData_.length > 0)) { + // Return all of the data. + dataToReturn = accumulatedData_; + accumulatedData_ = [NSMutableData data]; + break; + } else if (accumulatedData_.length > 0) { + // Return up to |size| bytes of the data. + std::int64_t sizeToReturn = + (accumulatedData_.length < size) ? accumulatedData_.length : size; + NSRange range = NSMakeRange(0, (NSUInteger)sizeToReturn); + dataToReturn = [accumulatedData_ subdataWithRange:range]; + [accumulatedData_ replaceBytesInRange:range withBytes:nil length:0]; + break; + } + + [condition_ wait]; + } + [condition_ unlock]; + + if (dataToReturn) { + return ExceptionOr(ByteArrayFromNSData(dataToReturn)); + } else { + return ExceptionOr{Exception::kIo}; + } } } @@ -119,7 +168,17 @@ Exception BleOutputStream::Write(absl::string_view data) { return {Exception::kIo}; } - NSMutableData *packet = [NSMutableData dataWithBytes:data.data() length:data.size()]; + NSData *packet; + if (GNCFeatureFlags.singleCopyEnabled) { + // OPTIMIZATION: Use DISPATCH_DATA_DESTRUCTOR_DEFAULT to perform a + // single copy into a GCD-managed buffer. No NSData required. + dispatch_data_t dispatchData = + dispatch_data_create(data.data(), data.size(), nil, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + // dispatch_data_t is toll-free bridged to NSData + packet = (NSData *)dispatchData; + } else { + packet = [NSMutableData dataWithBytes:data.data() length:data.size()]; + } // Send the data, blocking until the completion handler is called. __block bool isComplete = NO; From c90e273160b12cad8b9171065cc5af18de21e678 Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 16 Apr 2026 09:56:11 -0700 Subject: [PATCH 052/151] Automated Code Change PiperOrigin-RevId: 900780016 --- internal/platform/exception.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/platform/exception.h b/internal/platform/exception.h index 08345971..07dbfaac 100644 --- a/internal/platform/exception.h +++ b/internal/platform/exception.h @@ -15,6 +15,7 @@ #ifndef PLATFORM_BASE_EXCEPTION_H_ #define PLATFORM_BASE_EXCEPTION_H_ +#include #include #include "absl/meta/type_traits.h" @@ -82,7 +83,7 @@ class ExceptionOr { ExceptionOr(Exception exception) : exception_{exception} {} // NOLINT // If there exists explicit conversion from U to T, // then allow explicit conversion from ExceptionOr to ExceptionOr. - template ()})>> + template ()})>> explicit ExceptionOr(ExceptionOr value) { if (!value.ok()) { exception_ = value.GetException(); From dacbd03aa18bd78423179230288da756051b816c Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 16 Apr 2026 13:51:03 -0700 Subject: [PATCH 053/151] Replace ByteArray with std::string. PiperOrigin-RevId: 900893850 --- .../implementation/awdl_bwu_handler.cc | 2 +- connections/implementation/awdl_bwu_handler.h | 3 +- .../implementation/awdl_bwu_handler_test.cc | 19 +- .../implementation/base_bwu_handler.cc | 7 +- connections/implementation/base_bwu_handler.h | 5 +- .../implementation/base_bwu_handler_test.cc | 21 ++- .../implementation/base_endpoint_channel.cc | 6 +- .../implementation/base_endpoint_channel.h | 2 +- .../base_endpoint_channel_test.cc | 33 ++-- .../implementation/base_pcp_handler.cc | 4 +- .../implementation/base_pcp_handler_test.cc | 151 ++++++++-------- .../implementation/bluetooth_bwu_handler.cc | 3 +- .../implementation/bluetooth_bwu_handler.h | 3 +- .../implementation/bluetooth_bwu_test.cc | 6 +- connections/implementation/bwu_handler.h | 3 +- connections/implementation/bwu_manager.cc | 9 +- .../implementation/bwu_manager_test.cc | 4 +- .../connections_authentication_transport.cc | 3 +- ...nnections_authentication_transport_test.cc | 6 +- .../implementation/encryption_runner.cc | 14 +- .../implementation/encryption_runner_test.cc | 7 +- connections/implementation/endpoint_channel.h | 2 +- .../endpoint_channel_manager_test.cc | 4 +- .../implementation/endpoint_manager.cc | 15 +- connections/implementation/endpoint_manager.h | 4 +- .../implementation/endpoint_manager_test.cc | 15 +- connections/implementation/fake_bwu_handler.h | 8 +- .../implementation/fake_endpoint_channel.h | 2 +- connections/implementation/fuzzers/BUILD | 3 +- .../fuzzers/offline_frames_fuzzer.cc | 6 +- .../multiplex/multiplex_socket_test.cc | 4 +- connections/implementation/offline_frames.cc | 101 +++++------ connections/implementation/offline_frames.h | 48 ++--- .../implementation/offline_frames_test.cc | 89 ++++----- .../offline_frames_validator_test.cc | 170 +++++++++--------- .../implementation/payload_manager_test.cc | 4 +- .../implementation/webrtc_bwu_handler.cc | 3 +- .../implementation/webrtc_bwu_handler.h | 3 +- .../implementation/webrtc_bwu_handler_stub.cc | 2 +- .../implementation/webrtc_bwu_handler_stub.h | 2 +- .../implementation/wifi_direct_bwu_handler.cc | 3 +- .../implementation/wifi_direct_bwu_handler.h | 3 +- .../implementation/wifi_direct_bwu_test.cc | 5 +- .../wifi_hotspot_bwu_handler.cc | 3 +- .../implementation/wifi_hotspot_bwu_handler.h | 3 +- .../implementation/wifi_hotspot_bwu_test.cc | 5 +- .../implementation/wifi_lan_bwu_handler.cc | 3 +- .../implementation/wifi_lan_bwu_handler.h | 3 +- .../wifi_lan_bwu_handler_test.cc | 7 +- 49 files changed, 391 insertions(+), 440 deletions(-) diff --git a/connections/implementation/awdl_bwu_handler.cc b/connections/implementation/awdl_bwu_handler.cc index 45baead2..da96bc0c 100644 --- a/connections/implementation/awdl_bwu_handler.cc +++ b/connections/implementation/awdl_bwu_handler.cc @@ -185,7 +185,7 @@ AwdlBwuHandler::CreateUpgradedEndpointChannel( // Called by BWU initiator. Set up AWDL upgraded medium for this endpoint, // and returns a upgrade path info (service_name, port) for remote party to // perform discovery. -ByteArray AwdlBwuHandler::HandleInitializeUpgradedMediumForEndpoint( +std::string AwdlBwuHandler::HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) { if (!awdl_medium_.IsAcceptingConnections(upgrade_service_id)) { diff --git a/connections/implementation/awdl_bwu_handler.h b/connections/implementation/awdl_bwu_handler.h index 25e921ec..1a42a844 100644 --- a/connections/implementation/awdl_bwu_handler.h +++ b/connections/implementation/awdl_bwu_handler.h @@ -26,7 +26,6 @@ #include "connections/implementation/mediums/awdl.h" #include "connections/implementation/mediums/mediums.h" #include "internal/platform/awdl.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" #include "internal/platform/nsd_service_info.h" @@ -68,7 +67,7 @@ class AwdlBwuHandler : public BaseBwuHandler { const std::string& endpoint_id) final {} // BaseBwuHandler implementation: - ByteArray HandleInitializeUpgradedMediumForEndpoint( + std::string HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) final; void HandleRevertInitiatorStateForService( diff --git a/connections/implementation/awdl_bwu_handler_test.cc b/connections/implementation/awdl_bwu_handler_test.cc index 627a7af6..3fdba73a 100644 --- a/connections/implementation/awdl_bwu_handler_test.cc +++ b/connections/implementation/awdl_bwu_handler_test.cc @@ -35,7 +35,6 @@ #include "internal/analytics/mock_event_logger.h" #include "internal/analytics/sharing_log_matchers.h" #include "internal/platform/awdl.h" -#include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" @@ -211,10 +210,10 @@ TEST_F(AwdlBwuHandlerTest, EXPECT_CALL(*awdl_medium_mock, ListenForService(_, 0)) .WillOnce(Return(ByMove(nullptr))); - ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( + std::string result = handler_.InitializeUpgradedMediumForEndpoint( &client, std::string(kServiceId), std::string(kEndpointId)); - EXPECT_TRUE(result.Empty()); + EXPECT_TRUE(result.empty()); MediumEnvironment::Instance().Stop(); } @@ -262,10 +261,10 @@ TEST_F(AwdlBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { return true; }); - ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( + std::string result = handler_.InitializeUpgradedMediumForEndpoint( &client, std::string(kServiceId), std::string(kEndpointId)); - EXPECT_FALSE(result.Empty()); + EXPECT_FALSE(result.empty()); OfflineFrame expected_frame; expected_frame.set_version(OfflineFrame::V1); expected_frame.mutable_v1()->set_type( @@ -290,7 +289,7 @@ TEST_F(AwdlBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { // parser::ForBwuAwdlPathAvailable which puts the generated password. We // will extract it from result directly to build expected frame. OfflineFrame result_frame; - EXPECT_TRUE(result_frame.ParseFromString(std::string(result))); + EXPECT_TRUE(result_frame.ParseFromString(result)); awdl_credentials->set_password(result_frame.v1() .bandwidth_upgrade_negotiation() .upgrade_path_info() @@ -398,9 +397,9 @@ TEST_F(AwdlBwuHandlerTest, OnIncomingAwdlConnection_Success) { std::unique_ptr connection) { latch.CountDown(); }); - ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( + std::string result = handler_.InitializeUpgradedMediumForEndpoint( &client, std::string(kServiceId), std::string(kEndpointId)); - EXPECT_FALSE(result.Empty()); + EXPECT_FALSE(result.empty()); auto await_result = latch.Await(absl::Seconds(5)); EXPECT_TRUE(await_result.ok()); @@ -448,9 +447,9 @@ TEST_F(AwdlBwuHandlerTest, AwdlIncomingSocket_ToStringAndClose) { latch.CountDown(); }); - ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( + std::string result = handler_.InitializeUpgradedMediumForEndpoint( &client, std::string(kServiceId), std::string(kEndpointId)); - EXPECT_FALSE(result.Empty()); + EXPECT_FALSE(result.empty()); auto await_result = latch.Await(absl::Seconds(5)); EXPECT_TRUE(await_result.ok()); diff --git a/connections/implementation/base_bwu_handler.cc b/connections/implementation/base_bwu_handler.cc index 15f14aa2..29dbb8f0 100644 --- a/connections/implementation/base_bwu_handler.cc +++ b/connections/implementation/base_bwu_handler.cc @@ -20,7 +20,6 @@ #include "connections/implementation/client_proxy.h" #include "connections/implementation/service_id_constants.h" -#include "internal/platform/byte_array.h" #include "internal/platform/logging.h" namespace nearby { @@ -30,16 +29,16 @@ BaseBwuHandler::BaseBwuHandler( IncomingConnectionCallback incoming_connection_callback) : incoming_connection_callback_(std::move(incoming_connection_callback)) {} -ByteArray BaseBwuHandler::InitializeUpgradedMediumForEndpoint( +std::string BaseBwuHandler::InitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& service_id, const std::string& endpoint_id) { std::string upgrade_service_id = WrapInitiatorUpgradeServiceId(service_id); // Perform any medium-specific handling in the child class. - ByteArray upgrade_path_available_frame = + std::string upgrade_path_available_frame = HandleInitializeUpgradedMediumForEndpoint(client, upgrade_service_id, endpoint_id); - if (!upgrade_path_available_frame.Empty()) { + if (!upgrade_path_available_frame.empty()) { upgrade_service_id_to_active_endpoint_ids_[upgrade_service_id].insert( endpoint_id); } diff --git a/connections/implementation/base_bwu_handler.h b/connections/implementation/base_bwu_handler.h index 3f8e40ad..d95aacd8 100644 --- a/connections/implementation/base_bwu_handler.h +++ b/connections/implementation/base_bwu_handler.h @@ -22,7 +22,6 @@ #include "absl/container/flat_hash_set.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" -#include "internal/platform/byte_array.h" namespace nearby { namespace connections { @@ -35,7 +34,7 @@ class BaseBwuHandler : public BwuHandler { IncomingConnectionCallback incoming_connection_callback); // BwuHandler implementation: - ByteArray InitializeUpgradedMediumForEndpoint( + std::string InitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& service_id, const std::string& endpoint_id) final; void RevertInitiatorState() final; @@ -51,7 +50,7 @@ class BaseBwuHandler : public BwuHandler { // respectively, to handle medium-specific logic. // HandleRevertInitiatorStateForService is only invoked after the last // endpoint for the service is reverted. - virtual ByteArray HandleInitializeUpgradedMediumForEndpoint( + virtual std::string HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) = 0; virtual void HandleRevertInitiatorStateForService( diff --git a/connections/implementation/base_bwu_handler_test.cc b/connections/implementation/base_bwu_handler_test.cc index da3f87ab..a8c8c0be 100644 --- a/connections/implementation/base_bwu_handler_test.cc +++ b/connections/implementation/base_bwu_handler_test.cc @@ -24,7 +24,6 @@ #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/service_id_constants.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" namespace nearby { @@ -55,8 +54,8 @@ class BwuHandlerImpl : public BaseBwuHandler { const std::vector& handle_revert_calls() const { return handle_revert_calls_; } - void set_handle_initialize_output(ByteArray bytes) { - handle_initialize_output_ = bytes; + void set_handle_initialize_output(absl::string_view bytes) { + handle_initialize_output_ = std::string(bytes); } private: @@ -73,7 +72,7 @@ class BwuHandlerImpl : public BaseBwuHandler { const std::string& endpoint_id) final {} // BaseBwuHandler implementation: - ByteArray HandleInitializeUpgradedMediumForEndpoint( + std::string HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) final { handle_initialize_calls_.push_back({.client = client, @@ -86,7 +85,7 @@ class BwuHandlerImpl : public BaseBwuHandler { handle_revert_calls_.push_back({.service_id = upgrade_service_id}); } - ByteArray handle_initialize_output_; + std::string handle_initialize_output_; std::vector handle_initialize_calls_; std::vector handle_revert_calls_; }; @@ -95,7 +94,7 @@ TEST(BaseBwuHandlerTest, InitializeAndRevert) { ClientProxy client; BwuHandlerImpl handler; - ByteArray expected_output{"not empty"}; + absl::string_view expected_output{"not empty"}; handler.set_handle_initialize_output(expected_output); // Initialize two upgrade endpoints for service A and one for service B. @@ -150,7 +149,7 @@ TEST(BaseBwuHandlerTest, InitializeAndRevertAll) { ClientProxy client; BwuHandlerImpl handler; - ByteArray expected_output{"not empty"}; + absl::string_view expected_output{"not empty"}; handler.set_handle_initialize_output(expected_output); handler.InitializeUpgradedMediumForEndpoint(&client, /*service_id=*/"A", @@ -169,7 +168,7 @@ TEST(BaseBwuHandlerTest, Initialize_Failure_EmptyUpgradePathAvailableFrame) { ClientProxy client; BwuHandlerImpl handler; - ByteArray expected_output{}; + absl::string_view expected_output{}; handler.set_handle_initialize_output(expected_output); handler.InitializeUpgradedMediumForEndpoint(&client, /*service_id=*/"A", @@ -191,7 +190,7 @@ TEST(BaseBwuHandlerTest, Initialize_StillWorkWithUpgradeServiceIdSuffix) { ClientProxy client; BwuHandlerImpl handler; - ByteArray expected_output{"not empty"}; + absl::string_view expected_output{"not empty"}; handler.set_handle_initialize_output(expected_output); // The method should be robust and not add _another_ upgrade suffix @@ -208,7 +207,7 @@ TEST(BaseBwuHandlerTest, Revert_Failure_CantFindService) { ClientProxy client; BwuHandlerImpl handler; - ByteArray expected_output{"not empty"}; + absl::string_view expected_output{"not empty"}; handler.set_handle_initialize_output(expected_output); handler.InitializeUpgradedMediumForEndpoint(&client, /*service_id=*/"A", /*endpoint_id=*/"1"); @@ -222,7 +221,7 @@ TEST(BaseBwuHandlerTest, Revert_Failure_CantFindEndpoint) { ClientProxy client; BwuHandlerImpl handler; - ByteArray expected_output{"not empty"}; + absl::string_view expected_output{"not empty"}; handler.set_handle_initialize_output(expected_output); handler.InitializeUpgradedMediumForEndpoint(&client, /*service_id=*/"A", /*endpoint_id=*/"1"); diff --git a/connections/implementation/base_endpoint_channel.cc b/connections/implementation/base_endpoint_channel.cc index 0687d7be..ec45785c 100644 --- a/connections/implementation/base_endpoint_channel.cc +++ b/connections/implementation/base_endpoint_channel.cc @@ -157,7 +157,7 @@ ExceptionOr BaseEndpointChannel::Read( // and let it through if it is, otherwise message is erased. // TODO(apolyudov): verify this happens at most once per session. result = {}; - auto parsed = parser::FromBytes(ByteArray(input)); + auto parsed = parser::FromBytes(input); if (parsed.ok()) { if (parser::GetFrameType(parsed.result()) == location::nearby::connections::V1Frame::KEEP_ALIVE) { @@ -190,9 +190,9 @@ ExceptionOr BaseEndpointChannel::Read( return ExceptionOr(result); } -Exception BaseEndpointChannel::Write(const ByteArray& data) { +Exception BaseEndpointChannel::Write(absl::string_view data) { PacketMetaData packet_meta_data; - return Write(data.AsStringView(), packet_meta_data); + return Write(data, packet_meta_data); } Exception BaseEndpointChannel::Write(absl::string_view data, diff --git a/connections/implementation/base_endpoint_channel.h b/connections/implementation/base_endpoint_channel.h index 9946b9fa..3aa770a4 100644 --- a/connections/implementation/base_endpoint_channel.h +++ b/connections/implementation/base_endpoint_channel.h @@ -55,7 +55,7 @@ class BaseEndpointChannel : public EndpointChannel { ExceptionOr Read(PacketMetaData& packet_meta_data) ABSL_LOCKS_EXCLUDED(reader_mutex_, crypto_mutex_, last_read_mutex_) override; - Exception Write(const ByteArray& data) override; + Exception Write(absl::string_view data) override; Exception Write(absl::string_view data, PacketMetaData& packet_meta_data) ABSL_LOCKS_EXCLUDED(writer_mutex_, crypto_mutex_) override; void Close() ABSL_LOCKS_EXCLUDED(is_paused_mutex_) override; diff --git a/connections/implementation/base_endpoint_channel_test.cc b/connections/implementation/base_endpoint_channel_test.cc index a1bad6e0..cb05c1ff 100644 --- a/connections/implementation/base_endpoint_channel_test.cc +++ b/connections/implementation/base_endpoint_channel_test.cc @@ -174,7 +174,7 @@ class BaseEndpointChannelTest : public ::testing::Test { NearbyFlags::GetInstance().ResetOverridedValues(); } - const ByteArray kTestData{"test_data"}; + const absl::string_view kTestData = "test_data"; }; TEST_F(BaseEndpointChannelTest, ReadSucceedsWhenFlagDisabled) { @@ -189,7 +189,7 @@ TEST_F(BaseEndpointChannelTest, ReadSucceedsWhenFlagDisabled) { channel_a.Write(kTestData); ByteArray rx_message = std::move(channel_b.Read().result()); - EXPECT_EQ(rx_message, kTestData); + EXPECT_EQ(rx_message.AsStringView(), kTestData); } TEST_F(BaseEndpointChannelTest, ReadCallsDispatchPacketWhenFlagEnabled) { @@ -203,13 +203,14 @@ TEST_F(BaseEndpointChannelTest, ReadCallsDispatchPacketWhenFlagEnabled) { TestEndpointChannel channel_b(pipe_a.first.get(), pipe_b.second.get()); EXPECT_CALL(channel_b, DispatchPacket) - .WillOnce(::testing::Return(ExceptionOr(kTestData))); + .WillOnce(::testing::Return( + ExceptionOr(ByteArray(std::string(kTestData))))); channel_a.Write(kTestData); auto read_byte = channel_b.Read(); EXPECT_TRUE(read_byte.ok()); - EXPECT_EQ(read_byte.result(), kTestData); + EXPECT_EQ(read_byte.result().AsStringView(), kTestData); } TEST_F(BaseEndpointChannelTest, @@ -243,10 +244,10 @@ TEST_F(BaseEndpointChannelTest, ReadWrite) { auto pipe_b = CreatePipe(); // channel_b writes to pipe_b, reads from pipe_a. TestEndpointChannel channel_a(pipe_b.first.get(), pipe_a.second.get()); TestEndpointChannel channel_b(pipe_a.first.get(), pipe_b.second.get()); - ByteArray tx_message{"data message"}; + absl::string_view tx_message = "data message"; channel_a.Write(tx_message); ByteArray rx_message = std::move(channel_b.Read().result()); - EXPECT_EQ(rx_message, tx_message); + EXPECT_EQ(rx_message.AsStringView(), tx_message); } TEST_F(BaseEndpointChannelTest, ChannelUnencryptedByDefault) { @@ -332,12 +333,12 @@ TEST_F(BaseEndpointChannelTest, NotEncryptedReadWriteCanBeIntercepted) { EXPECT_EQ(channel_b.GetType(), "BLE"); // Start data transfer - ByteArray tx_message{"data message"}; + absl::string_view tx_message = "data message"; channel_a.Write(tx_message); ByteArray rx_message = std::move(channel_b.Read().result()); // Verify expectations. - EXPECT_EQ(rx_message, tx_message); + EXPECT_EQ(rx_message.AsStringView(), tx_message); { absl::MutexLock lock(mutex); std::string message{tx_message}; @@ -396,12 +397,12 @@ TEST_F(BaseEndpointChannelTest, EncryptedReadWriteCanNotBeIntercepted) { EXPECT_TRUE(channel_b.IsEncrypted()); // Start data transfer - ByteArray tx_message{"data message"}; + absl::string_view tx_message = "data message"; channel_a.Write(tx_message); ByteArray rx_message = std::move(channel_b.Read().result()); // Verify expectations. - EXPECT_EQ(rx_message, tx_message); + EXPECT_EQ(rx_message.AsStringView(), tx_message); { absl::MutexLock lock(mutex); std::string message{tx_message}; @@ -432,8 +433,8 @@ TEST_F(BaseEndpointChannelTest, CanBesuspendedAndResumed) { EXPECT_EQ(channel_b.GetType(), "WIFI_LAN"); // Start data transfer - ByteArray tx_message{"data message"}; - ByteArray more_message{"more data"}; + absl::string_view tx_message = "data message"; + absl::string_view more_message = "more data"; channel_a.Write(tx_message); ByteArray rx_message = std::move(channel_b.Read().result()); @@ -459,7 +460,7 @@ TEST_F(BaseEndpointChannelTest, CanBesuspendedAndResumed) { // Resume; verify that data transfer comepleted. channel_a.Resume(); EXPECT_TRUE(latch.Await(absl::Milliseconds(1000)).result()); - EXPECT_EQ(read_more, more_message); + EXPECT_EQ(read_more.AsStringView(), more_message); // Shutdown test environment. channel_a.Close(DisconnectionReason::LOCAL_DISCONNECTION); @@ -506,14 +507,14 @@ TEST_F(BaseEndpointChannelTest, ReadUnencryptedFrameOnEncryptedChannel) { EXPECT_EQ(channel_b.GetType(), "ENCRYPTED_BLUETOOTH"); // An unencrypted KeepAlive should succeed. - ByteArray keep_alive_message = parser::ForKeepAlive(); + std::string keep_alive_message = parser::ForKeepAlive(); channel_a.Write(keep_alive_message); ExceptionOr result = channel_b.Read(); EXPECT_TRUE(result.ok()); - EXPECT_EQ(result.result(), keep_alive_message); + EXPECT_EQ(result.result().AsStringView(), keep_alive_message); // An unencrypted data frame should fail. - ByteArray tx_message{"data message"}; + absl::string_view tx_message = "data message"; channel_a.Write(tx_message); result = channel_b.Read(); EXPECT_FALSE(result.ok()); diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 406d35f2..1aab772d 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -2477,8 +2477,8 @@ ExceptionOr BasePcpHandler::ReadConnectionRequestFrame( return ExceptionOr(wrapped_bytes.exception()); } - ByteArray bytes = std::move(wrapped_bytes.result()); - ExceptionOr wrapped_frame = parser::FromBytes(bytes); + ExceptionOr wrapped_frame = + parser::FromBytes(wrapped_bytes.result().AsStringView()); if (wrapped_frame.GetException().Raised(Exception::kInvalidProtocolBuffer)) { return ExceptionOr(Exception::kIo); } diff --git a/connections/implementation/base_pcp_handler_test.cc b/connections/implementation/base_pcp_handler_test.cc index 10f6bdd7..351e3dc3 100644 --- a/connections/implementation/base_pcp_handler_test.cc +++ b/connections/implementation/base_pcp_handler_test.cc @@ -88,7 +88,6 @@ using ::nearby::analytics::HasEventType; using ::testing::_; using ::testing::AtLeast; using ::protobuf_matchers::EqualsProto; -using ::testing::Invoke; using ::testing::Matcher; using ::testing::MockFunction; using ::testing::NiceMock; @@ -171,7 +170,7 @@ class MockEndpointChannel : public BaseEndpointChannel { output_stream_(std::move(writer)) {} ExceptionOr DoRead() { return BaseEndpointChannel::Read(); } - Exception DoWrite(const ByteArray& data) { + Exception DoWrite(absl::string_view data) { if (broken_write_) { return {Exception::kFailed}; } @@ -182,7 +181,7 @@ class MockEndpointChannel : public BaseEndpointChannel { } MOCK_METHOD(ExceptionOr, Read, (), (override)); - MOCK_METHOD(Exception, Write, (const ByteArray& data), (override)); + MOCK_METHOD(Exception, Write, (absl::string_view data), (override)); MOCK_METHOD(void, CloseImpl, (), (override)); MOCK_METHOD(location::nearby::proto::connections::Medium, GetMedium, (), (const, override)); @@ -576,26 +575,26 @@ class BasePcpHandlerTest // the peer channel. The rest of the exchange must happen for the benefit of // DH key exchange. EXPECT_CALL(*channel_a, Read()) - .WillRepeatedly(Invoke( - [channel = channel_a.get()]() { return channel->DoRead(); })); + .WillRepeatedly( + [channel = channel_a.get()]() { return channel->DoRead(); }); EXPECT_CALL(*channel_a, Write(_)) .WillOnce(Return(Exception{Exception::kSuccess})) .WillRepeatedly( - Invoke([channel = channel_a.get()](const ByteArray& data) { + [channel = channel_a.get()](absl::string_view data) { return channel->DoWrite(data); - })); + }); EXPECT_CALL(*channel_a, GetMedium).WillRepeatedly(Return(medium)); EXPECT_CALL(*channel_a, GetLastReadTimestamp) .WillRepeatedly(Return(absl::Now())); EXPECT_CALL(*channel_a, IsPaused).WillRepeatedly(Return(false)); EXPECT_CALL(*channel_b, Read()) - .WillRepeatedly(Invoke( - [channel = channel_b.get()]() { return channel->DoRead(); })); + .WillRepeatedly( + [channel = channel_b.get()]() { return channel->DoRead(); }); EXPECT_CALL(*channel_b, Write(_)) .WillRepeatedly( - Invoke([channel = channel_b.get()](const ByteArray& data) { + [channel = channel_b.get()](absl::string_view data) { return channel->DoWrite(data); - })); + }); EXPECT_CALL(*channel_b, GetMedium).WillRepeatedly(Return(medium)); EXPECT_CALL(*channel_b, GetLastReadTimestamp) .WillRepeatedly(Return(absl::Now())); @@ -622,20 +621,20 @@ class BasePcpHandlerTest // the peer channel. The rest of the exchange must happen for the benefit of // DH key exchange. EXPECT_CALL(*channel_a, Read()) - .WillRepeatedly(Invoke( - [channel = channel_a.get()]() { return channel->DoRead(); })); + .WillRepeatedly( + [channel = channel_a.get()]() { return channel->DoRead(); }); EXPECT_CALL(*channel_a, GetMedium).WillRepeatedly(Return(medium)); EXPECT_CALL(*channel_a, GetLastReadTimestamp) .WillRepeatedly(Return(absl::Now())); EXPECT_CALL(*channel_a, IsPaused).WillRepeatedly(Return(false)); EXPECT_CALL(*channel_b, Read()) - .WillRepeatedly(Invoke( - [channel = channel_b.get()]() { return channel->DoRead(); })); + .WillRepeatedly( + [channel = channel_b.get()]() { return channel->DoRead(); }); EXPECT_CALL(*channel_b, Write(_)) .WillRepeatedly( - Invoke([channel = channel_b.get()](const ByteArray& data) { + [channel = channel_b.get()](absl::string_view data) { return channel->DoWrite(data); - })); + }); EXPECT_CALL(*channel_b, GetMedium).WillRepeatedly(Return(medium)); EXPECT_CALL(*channel_b, GetLastReadTimestamp) .WillRepeatedly(Return(absl::Now())); @@ -675,15 +674,15 @@ class BasePcpHandlerTest auto allowed_mediums = pcp_handler->GetDiscoveryMediums(client); EXPECT_CALL(*pcp_handler, ConnectImpl) - .WillOnce(Invoke([&channel_a, connect_medium]( - ClientProxy* client, - MockPcpHandler::DiscoveredEndpoint* endpoint) { + .WillOnce([&channel_a, connect_medium]( + ClientProxy* client, + MockPcpHandler::DiscoveredEndpoint* endpoint) { return MockPcpHandler::ConnectImplResult{ .medium = connect_medium, .status = {Status::kSuccess}, .endpoint_channel = std::move(channel_a), }; - })); + }); for (const auto& discovered_medium : allowed_mediums) { pcp_handler->OnEndpointFound( @@ -756,15 +755,15 @@ class BasePcpHandlerTest EXPECT_CALL(*pcp_handler, ConnectImpl) .WillRepeatedly( - Invoke([&channel_a, connect_medium]( - ClientProxy* client, - MockPcpHandler::DiscoveredEndpoint* endpoint) { + [&channel_a, connect_medium]( + ClientProxy* client, + MockPcpHandler::DiscoveredEndpoint* endpoint) { return MockPcpHandler::ConnectImplResult{ .medium = connect_medium, .status = {Status::kSuccess}, .endpoint_channel = std::move(channel_a), }; - })); + }); for (const auto& discovered_medium : allowed_mediums) { pcp_handler->OnEndpointFound( @@ -824,8 +823,8 @@ class BasePcpHandlerTest EXPECT_CALL(*pcp_handler, ConnectImpl) .WillRepeatedly( - Invoke([&channel_a](ClientProxy* client, - MockPcpHandler::DiscoveredEndpoint* endpoint) { + [&channel_a](ClientProxy* client, + MockPcpHandler::DiscoveredEndpoint* endpoint) { if (endpoint->medium == location::nearby::proto::connections::WIFI_LAN) { LOG(INFO) << "Connect with Medium WIFI_LAN failed."; @@ -844,7 +843,7 @@ class BasePcpHandlerTest .endpoint_channel = std::move(channel_a), }; } - })); + }); for (const auto& discovered_medium : allowed_mediums) { pcp_handler->OnEndpointFound( @@ -1353,7 +1352,7 @@ TEST_P(BasePcpHandlerTest, RequestConnectionV3_ConnectImplFailure) { auto allowed_mediums = pcp_handler.GetDiscoveryMediums(client_.get()); EXPECT_CALL(pcp_handler, ConnectImpl) - .WillRepeatedly(Invoke( + .WillRepeatedly( [connect_medium](ClientProxy* client, MockPcpHandler::DiscoveredEndpoint* endpoint) { return MockPcpHandler::ConnectImplResult{ @@ -1361,7 +1360,7 @@ TEST_P(BasePcpHandlerTest, RequestConnectionV3_ConnectImplFailure) { .status = {Status::kError}, .endpoint_channel = nullptr, }; - })); + }); for (const auto& discovered_medium : allowed_mediums) { pcp_handler.OnEndpointFound( @@ -1428,7 +1427,7 @@ TEST_P(BasePcpHandlerTest, RequestConnection_ConnectImplFailure) { auto allowed_mediums = pcp_handler.GetDiscoveryMediums(client_.get()); EXPECT_CALL(pcp_handler, ConnectImpl) - .WillRepeatedly(Invoke( + .WillRepeatedly( [connect_medium](ClientProxy* client, MockPcpHandler::DiscoveredEndpoint* endpoint) { return MockPcpHandler::ConnectImplResult{ @@ -1436,7 +1435,7 @@ TEST_P(BasePcpHandlerTest, RequestConnection_ConnectImplFailure) { .status = {Status::kError}, .endpoint_channel = nullptr, }; - })); + }); for (const auto& discovered_medium : allowed_mediums) { pcp_handler.OnEndpointFound( @@ -1787,7 +1786,7 @@ TEST_F(BasePcpHandlerTest, InjectEndpoint) { EXPECT_TRUE(client_->IsDiscovering()); EXPECT_CALL(pcp_handler, InjectEndpointImpl(client_.get(), service_id, _)) - .WillOnce(Invoke([&pcp_handler, &endpoint_id]( + .WillOnce([&pcp_handler, &endpoint_id]( ClientProxy* client, const std::string& service_id, const OutOfBandConnectionMetadata& metadata) { pcp_handler.OnEndpointFound( @@ -1803,7 +1802,7 @@ TEST_F(BasePcpHandlerTest, InjectEndpoint) { MockContext{nullptr}, })); return Status{Status::kSuccess}; - })); + }); pcp_handler.InjectEndpoint( client_.get(), service_id, OutOfBandConnectionMetadata{ @@ -1851,30 +1850,30 @@ TEST_F(BasePcpHandlerTest, ::testing::InSequence seq; EXPECT_CALL(mock_discovery_listener_.endpoint_found_cb, Call) - .WillOnce(Invoke([id = endpoint_id](const std::string& endpoint_id, + .WillOnce([id = endpoint_id](const std::string& endpoint_id, const ByteArray& endpoint_info, const std::string& service_id) { EXPECT_EQ(endpoint_id, id); EXPECT_EQ(endpoint_info, ByteArray{"ABCD"}); - })); + }); EXPECT_CALL(mock_discovery_listener_.endpoint_lost_cb, Call) - .WillOnce(Invoke([id = endpoint_id](const std::string& endpoint_id) { + .WillOnce([id = endpoint_id](const std::string& endpoint_id) { EXPECT_EQ(endpoint_id, id); - })); + }); EXPECT_CALL(mock_discovery_listener_.endpoint_found_cb, Call) - .WillOnce(Invoke([id = endpoint_id](const std::string& endpoint_id, + .WillOnce([id = endpoint_id](const std::string& endpoint_id, const ByteArray& endpoint_info, const std::string& service_id) { EXPECT_EQ(endpoint_id, id); EXPECT_EQ(endpoint_info, ByteArray{"ABCDEF"}); - })); + }); EXPECT_CALL(mock_discovery_listener_.endpoint_lost_cb, Call) - .WillOnce(Invoke([id = endpoint_id](const std::string& endpoint_id) { + .WillOnce([id = endpoint_id](const std::string& endpoint_id) { EXPECT_EQ(endpoint_id, id); - })); + }); // Found endpoint on Bluetooth pcp_handler.OnEndpointFound( @@ -1964,7 +1963,7 @@ TEST_F(BasePcpHandlerTest, TestStartStopEndpointLostAlarm) { EXPECT_TRUE(client_->IsDiscovering()); EXPECT_CALL(pcp_handler, InjectEndpointImpl) - .WillOnce(Invoke([&pcp_handler, &endpoint_id]( + .WillOnce([&pcp_handler, &endpoint_id]( ClientProxy* client, const std::string& service_id, const OutOfBandConnectionMetadata& metadata) { pcp_handler.OnEndpointFound( @@ -1980,7 +1979,7 @@ TEST_F(BasePcpHandlerTest, TestStartStopEndpointLostAlarm) { MockContext{nullptr}, })); return Status{Status::kSuccess}; - })); + }); pcp_handler.InjectEndpoint( client_.get(), service_id, OutOfBandConnectionMetadata{ @@ -2027,7 +2026,7 @@ TEST_F(BasePcpHandlerTest, TestStartEndpointLostByMediumAlarms) { EXPECT_TRUE(client_->IsDiscovering()); EXPECT_CALL(pcp_handler, InjectEndpointImpl) - .WillOnce(Invoke([&pcp_handler, &endpoint_id]( + .WillOnce([&pcp_handler, &endpoint_id]( ClientProxy* client, const std::string& service_id, const OutOfBandConnectionMetadata& metadata) { pcp_handler.OnEndpointFound( @@ -2043,7 +2042,7 @@ TEST_F(BasePcpHandlerTest, TestStartEndpointLostByMediumAlarms) { MockContext{nullptr}, })); return Status{Status::kSuccess}; - })); + }); pcp_handler.InjectEndpoint( client_.get(), service_id, OutOfBandConnectionMetadata{ @@ -2094,7 +2093,7 @@ TEST_F(BasePcpHandlerTest, TestEndpointFoundStopsAlarm) { EXPECT_CALL(pcp_handler, InjectEndpointImpl) .Times(2) .WillRepeatedly( - Invoke([&pcp_handler, &endpoint_id, &first_call]( + [&pcp_handler, &endpoint_id, &first_call]( ClientProxy* client, const std::string& service_id, const OutOfBandConnectionMetadata& metadata) { ByteArray endpoint_info; @@ -2117,7 +2116,7 @@ TEST_F(BasePcpHandlerTest, TestEndpointFoundStopsAlarm) { MockContext{nullptr}, })); return Status{Status::kSuccess}; - })); + }); pcp_handler.InjectEndpoint( client_.get(), service_id, OutOfBandConnectionMetadata{ @@ -2271,20 +2270,20 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForConnectionsWithUnknown) { ASSERT_TRUE(client_->IsListeningForIncomingConnections()); ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(client_.get())); auto channel_pair = SetupConnection(Medium::BLUETOOTH); - ByteArray serialized_frame = parser::ForConnectionRequestConnections( + std::string serialized_frame = parser::ForConnectionRequestConnections( {}, { .local_endpoint_id = "ABCD", .local_endpoint_info = ByteArray("local endpoint"), }); location::nearby::connections::OfflineFrame frame; - frame.ParseFromString(serialized_frame.AsStringView()); + frame.ParseFromString(serialized_frame); frame.mutable_v1()->mutable_connection_request()->clear_connections_device(); frame.mutable_v1()->mutable_connection_request()->clear_presence_device(); ASSERT_FALSE(frame.v1().connection_request().has_connections_device()); ASSERT_FALSE(frame.v1().connection_request().has_presence_device()); // do a dummy write to get to the actual write. - channel_pair.first->Write(ByteArray()); - channel_pair.first->Write(ByteArray(frame.SerializeAsString())); + channel_pair.first->Write(""); + channel_pair.first->Write(frame.SerializeAsString()); EXPECT_TRUE(pcp_handler .OnIncomingConnection( client_.get(), ByteArray("remote endpoint"), @@ -2321,20 +2320,20 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForPresenceWithUnknown) { ASSERT_TRUE(client_->IsListeningForIncomingConnections()); ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(client_.get())); auto channel_pair = SetupConnection(Medium::BLUETOOTH); - ByteArray serialized_frame = parser::ForConnectionRequestConnections( + std::string serialized_frame = parser::ForConnectionRequestConnections( {}, { .local_endpoint_id = "ABCD", .local_endpoint_info = ByteArray("local endpoint"), }); location::nearby::connections::OfflineFrame frame; - frame.ParseFromString(serialized_frame.AsStringView()); + frame.ParseFromString(serialized_frame); frame.mutable_v1()->mutable_connection_request()->clear_connections_device(); frame.mutable_v1()->mutable_connection_request()->clear_presence_device(); ASSERT_FALSE(frame.v1().connection_request().has_connections_device()); ASSERT_FALSE(frame.v1().connection_request().has_presence_device()); // do a dummy write to get to the actual write. - channel_pair.first->Write(ByteArray()); - channel_pair.first->Write(ByteArray(frame.SerializeAsString())); + channel_pair.first->Write(""); + channel_pair.first->Write(frame.SerializeAsString()); EXPECT_EQ(pcp_handler .OnIncomingConnection( client_.get(), ByteArray("remote endpoint"), @@ -2370,21 +2369,21 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForPresenceWithConnections) { ASSERT_TRUE(client_->IsListeningForIncomingConnections()); ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(client_.get())); auto channel_pair = SetupConnection(Medium::BLUETOOTH); - ByteArray serialized_frame = parser::ForConnectionRequestConnections( + std::string serialized_frame = parser::ForConnectionRequestConnections( {}, { .local_endpoint_id = "ABCD", .local_endpoint_info = ByteArray("local endpoint"), }); location::nearby::connections::OfflineFrame frame; - frame.ParseFromString(serialized_frame.AsStringView()); + frame.ParseFromString(serialized_frame); frame.mutable_v1() ->mutable_connection_request() ->mutable_connections_device() ->set_endpoint_id("ABCD"); ASSERT_TRUE(frame.v1().connection_request().has_connections_device()); // do a dummy write to get to the actual write. - channel_pair.first->Write(ByteArray()); - channel_pair.first->Write(ByteArray(frame.SerializeAsString())); + channel_pair.first->Write(""); + channel_pair.first->Write(frame.SerializeAsString()); EXPECT_EQ(pcp_handler .OnIncomingConnection( client_.get(), ByteArray("remote endpoint"), @@ -2420,21 +2419,21 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForPresenceWithPresence) { ASSERT_TRUE(client_->IsListeningForIncomingConnections()); ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(client_.get())); auto channel_pair = SetupConnection(Medium::BLUETOOTH); - ByteArray serialized_frame = parser::ForConnectionRequestConnections( + std::string serialized_frame = parser::ForConnectionRequestConnections( {}, { .local_endpoint_id = "ABCD", .local_endpoint_info = ByteArray("local endpoint"), }); location::nearby::connections::OfflineFrame frame; - frame.ParseFromString(serialized_frame.AsStringView()); + frame.ParseFromString(serialized_frame); frame.mutable_v1() ->mutable_connection_request() ->mutable_presence_device() ->set_endpoint_id("ABCD"); ASSERT_TRUE(frame.v1().connection_request().has_presence_device()); // do a dummy write to get to the actual write. - channel_pair.first->Write(ByteArray()); - channel_pair.first->Write(ByteArray(frame.SerializeAsString())); + channel_pair.first->Write(""); + channel_pair.first->Write(frame.SerializeAsString()); EXPECT_TRUE(pcp_handler .OnIncomingConnection( client_.get(), ByteArray("remote endpoint"), @@ -2469,21 +2468,21 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForConnectionsWithConnections) { ASSERT_TRUE(client_->IsListeningForIncomingConnections()); ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(client_.get())); auto channel_pair = SetupConnection(Medium::BLUETOOTH); - ByteArray serialized_frame = parser::ForConnectionRequestConnections( + std::string serialized_frame = parser::ForConnectionRequestConnections( {}, { .local_endpoint_id = "ABCD", .local_endpoint_info = ByteArray("local endpoint"), }); location::nearby::connections::OfflineFrame frame; - frame.ParseFromString(serialized_frame.AsStringView()); + frame.ParseFromString(serialized_frame); frame.mutable_v1() ->mutable_connection_request() ->mutable_connections_device() ->set_endpoint_id("ABCD"); ASSERT_TRUE(frame.v1().connection_request().has_connections_device()); // do a dummy write to get to the actual write. - channel_pair.first->Write(ByteArray()); - channel_pair.first->Write(ByteArray(frame.SerializeAsString())); + channel_pair.first->Write(""); + channel_pair.first->Write(frame.SerializeAsString()); EXPECT_TRUE(pcp_handler .OnIncomingConnection( client_.get(), ByteArray("remote endpoint"), @@ -2518,21 +2517,21 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForConnectionsWithPresence) { ASSERT_TRUE(client_->IsListeningForIncomingConnections()); ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(client_.get())); auto channel_pair = SetupConnection(Medium::BLUETOOTH); - ByteArray serialized_frame = parser::ForConnectionRequestConnections( + std::string serialized_frame = parser::ForConnectionRequestConnections( {}, { .local_endpoint_id = "ABCD", .local_endpoint_info = ByteArray("local endpoint"), }); location::nearby::connections::OfflineFrame frame; - frame.ParseFromString(serialized_frame.AsStringView()); + frame.ParseFromString(serialized_frame); frame.mutable_v1() ->mutable_connection_request() ->mutable_presence_device() ->set_endpoint_id("ABCD"); ASSERT_TRUE(frame.v1().connection_request().has_presence_device()); // do a dummy write to get to the actual write. - channel_pair.first->Write(ByteArray()); - channel_pair.first->Write(ByteArray(frame.SerializeAsString())); + channel_pair.first->Write(""); + channel_pair.first->Write(frame.SerializeAsString()); EXPECT_EQ(pcp_handler .OnIncomingConnection( client_.get(), ByteArray("remote endpoint"), @@ -2568,7 +2567,7 @@ TEST_F(BasePcpHandlerTest, IncomingConnectionFailsWithEmptyEndpointId) { ASSERT_TRUE(client_->IsListeningForIncomingConnections()); ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(client_.get())); auto channel_pair = SetupConnection(Medium::BLUETOOTH); - ByteArray serialized_frame = parser::ForConnectionRequestConnections( + std::string serialized_frame = parser::ForConnectionRequestConnections( {}, { .local_endpoint_id = "", .local_endpoint_info = ByteArray("local endpoint"), @@ -2576,12 +2575,12 @@ TEST_F(BasePcpHandlerTest, IncomingConnectionFailsWithEmptyEndpointId) { // At this point the connection request doesn't have an endpoint ID field // set, so we do that here. location::nearby::connections::OfflineFrame frame; - frame.ParseFromString(serialized_frame.AsStringView()); + frame.ParseFromString(serialized_frame); frame.mutable_v1()->mutable_connection_request()->set_endpoint_id(""); ASSERT_TRUE(frame.v1().connection_request().has_endpoint_id()); // do a dummy write to get to the actual write. - channel_pair.first->Write(ByteArray()); - channel_pair.first->Write(ByteArray(frame.SerializeAsString())); + channel_pair.first->Write(""); + channel_pair.first->Write(frame.SerializeAsString()); absl::string_view expected_log = R"pb( event_type: CLIENT_SESSION client_session { diff --git a/connections/implementation/bluetooth_bwu_handler.cc b/connections/implementation/bluetooth_bwu_handler.cc index f6734597..00c059a9 100644 --- a/connections/implementation/bluetooth_bwu_handler.cc +++ b/connections/implementation/bluetooth_bwu_handler.cc @@ -27,7 +27,6 @@ #include "connections/implementation/offline_frames.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_classic.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" #include "internal/platform/logging.h" #include "internal/platform/mac_address.h" @@ -116,7 +115,7 @@ BluetoothBwuHandler::CreateUpgradedEndpointChannel( return {std::move(channel)}; } -ByteArray BluetoothBwuHandler::HandleInitializeUpgradedMediumForEndpoint( +std::string BluetoothBwuHandler::HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) { MacAddress mac_address = bluetooth_medium_.GetAddress(); diff --git a/connections/implementation/bluetooth_bwu_handler.h b/connections/implementation/bluetooth_bwu_handler.h index ae409310..b468a54a 100644 --- a/connections/implementation/bluetooth_bwu_handler.h +++ b/connections/implementation/bluetooth_bwu_handler.h @@ -26,7 +26,6 @@ #include "connections/implementation/mediums/mediums.h" #include "connections/medium_selector.h" #include "internal/platform/bluetooth_classic.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" namespace nearby { @@ -66,7 +65,7 @@ class BluetoothBwuHandler : public BaseBwuHandler { const std::string& endpoint_id) final {} // BaseBwuHandler implementation: - ByteArray HandleInitializeUpgradedMediumForEndpoint( + std::string HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) final; void HandleRevertInitiatorStateForService( diff --git a/connections/implementation/bluetooth_bwu_test.cc b/connections/implementation/bluetooth_bwu_test.cc index a60f8333..52ad5fe5 100644 --- a/connections/implementation/bluetooth_bwu_test.cc +++ b/connections/implementation/bluetooth_bwu_test.cc @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gtest/gtest.h" @@ -23,7 +24,6 @@ #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/offline_frames.h" -#include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" #include "internal/platform/expected.h" @@ -83,11 +83,11 @@ TEST_F(BluetoothBwuTest, SoftAPBWUInit_STACreateEndpointChannel) { // client_1 works as Bluetooth Server Device SingleThreadExecutor server_executor; server_executor.Execute([&]() { - ByteArray upgrade_path_available_frame = + std::string upgrade_path_available_frame = handler_1->InitializeUpgradedMediumForEndpoint(&client_1, /*service_id=*/"A", /*endpoint_id=*/"1"); - EXPECT_FALSE(upgrade_path_available_frame.Empty()); + EXPECT_FALSE(upgrade_path_available_frame.empty()); upgrade_frame = parser::FromBytes(upgrade_path_available_frame); start_latch.CountDown(); diff --git a/connections/implementation/bwu_handler.h b/connections/implementation/bwu_handler.h index cd0fc073..b1704983 100644 --- a/connections/implementation/bwu_handler.h +++ b/connections/implementation/bwu_handler.h @@ -21,7 +21,6 @@ #include "absl/functional/any_invocable.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" namespace nearby { @@ -53,7 +52,7 @@ class BwuHandler { // that hasn't already been done), and returns a serialized UpgradePathInfo // that can be sent to the Responder. // @BwuHandlerThread - virtual ByteArray InitializeUpgradedMediumForEndpoint( + virtual std::string InitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& service_id, const std::string& endpoint_id) = 0; diff --git a/connections/implementation/bwu_manager.cc b/connections/implementation/bwu_manager.cc index fd41cfb2..53084af8 100644 --- a/connections/implementation/bwu_manager.cc +++ b/connections/implementation/bwu_manager.cc @@ -47,7 +47,6 @@ #include "connections/implementation/wifi_hotspot_bwu_handler.h" #include "connections/implementation/wifi_lan_bwu_handler.h" #include "connections/medium_selector.h" -#include "internal/platform/byte_array.h" #include "internal/platform/cancelable_alarm.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/expected.h" @@ -341,12 +340,12 @@ void BwuManager::InitiateBwuForEndpoint(ClientProxy* client, } std::string service_id = channel->GetServiceId(); - ByteArray bytes = handler->InitializeUpgradedMediumForEndpoint( + std::string bytes = handler->InitializeUpgradedMediumForEndpoint( client, service_id, endpoint_id); // Because we grab the endpointChannel first thing, it is possible the // endpointChannel is stale by the time we attempt to write over it. - if (bytes.Empty()) { + if (bytes.empty()) { LOG(ERROR) << "BwuManager couldn't complete the upgrade for endpoint " << endpoint_id << " to medium " << location::nearby::proto::connections::Medium_Name( @@ -1138,7 +1137,7 @@ bool BwuManager::ReadClientIntroductionFrame( auto data = channel->Read(); timeout_alarm.Cancel(); if (!data.ok()) return false; - auto transfer(parser::FromBytes(data.result())); + auto transfer(parser::FromBytes(data.result().AsStringView())); if (!transfer.ok()) { LOG(ERROR) << "In ReadClientIntroductionFrame, attempted to read a " "ClientIntroductionFrame from EndpointChannel " @@ -1189,7 +1188,7 @@ bool BwuManager::ReadClientIntroductionAckFrame(EndpointChannel* channel) { auto data = channel->Read(); timeout_alarm.Cancel(); if (!data.ok()) return false; - auto transfer(parser::FromBytes(data.result())); + auto transfer(parser::FromBytes(data.result().AsStringView())); if (!transfer.ok()) return false; OfflineFrame frame = transfer.result(); if (!frame.has_v1() || !frame.v1().has_bandwidth_upgrade_negotiation()) diff --git a/connections/implementation/bwu_manager_test.cc b/connections/implementation/bwu_manager_test.cc index 40cd3e50..4862c2e1 100644 --- a/connections/implementation/bwu_manager_test.cc +++ b/connections/implementation/bwu_manager_test.cc @@ -924,12 +924,12 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_WifiDirect) { OfflineFrame frame; CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH); - ByteArray bytes = parser::ForBwuWifiDirectPathAvailable( + std::string bytes = parser::ForBwuWifiDirectPathAvailable( /*ssid=*/"", /*password=*/"", /*port=*/2143, /*frequency=*/2412, /*supports_disabling_encryption=*/false, /*gateway=*/"123.234.23.1", /*service_name=*/"NC-WifiDirectTest", /*pin=*/"b592f7d3"); - frame.ParseFromString(std::string(bytes)); + frame.ParseFromString(bytes); ::nearby::connections::V1Frame* v1_frame = frame.mutable_v1(); ::nearby::connections::BandwidthUpgradeNegotiationFrame* sub_frame = diff --git a/connections/implementation/connections_authentication_transport.cc b/connections/implementation/connections_authentication_transport.cc index c98edbbe..ec669d9b 100644 --- a/connections/implementation/connections_authentication_transport.cc +++ b/connections/implementation/connections_authentication_transport.cc @@ -18,7 +18,6 @@ #include "absl/strings/string_view.h" #include "connections/implementation/endpoint_channel.h" -#include "internal/platform/byte_array.h" #include "internal/platform/logging.h" namespace nearby { @@ -33,7 +32,7 @@ void ConnectionsAuthenticationTransport::WriteMessage( absl::string_view message) const { // channel_ should never be null. CHECK(channel_ != nullptr); - channel_->Write(ByteArray(message.data(), message.size())); + channel_->Write(message); } std::string ConnectionsAuthenticationTransport::ReadMessage() const { diff --git a/connections/implementation/connections_authentication_transport_test.cc b/connections/implementation/connections_authentication_transport_test.cc index 11ebd2eb..4198080f 100644 --- a/connections/implementation/connections_authentication_transport_test.cc +++ b/connections/implementation/connections_authentication_transport_test.cc @@ -40,7 +40,7 @@ class MockEndpointChannel : public EndpointChannel { public: MOCK_METHOD(ExceptionOr, Read, (), (override)); MOCK_METHOD(ExceptionOr, Read, (PacketMetaData&), (override)); - MOCK_METHOD(Exception, Write, (const ByteArray& data), (override)); + MOCK_METHOD(Exception, Write, (absl::string_view data), (override)); MOCK_METHOD(Exception, Write, (absl::string_view data, PacketMetaData&), (override)); MOCK_METHOD(void, Close, (), (override)); @@ -87,8 +87,8 @@ class MockEndpointChannel : public EndpointChannel { TEST(ConnectionsAuthenticationTransportTest, TestWriteMessage) { MockEndpointChannel channel; ConnectionsAuthenticationTransport transport(channel); - EXPECT_CALL(channel, Write(_)).WillOnce([&channel](const ByteArray& data) { - channel.messages_.push_back(data.string_data()); + EXPECT_CALL(channel, Write(_)).WillOnce([&channel](absl::string_view data) { + channel.messages_.push_back(std::string(data)); return Exception{ .value = Exception::Value::kSuccess, }; diff --git a/connections/implementation/encryption_runner.cc b/connections/implementation/encryption_runner.cc index a74a4b8e..7a2842db 100644 --- a/connections/implementation/encryption_runner.cc +++ b/connections/implementation/encryption_runner.cc @@ -14,7 +14,6 @@ #include "connections/implementation/encryption_runner.h" -#include #include #include #include @@ -22,7 +21,6 @@ #include "securegcm/ukey2_handshake.h" #include "absl/strings/ascii.h" -#include "absl/time/clock.h" #include "absl/time/time.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" @@ -139,8 +137,7 @@ class ServerRunnable final { return; } - Exception write_exception = - channel_->Write(ByteArray(std::move(*server_init))); + Exception write_exception = channel_->Write(*server_init); if (!write_exception.Ok()) { LogException(); HandleHandshakeOrIoException(&timeout_alarm); @@ -198,7 +195,7 @@ class ServerRunnable final { void HandleAlertException( const securegcm::UKey2Handshake::ParseResult& parse_result) const { Exception write_exception = - channel_->Write(ByteArray(*parse_result.alert_to_send)); + channel_->Write(*parse_result.alert_to_send); if (!write_exception.Ok()) { LOG(WARNING) << "In StartServer(), client " << client_->GetClientId() << " failed to pass the alert error message to endpoint(id=" @@ -251,7 +248,7 @@ class ClientRunnable final { return; } - Exception write_init_exception = channel_->Write(ByteArray(*client_init)); + Exception write_init_exception = channel_->Write(*client_init); if (!write_init_exception.Ok()) { LogException(); HandleHandshakeOrIoException(&timeout_alarm); @@ -298,7 +295,7 @@ class ClientRunnable final { } Exception write_finish_exception = - channel_->Write(ByteArray(*client_finish)); + channel_->Write(*client_finish); if (!write_finish_exception.Ok()) { LogException(); HandleHandshakeOrIoException(&timeout_alarm); @@ -330,8 +327,7 @@ class ClientRunnable final { void HandleAlertException( const securegcm::UKey2Handshake::ParseResult& parse_result) const { - Exception write_exception = - channel_->Write(ByteArray(*parse_result.alert_to_send)); + Exception write_exception = channel_->Write(*parse_result.alert_to_send); if (!write_exception.Ok()) { LOG(WARNING) << "In StartClient(), client " << client_->GetClientId() << " failed to pass the alert error message to endpoint(id=" diff --git a/connections/implementation/encryption_runner_test.cc b/connections/implementation/encryption_runner_test.cc index c5ec1964..5cf31250 100644 --- a/connections/implementation/encryption_runner_test.cc +++ b/connections/implementation/encryption_runner_test.cc @@ -56,14 +56,13 @@ class FakeEndpointChannel : public EndpointChannel { read_timestamp_ = SystemClock::ElapsedRealtime(); return in_ ? in_->Read(kChunkSize) : ExceptionOr{Exception::kIo}; } - Exception Write(const ByteArray& data) override { + Exception Write(absl::string_view data) override { write_timestamp_ = SystemClock::ElapsedRealtime(); - return out_ ? out_->Write(data.AsStringView()) : Exception{Exception::kIo}; + return out_ ? out_->Write(data) : Exception{Exception::kIo}; } Exception Write(absl::string_view data, PacketMetaData& packet_meta_data) override { - write_timestamp_ = SystemClock::ElapsedRealtime(); - return out_ ? out_->Write(data) : Exception{Exception::kIo}; + return Write(data); } void Close() override { if (in_) in_->Close(); diff --git a/connections/implementation/endpoint_channel.h b/connections/implementation/endpoint_channel.h index b4e9cbe3..abd20ef3 100644 --- a/connections/implementation/endpoint_channel.h +++ b/connections/implementation/endpoint_channel.h @@ -43,7 +43,7 @@ class EndpointChannel { virtual ExceptionOr Read(PacketMetaData& packet_meta_data) = 0; - virtual Exception Write(const ByteArray& data) = 0; // throws Exception::IO + virtual Exception Write(absl::string_view data) = 0; // throws Exception::IO virtual Exception Write( absl::string_view data, diff --git a/connections/implementation/endpoint_channel_manager_test.cc b/connections/implementation/endpoint_channel_manager_test.cc index 23f61bd4..e5ada1ec 100644 --- a/connections/implementation/endpoint_channel_manager_test.cc +++ b/connections/implementation/endpoint_channel_manager_test.cc @@ -227,12 +227,12 @@ TEST(BaseEndpointChannelManagerTest, RegisterChannelEncryptedReadwrite) { EXPECT_EQ(channel_a_raw->GetType(), "ENCRYPTED_BLUETOOTH"); EXPECT_EQ(channel_b_raw->GetType(), "ENCRYPTED_BLUETOOTH"); - ByteArray tx_message{"data message"}; + absl::string_view tx_message = "data message"; channel_a_raw->Write(tx_message); ByteArray rx_message = std::move(channel_b_raw->Read().result()); // Verify expectations. - EXPECT_EQ(rx_message, tx_message); + EXPECT_EQ(rx_message.AsStringView(), tx_message); { absl::MutexLock lock(mutex); std::string message{tx_message}; diff --git a/connections/implementation/endpoint_manager.cc b/connections/implementation/endpoint_manager.cc index 15fdd726..1c950387 100644 --- a/connections/implementation/endpoint_manager.cc +++ b/connections/implementation/endpoint_manager.cc @@ -207,7 +207,7 @@ ExceptionOr EndpointManager::TryDecryptFrame( if (decrypted.ok()) { VLOG(1) << "Message decrypted after " << SystemClock::ElapsedRealtime() - start_time; - return parser::FromBytes(decrypted.result()); + return parser::FromBytes(decrypted.result().AsStringView()); } if (decrypted.exception() == Exception::kExecution) { return decrypted.exception(); @@ -245,7 +245,8 @@ ExceptionOr EndpointManager::HandleData( } return ExceptionOr(bytes.exception()); } - ExceptionOr wrapped_frame = parser::FromBytes(bytes.result()); + ExceptionOr wrapped_frame = + parser::FromBytes(bytes.result().AsStringView()); if (!wrapped_frame.ok() && try_decrypting) { // Workaround for a race condition where the remote party has sent an // encrypted message but our end was still configured as unencrypted when @@ -668,7 +669,7 @@ std::vector EndpointManager::SendPayloadChunk( const PayloadTransferFrame::PayloadChunk& payload_chunk, const std::vector& endpoint_ids, PacketMetaData& packet_meta_data) { - ByteArray bytes = + std::string bytes = parser::ForDataPayloadTransfer(payload_header, payload_chunk); return SendTransferFrameBytes( @@ -743,7 +744,7 @@ std::vector EndpointManager::SendControlMessage( const PayloadTransferFrame::PayloadHeader& header, const PayloadTransferFrame::ControlMessage& control, const std::vector& endpoint_ids) { - ByteArray bytes = parser::ForControlPayloadTransfer(header, control); + std::string bytes = parser::ForControlPayloadTransfer(header, control); PacketMetaData packet_meta_data; return SendTransferFrameBytes( @@ -920,7 +921,7 @@ CountDownLatch EndpointManager::NotifyFrameProcessorsOnEndpointDisconnect( std::vector EndpointManager::SendPayloadAck( std::int64_t payload_id, const std::vector& endpoint_ids) { - ByteArray bytes = parser::ForPayloadAckPayloadTransfer(payload_id); + std::string bytes = parser::ForPayloadAckPayloadTransfer(payload_id); PacketMetaData packet_meta_data; return SendTransferFrameBytes( @@ -932,7 +933,7 @@ std::vector EndpointManager::SendPayloadAck( } std::vector EndpointManager::SendTransferFrameBytes( - const std::vector& endpoint_ids, const ByteArray& bytes, + const std::vector& endpoint_ids, const std::string& bytes, std::int64_t payload_id, std::int64_t offset, const std::string& packet_type, PacketMetaData& packet_meta_data) { std::vector failed_endpoint_ids; @@ -954,7 +955,7 @@ std::vector EndpointManager::SendTransferFrameBytes( } Exception write_exception = - channel->Write(bytes.AsStringView(), packet_meta_data); + channel->Write(bytes, packet_meta_data); if (!write_exception.Ok()) { failed_endpoint_ids.push_back(endpoint_id); LOG(INFO) << "Failed to send packet; endpoint_id=" << endpoint_id; diff --git a/connections/implementation/endpoint_manager.h b/connections/implementation/endpoint_manager.h index 8b2b0b81..68f7f4f9 100644 --- a/connections/implementation/endpoint_manager.h +++ b/connections/implementation/endpoint_manager.h @@ -16,7 +16,6 @@ #define CORE_INTERNAL_ENDPOINT_MANAGER_H_ #include -#include #include #include #include @@ -24,7 +23,6 @@ #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/time/time.h" #include "connections/implementation/analytics/packet_meta_data.h" @@ -283,7 +281,7 @@ class EndpointManager { std::vector SendTransferFrameBytes( const std::vector& endpoint_ids, - const ByteArray& payload_transfer_frame_bytes, std::int64_t payload_id, + const std::string& payload_transfer_frame_bytes, std::int64_t payload_id, std::int64_t offset, const std::string& packet_type, analytics::PacketMetaData& packet_meta_data); diff --git a/connections/implementation/endpoint_manager_test.cc b/connections/implementation/endpoint_manager_test.cc index d9a01b9a..aecd71ab 100644 --- a/connections/implementation/endpoint_manager_test.cc +++ b/connections/implementation/endpoint_manager_test.cc @@ -68,7 +68,7 @@ class MockEndpointChannel : public EndpointChannel { MOCK_METHOD(ExceptionOr, Read, (), (override)); MOCK_METHOD(ExceptionOr, Read, (PacketMetaData & packet_meta_data), (override)); - MOCK_METHOD(Exception, Write, (const ByteArray& data), (override)); + MOCK_METHOD(Exception, Write, (absl::string_view data), (override)); MOCK_METHOD(Exception, Write, (absl::string_view data, PacketMetaData& packet_meta_data), (override)); @@ -277,11 +277,12 @@ TEST_F(EndpointManagerTest, RegisterFrameProcessorWorks) { 0 /*keep_alive_interval_millis*/, 0 /*keep_alive_timeout_millis*/}; - auto read_data = parser::ForConnectionRequestConnections({}, connection_info); + std::string read_data = + parser::ForConnectionRequestConnections({}, connection_info); EXPECT_CALL(*connect_request, OnIncomingFrame); EXPECT_CALL(*connect_request, OnEndpointDisconnect); EXPECT_CALL(*endpoint_channel, Read(_)) - .WillOnce(Return(ExceptionOr(read_data))) + .WillOnce(Return(ExceptionOr(ByteArray(read_data)))) .WillRepeatedly(Return(ExceptionOr(Exception::kIo))); EXPECT_CALL(*endpoint_channel, Write(_)) .WillRepeatedly(Return(Exception{Exception::kSuccess})); @@ -429,7 +430,9 @@ class EndpointManagerFuzzTest auto InvalidPayloadDomain() { return Filter( - [](ByteArray payload) { return !parser::FromBytes(payload).ok(); }, + [](ByteArray payload) { + return !parser::FromBytes(payload.AsStringView()).ok(); + }, Map([](std::string payloadString) { return ByteArray(payloadString); }, String())); } @@ -461,7 +464,7 @@ TEST_F(EndpointManagerTest, TryDecrypt) { std::vector{Medium::BLE} /*supported_mediums*/, 0 /*keep_alive_interval_millis*/, 0 /*keep_alive_timeout_millis*/}; - ByteArray decrypted_data = + std::string decrypted_data = parser::ForConnectionRequestConnections({}, connection_info); EXPECT_CALL(*connect_request, OnIncomingFrame); EXPECT_CALL(*connect_request, OnEndpointDisconnect); @@ -470,7 +473,7 @@ TEST_F(EndpointManagerTest, TryDecrypt) { .WillRepeatedly(Return(ExceptionOr(Exception::kIo))); EXPECT_CALL(*endpoint_channel, TryDecrypt(Eq(payload))) .WillOnce(Return(ExceptionOr(Exception::kFailed))) - .WillOnce(Return(ExceptionOr(decrypted_data))); + .WillOnce(Return(ExceptionOr(ByteArray(decrypted_data)))); EXPECT_CALL(*endpoint_channel, Write(_)) .WillRepeatedly(Return(Exception{Exception::kSuccess})); em_.RegisterFrameProcessor(V1Frame::CONNECTION_REQUEST, diff --git a/connections/implementation/fake_bwu_handler.h b/connections/implementation/fake_bwu_handler.h index c26a91e6..fd1fb1dc 100644 --- a/connections/implementation/fake_bwu_handler.h +++ b/connections/implementation/fake_bwu_handler.h @@ -87,9 +87,9 @@ class FakeBwuHandler : public BaseBwuHandler { medium_, *handle_initialize_calls_[initialize_call_index].service_id); FakeEndpointChannel* upgraded_channel_raw = upgraded_channel.get(); upgraded_channel->set_read_output( - ExceptionOr(parser::ForBwuIntroduction( + ExceptionOr(ByteArray(parser::ForBwuIntroduction( *handle_initialize_calls_[initialize_call_index].endpoint_id, - false /* supports_disabling_encryption */))); + false /* supports_disabling_encryption */)))); auto connection = std::make_unique(); connection->channel = std::move(upgraded_channel); @@ -133,7 +133,7 @@ class FakeBwuHandler : public BaseBwuHandler { } // BaseBwuHandler: - ByteArray HandleInitializeUpgradedMediumForEndpoint( + std::string HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) final { handle_initialize_calls_.push_back({.client = client, @@ -188,7 +188,7 @@ class FakeBwuHandler : public BaseBwuHandler { case location::nearby::proto::connections::BLE_L2CAP: case location::nearby::proto::connections::USB: case location::nearby::proto::connections::AWDL: - return ByteArray{}; + return {}; } } diff --git a/connections/implementation/fake_endpoint_channel.h b/connections/implementation/fake_endpoint_channel.h index fa1bc3f7..9221147d 100644 --- a/connections/implementation/fake_endpoint_channel.h +++ b/connections/implementation/fake_endpoint_channel.h @@ -50,7 +50,7 @@ class FakeEndpointChannel : public EndpointChannel { read_timestamp_ = SystemClock::ElapsedRealtime(); return read_output_; } - Exception Write(const ByteArray& data) override { + Exception Write(absl::string_view data) override { write_timestamp_ = SystemClock::ElapsedRealtime(); return write_output_; } diff --git a/connections/implementation/fuzzers/BUILD b/connections/implementation/fuzzers/BUILD index 2ef4e0d5..2d0c0629 100644 --- a/connections/implementation/fuzzers/BUILD +++ b/connections/implementation/fuzzers/BUILD @@ -25,10 +25,9 @@ cc_test( tags = ["componentid:148515"], deps = [ "//connections/implementation:internal", - "//internal/platform:base", "//internal/platform/implementation/g3", - "//testing/fuzzing:fuzztest", "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_absl//absl/strings:string_view", "@com_google_googletest//:gtest_main", ], ) diff --git a/connections/implementation/fuzzers/offline_frames_fuzzer.cc b/connections/implementation/fuzzers/offline_frames_fuzzer.cc index 256f112c..5f3aaafe 100644 --- a/connections/implementation/fuzzers/offline_frames_fuzzer.cc +++ b/connections/implementation/fuzzers/offline_frames_fuzzer.cc @@ -12,13 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "absl/strings/string_view.h" #include "connections/implementation/offline_frames.h" -#include "internal/platform/byte_array.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - nearby::ByteArray byte_array; - byte_array.SetData(reinterpret_cast(data), size); - + absl::string_view byte_array(reinterpret_cast(data), size); nearby::connections::parser::FromBytes(byte_array); return 0; diff --git a/connections/implementation/mediums/multiplex/multiplex_socket_test.cc b/connections/implementation/mediums/multiplex/multiplex_socket_test.cc index 3b523d20..aba53de0 100644 --- a/connections/implementation/mediums/multiplex/multiplex_socket_test.cc +++ b/connections/implementation/mediums/multiplex/multiplex_socket_test.cc @@ -192,7 +192,7 @@ TEST(MultiplexSocketTest, CreateIncomingSocketSuccess) { SingleThreadExecutor executor; FakeSocket* socket = fake_socket_ptr.get(); executor.Execute([socket]() { - ByteArray connection_req_frame = parser::ForConnectionRequestConnections( + std::string connection_req_frame = parser::ForConnectionRequestConnections( {}, { .local_endpoint_id = "endpoint1", .local_endpoint_info = ByteArray("endpoint1 info"), @@ -200,7 +200,7 @@ TEST(MultiplexSocketTest, CreateIncomingSocketSuccess) { auto& writer = socket->writer_1_; LOG(INFO) << "writer_1_ Write start"; Base64Utils::WriteInt(writer.get(), connection_req_frame.size()); - writer->Write(connection_req_frame.AsStringView()); + writer->Write(connection_req_frame); writer->Flush(); LOG(INFO) << "writer_1_ Write end"; }); diff --git a/connections/implementation/offline_frames.cc b/connections/implementation/offline_frames.cc index 45b91311..aef8c3dd 100644 --- a/connections/implementation/offline_frames.cc +++ b/connections/implementation/offline_frames.cc @@ -19,6 +19,7 @@ #include #include +#include "absl/strings/string_view.h" #include "connections/connection_options.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/internal_payload.h" @@ -27,7 +28,6 @@ #include "connections/medium_selector.h" #include "connections/status.h" #include "internal/flags/nearby_flags.h" -#include "internal/platform/byte_array.h" #include "internal/platform/exception.h" #include "internal/platform/logging.h" #include "internal/platform/mac_address.h" @@ -49,19 +49,12 @@ using ::location::nearby::connections::OsInfo; using ::location::nearby::connections::PayloadTransferFrame; using ::location::nearby::connections::V1Frame; -ByteArray ToBytes(OfflineFrame&& frame) { - ByteArray bytes(frame.ByteSizeLong()); - frame.set_version(OfflineFrame::V1); - frame.SerializeToArray(bytes.data(), bytes.size()); - return bytes; -} - } // namespace -ExceptionOrOfflineFrame FromBytes(const ByteArray& bytes) { +ExceptionOrOfflineFrame FromBytes(absl::string_view bytes) { OfflineFrame frame; - if (frame.ParseFromString(std::string(bytes))) { + if (frame.ParseFromString(bytes)) { Exception validation_exception = EnsureValidOfflineFrame(frame); if (validation_exception.Raised()) { return ExceptionOrOfflineFrame(validation_exception); @@ -80,7 +73,7 @@ V1Frame::FrameType GetFrameType(const OfflineFrame& frame) { return V1Frame::UNKNOWN_FRAME_TYPE; } -ByteArray ForConnectionRequestConnections( +std::string ForConnectionRequestConnections( const location::nearby::connections::ConnectionsDevice& proto_connections_device, const ConnectionInfo& connection_info) { @@ -139,10 +132,10 @@ ByteArray ForConnectionRequestConnections( connection_info.keep_alive_timeout_millis); } - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForConnectionRequestPresence( +std::string ForConnectionRequestPresence( const location::nearby::connections::PresenceDevice& proto_presence_device, const ConnectionInfo& connection_info) { OfflineFrame frame; @@ -184,10 +177,10 @@ ByteArray ForConnectionRequestPresence( connection_info.keep_alive_timeout_millis); } - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForConnectionResponse(std::int32_t status, const OsInfo& os_info, +std::string ForConnectionResponse(std::int32_t status, const OsInfo& os_info, std::int32_t multiplex_socket_bitmask) { OfflineFrame frame; @@ -210,10 +203,10 @@ ByteArray ForConnectionResponse(std::int32_t status, const OsInfo& os_info, config_package_nearby::nearby_connections_feature:: kSafeToDisconnectVersion)); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForDataPayloadTransfer( +std::string ForDataPayloadTransfer( const PayloadTransferFrame::PayloadHeader& header, const PayloadTransferFrame::PayloadChunk& chunk) { OfflineFrame frame; @@ -226,10 +219,10 @@ ByteArray ForDataPayloadTransfer( *sub_frame->mutable_payload_header() = header; *sub_frame->mutable_payload_chunk() = chunk; - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForControlPayloadTransfer( +std::string ForControlPayloadTransfer( const PayloadTransferFrame::PayloadHeader& header, const PayloadTransferFrame::ControlMessage& control) { OfflineFrame frame; @@ -242,10 +235,10 @@ ByteArray ForControlPayloadTransfer( *sub_frame->mutable_payload_header() = header; *sub_frame->mutable_control_message() = control; - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForPayloadAckPayloadTransfer(std::int64_t payload_id) { +std::string ForPayloadAckPayloadTransfer(std::int64_t payload_id) { OfflineFrame frame; frame.set_version(OfflineFrame::V1); @@ -259,10 +252,10 @@ ByteArray ForPayloadAckPayloadTransfer(std::int64_t payload_id) { header.set_total_size(InternalPayload::kIndeterminateSize); *sub_frame->mutable_payload_header() = header; - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuWifiHotspotPathAvailable( +std::string ForBwuWifiHotspotPathAvailable( BandwidthUpgradeNegotiationFrame::UpgradePathInfo::WifiHotspotCredentials credentials, bool supports_disabling_encryption) { @@ -282,10 +275,10 @@ ByteArray ForBwuWifiHotspotPathAvailable( auto* wifi_hotspot_credentials = upgrade_path_info->mutable_wifi_hotspot_credentials(); *wifi_hotspot_credentials = std::move(credentials); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuWifiLanPathAvailable( +std::string ForBwuWifiLanPathAvailable( const std::vector& addresses) { OfflineFrame frame; @@ -314,10 +307,10 @@ ByteArray ForBwuWifiLanPathAvailable( VLOG(1) << "ForBwuWifiLanPathAvailable: " << address; } } - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuAwdlPathAvailable(const std::string& service_name, +std::string ForBwuAwdlPathAvailable(const std::string& service_name, const std::string& service_type, const std::string& password, bool supports_disabling_encryption) { @@ -339,10 +332,10 @@ ByteArray ForBwuAwdlPathAvailable(const std::string& service_name, awdl_socket->set_service_type(service_type); awdl_socket->set_password(password); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuWifiAwarePathAvailable(const std::string& service_id, +std::string ForBwuWifiAwarePathAvailable(const std::string& service_id, const std::string& service_info, const std::string& password, bool supports_disabling_encryption) { @@ -365,10 +358,10 @@ ByteArray ForBwuWifiAwarePathAvailable(const std::string& service_id, wifi_aware_credentials->set_service_info(service_info); if (!password.empty()) wifi_aware_credentials->set_password(password); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuWifiDirectPathAvailable( +std::string ForBwuWifiDirectPathAvailable( const std::string& ssid, const std::string& password, std::int32_t port, std::int32_t frequency, bool supports_disabling_encryption, const std::string& gateway, const std::string& service_name, @@ -396,10 +389,10 @@ ByteArray ForBwuWifiDirectPathAvailable( wifi_direct_credentials->set_service_name(service_name); wifi_direct_credentials->set_pin(pin); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuBluetoothPathAvailable(const std::string& service_id, +std::string ForBwuBluetoothPathAvailable(const std::string& service_id, MacAddress mac_address) { OfflineFrame frame; @@ -417,10 +410,10 @@ ByteArray ForBwuBluetoothPathAvailable(const std::string& service_id, bluetooth_credentials->set_mac_address(mac_address.ToString()); bluetooth_credentials->set_service_name(service_id); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuWebrtcPathAvailable(const std::string& peer_id, +std::string ForBwuWebrtcPathAvailable(const std::string& peer_id, const LocationHint& location_hint) { OfflineFrame frame; @@ -438,10 +431,10 @@ ByteArray ForBwuWebrtcPathAvailable(const std::string& peer_id, auto* local_location_hint = webrtc_credentials->mutable_location_hint(); *local_location_hint = location_hint; - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuLastWrite() { +std::string ForBwuLastWrite() { OfflineFrame frame; frame.set_version(OfflineFrame::V1); @@ -451,10 +444,10 @@ ByteArray ForBwuLastWrite() { sub_frame->set_event_type( BandwidthUpgradeNegotiationFrame::LAST_WRITE_TO_PRIOR_CHANNEL); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuSafeToClose() { +std::string ForBwuSafeToClose() { OfflineFrame frame; frame.set_version(OfflineFrame::V1); @@ -464,10 +457,10 @@ ByteArray ForBwuSafeToClose() { sub_frame->set_event_type( BandwidthUpgradeNegotiationFrame::SAFE_TO_CLOSE_PRIOR_CHANNEL); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuIntroduction(const std::string& endpoint_id, +std::string ForBwuIntroduction(const std::string& endpoint_id, bool supports_disabling_encryption) { OfflineFrame frame; @@ -482,10 +475,10 @@ ByteArray ForBwuIntroduction(const std::string& endpoint_id, client_introduction->set_supports_disabling_encryption( supports_disabling_encryption); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuIntroductionAck() { +std::string ForBwuIntroductionAck() { OfflineFrame frame; frame.set_version(OfflineFrame::V1); @@ -495,10 +488,10 @@ ByteArray ForBwuIntroductionAck() { sub_frame->set_event_type( BandwidthUpgradeNegotiationFrame::CLIENT_INTRODUCTION_ACK); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuFailure(const UpgradePathInfo& info) { +std::string ForBwuFailure(const UpgradePathInfo& info) { OfflineFrame frame; frame.set_version(OfflineFrame::V1); @@ -511,10 +504,10 @@ ByteArray ForBwuFailure(const UpgradePathInfo& info) { *sub_frame->mutable_upgrade_path_info() = info; - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForBwuPathRequest(const std::vector& mediums, +std::string ForBwuPathRequest(const std::vector& mediums, const MediumRole& medium_role) { OfflineFrame frame; @@ -533,10 +526,10 @@ ByteArray ForBwuPathRequest(const std::vector& mediums, upgrade_path_request->mutable_medium_meta_data()->mutable_medium_role(); role->MergeFrom(medium_role); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForKeepAlive() { +std::string ForKeepAlive() { OfflineFrame frame; frame.set_version(OfflineFrame::V1); @@ -544,10 +537,10 @@ ByteArray ForKeepAlive() { v1_frame->set_type(V1Frame::KEEP_ALIVE); v1_frame->mutable_keep_alive(); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForKeepAlive(bool ack, uint32_t seq_num) { +std::string ForKeepAlive(bool ack, uint32_t seq_num) { OfflineFrame frame; frame.set_version(OfflineFrame::V1); @@ -556,10 +549,10 @@ ByteArray ForKeepAlive(bool ack, uint32_t seq_num) { KeepAliveFrame* keep_alive = v1_frame->mutable_keep_alive(); keep_alive->set_ack(ack); keep_alive->set_seq_num(seq_num); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } -ByteArray ForDisconnection(bool request_safe_to_disconnect, +std::string ForDisconnection(bool request_safe_to_disconnect, bool ack_safe_to_disconnect) { OfflineFrame frame; @@ -570,7 +563,7 @@ ByteArray ForDisconnection(bool request_safe_to_disconnect, disconnection->set_request_safe_to_disconnect(request_safe_to_disconnect); disconnection->set_ack_safe_to_disconnect(ack_safe_to_disconnect); - return ToBytes(std::move(frame)); + return frame.SerializeAsString(); } diff --git a/connections/implementation/offline_frames.h b/connections/implementation/offline_frames.h index e8e4b7d9..bf7248b7 100644 --- a/connections/implementation/offline_frames.h +++ b/connections/implementation/offline_frames.h @@ -19,10 +19,10 @@ #include #include +#include "absl/strings/string_view.h" #include "connections/connection_options.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "connections/medium_selector.h" -#include "internal/platform/byte_array.h" #include "internal/platform/exception.h" #include "internal/platform/mac_address.h" #include "internal/platform/service_address.h" @@ -43,7 +43,7 @@ using WifiDirectAuthType = // Returns OfflineFrame if parser was able to understand it, or // Exception::kInvalidProtocolBuffer, if parser failed. ExceptionOr FromBytes( - const ByteArray& offline_frame_bytes); + absl::string_view offline_frame_bytes); // Returns FrameType of a parsed message, or // V1Frame::UNKNOWN_FRAME_TYPE, if frame contents is not recognized. @@ -51,49 +51,49 @@ location::nearby::connections::V1Frame::FrameType GetFrameType( const location::nearby::connections::OfflineFrame& offline_frame); // Builds Connection Request / Response messages. -ByteArray ForConnectionRequestConnections( +std::string ForConnectionRequestConnections( const location::nearby::connections::ConnectionsDevice& proto_connections_device, const ConnectionInfo& connection_info); -ByteArray ForConnectionRequestPresence( +std::string ForConnectionRequestPresence( const location::nearby::connections::PresenceDevice& proto_presence_device, const ConnectionInfo& connection_info); -ByteArray ForConnectionResponse( +std::string ForConnectionResponse( std::int32_t status, const location::nearby::connections::OsInfo& os_info, std::int32_t multiplex_socket_bitmask); // Builds Payload transfer messages. -ByteArray ForDataPayloadTransfer( +std::string ForDataPayloadTransfer( const location::nearby::connections::PayloadTransferFrame::PayloadHeader& header, const location::nearby::connections::PayloadTransferFrame::PayloadChunk& chunk); -ByteArray ForControlPayloadTransfer( +std::string ForControlPayloadTransfer( const location::nearby::connections::PayloadTransferFrame::PayloadHeader& header, const location::nearby::connections::PayloadTransferFrame::ControlMessage& control); -ByteArray ForPayloadAckPayloadTransfer(std::int64_t payload_id); +std::string ForPayloadAckPayloadTransfer(std::int64_t payload_id); // Builds Bandwidth Upgrade [BWU] messages. -ByteArray ForBwuIntroduction(const std::string& endpoint_id, +std::string ForBwuIntroduction(const std::string& endpoint_id, bool supports_disabling_encryption); -ByteArray ForBwuIntroductionAck(); -ByteArray ForBwuWifiHotspotPathAvailable( +std::string ForBwuIntroductionAck(); +std::string ForBwuWifiHotspotPathAvailable( location::nearby::connections::BandwidthUpgradeNegotiationFrame:: UpgradePathInfo::WifiHotspotCredentials credentials, bool supports_disabling_encryption); -ByteArray ForBwuWifiLanPathAvailable( +std::string ForBwuWifiLanPathAvailable( const std::vector& addresses); -ByteArray ForBwuAwdlPathAvailable(const std::string& service_name, +std::string ForBwuAwdlPathAvailable(const std::string& service_name, const std::string& service_type, const std::string& password, bool supports_disabling_encryption); -ByteArray ForBwuWifiAwarePathAvailable(const std::string& service_id, +std::string ForBwuWifiAwarePathAvailable(const std::string& service_id, const std::string& service_info, const std::string& password, bool supports_disabling_encryption); -ByteArray ForBwuWifiDirectPathAvailable(const std::string& ssid, +std::string ForBwuWifiDirectPathAvailable(const std::string& ssid, const std::string& password, std::int32_t port, std::int32_t frequency, @@ -101,21 +101,21 @@ ByteArray ForBwuWifiDirectPathAvailable(const std::string& ssid, const std::string& gateway, const std::string& service_name, const std::string& pin); -ByteArray ForBwuBluetoothPathAvailable(const std::string& service_id, +std::string ForBwuBluetoothPathAvailable(const std::string& service_id, MacAddress mac_address); -ByteArray ForBwuWebrtcPathAvailable( +std::string ForBwuWebrtcPathAvailable( const std::string& peer_id, const location::nearby::connections::LocationHint& location_hint_a); -ByteArray ForBwuFailure(const UpgradePathInfo& info); -ByteArray ForBwuPathRequest( +std::string ForBwuFailure(const UpgradePathInfo& info); +std::string ForBwuPathRequest( const std::vector& mediums, const location::nearby::connections::MediumRole& medium_role); -ByteArray ForBwuLastWrite(); -ByteArray ForBwuSafeToClose(); +std::string ForBwuLastWrite(); +std::string ForBwuSafeToClose(); -ByteArray ForKeepAlive(); -ByteArray ForKeepAlive(bool ack, uint32_t seq_num); -ByteArray ForDisconnection(bool request_safe_to_disconnect, +std::string ForKeepAlive(); +std::string ForKeepAlive(bool ack, uint32_t seq_num); +std::string ForDisconnection(bool request_safe_to_disconnect, bool ack_safe_to_disconnect); UpgradePathInfo::Medium MediumToUpgradePathInfoMedium(Medium medium); Medium UpgradePathInfoMediumToMedium(UpgradePathInfo::Medium medium); diff --git a/connections/implementation/offline_frames_test.cc b/connections/implementation/offline_frames_test.cc index e52099ef..10fc9f07 100644 --- a/connections/implementation/offline_frames_test.cc +++ b/connections/implementation/offline_frames_test.cc @@ -88,8 +88,7 @@ TEST(OfflineFramesTest, CanParseMessageFromBytes) { sub_frame->add_mediums(MediumToConnectionRequestMedium(medium)); } } - auto serialized_bytes = ByteArray(tx_message.SerializeAsString()); - auto ret_value = FromBytes(serialized_bytes); + auto ret_value = FromBytes(tx_message.SerializeAsString()); ASSERT_TRUE(ret_value.ok()); const auto& rx_message = ret_value.result(); EXPECT_THAT(rx_message, EqualsProto(tx_message)); @@ -141,8 +140,8 @@ TEST(OfflineFramesTest, CanGenerateLegacyConnectionRequest) { kMediums.begin(), kMediums.end()), kKeepAliveIntervalMillis, kKeepAliveTimeoutMillis}; - ByteArray bytes = ForConnectionRequestConnections({}, connection_info); - auto response = FromBytes(bytes); + auto response = + FromBytes(ForConnectionRequestConnections({}, connection_info)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -208,9 +207,8 @@ TEST(OfflineFramesTest, CanGenerateConnectionsConnectionRequest) { kKeepAliveIntervalMillis, kKeepAliveTimeoutMillis, medium_role}; - ByteArray bytes = - ForConnectionRequestConnections(connections_device, connection_info); - auto response = FromBytes(bytes); + auto response = FromBytes( + ForConnectionRequestConnections(connections_device, connection_info)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -268,9 +266,8 @@ TEST(OfflineFramesTest, CanGeneratePresenceConnectionRequest) { presence_device.set_endpoint_type( location::nearby::connections::PRESENCE_ENDPOINT); presence_device.set_device_name("TEST DEVICE"); - ByteArray bytes = - ForConnectionRequestPresence(presence_device, connection_info); - auto response = FromBytes(bytes); + auto response = + FromBytes(ForConnectionRequestPresence(presence_device, connection_info)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -336,9 +333,8 @@ TEST(OfflineFramesTest, location::nearby::connections::CONNECTIONS_ENDPOINT); connections_device.set_endpoint_info("XYZ"); - ByteArray bytes = - ForConnectionRequestConnections(connections_device, connection_info); - auto response = FromBytes(bytes); + auto response = FromBytes( + ForConnectionRequestConnections(connections_device, connection_info)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -365,9 +361,8 @@ TEST(OfflineFramesTest, CanGenerateConnectionResponse) { config_package_nearby::nearby_connections_feature:: kSafeToDisconnectVersion, 5); - ByteArray bytes = - ForConnectionResponse(1, os_info, /*multiplex_socket_bitmask=*/0x01); - auto response = FromBytes(bytes); + auto response = FromBytes( + ForConnectionResponse(1, os_info, /*multiplex_socket_bitmask=*/0x01)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -393,8 +388,7 @@ TEST(OfflineFramesTest, CanGenerateControlPayloadTransfer) { control_message: < event: PAYLOAD_CANCELED offset: 150 > > >)pb"; - ByteArray bytes = ForControlPayloadTransfer(header, control); - auto response = FromBytes(bytes); + auto response = FromBytes(ForControlPayloadTransfer(header, control)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -421,8 +415,7 @@ TEST(OfflineFramesTest, CanGenerateDataPayloadTransfer) { payload_chunk: < flags: 1 offset: 150 body: "payload data" > > >)pb"; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - auto response = FromBytes(bytes); + auto response = FromBytes(ForDataPayloadTransfer(header, chunk)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -439,8 +432,7 @@ TEST(OfflineFramesTest, CanGeneratePayloadAckPayloadTransfer) { payload_header: < id: 12345 total_size: -1 > > >)pb"; - ByteArray bytes = ForPayloadAckPayloadTransfer(12345); - auto response = FromBytes(bytes); + auto response = FromBytes(ForPayloadAckPayloadTransfer(12345)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -487,9 +479,8 @@ TEST(OfflineFramesTest, CanGenerateBwuWifiHotspotPathAvailable) { address_candidate = credentials.add_address_candidates(); address_candidate->set_ip_address(std::string("\xc0\xa8\x00\x01", 4)); address_candidate->set_port(5678); - ByteArray bytes = - ForBwuWifiHotspotPathAvailable(std::move(credentials), false); - auto response = FromBytes(bytes); + auto response = + FromBytes(ForBwuWifiHotspotPathAvailable(std::move(credentials), false)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -521,7 +512,7 @@ TEST(OfflineFramesTest, CanGenerateBwuWifiLanPathAvailable) { > > >)pb"; - ByteArray bytes = ForBwuWifiLanPathAvailable( + std::string bytes = ForBwuWifiLanPathAvailable( {ServiceAddress{ .address = {'\x2a', '\x00', '\x79', '\xe0', '\x2e', '\x87', '\x00', '\x06', '\xb7', '\x28', '\x67', '\x45', '\x7a', '\xdd', @@ -555,9 +546,8 @@ TEST(OfflineFramesTest, CanGenerateBwuAwdlPathAvailable) { > > >)pb"; - ByteArray bytes = ForBwuAwdlPathAvailable("service_name", "nearby_upgrade", - "password", true); - auto response = FromBytes(bytes); + auto response = FromBytes(ForBwuAwdlPathAvailable( + "service_name", "nearby_upgrade", "password", true)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -583,9 +573,9 @@ TEST(OfflineFramesTest, CanGenerateBwuWifiAwarePathAvailable) { > > >)pb"; - ByteArray bytes = ForBwuWifiAwarePathAvailable("service_id", "service_info", - "password", false); - auto response = FromBytes(bytes); + auto response = FromBytes( + ForBwuWifiAwarePathAvailable("service_id", "service_info", "password", + /*supports_disabling_encryption=*/false)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -615,10 +605,10 @@ TEST(OfflineFramesTest, CanGenerateBwuWifiDirectPathAvailable) { > > >)pb"; - ByteArray bytes = ForBwuWifiDirectPathAvailable( - "", "", 1000, 2412, false, "192.168.1.1", - "NC-WifiDirectTest", "b592f7d3"); - auto response = FromBytes(bytes); + auto response = FromBytes(ForBwuWifiDirectPathAvailable( + /*ssid=*/"", /*password=*/"", /*port=*/1000, /*frequency=*/2412, + /*supports_disabling_encryption=*/false, "192.168.1.1", + "NC-WifiDirectTest", "b592f7d3")); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -644,8 +634,8 @@ TEST(OfflineFramesTest, CanGenerateBwuBluetoothPathAvailable) { >)pb"; MacAddress mac_address; MacAddress::FromString("11:22:33:44:55:66", mac_address); - ByteArray bytes = ForBwuBluetoothPathAvailable("service", mac_address); - auto response = FromBytes(bytes); + auto response = + FromBytes(ForBwuBluetoothPathAvailable("service", mac_address)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -659,8 +649,7 @@ TEST(OfflineFramesTest, CanGenerateBwuLastWrite) { type: BANDWIDTH_UPGRADE_NEGOTIATION bandwidth_upgrade_negotiation: < event_type: LAST_WRITE_TO_PRIOR_CHANNEL > >)pb"; - ByteArray bytes = ForBwuLastWrite(); - auto response = FromBytes(bytes); + auto response = FromBytes(ForBwuLastWrite()); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -674,8 +663,7 @@ TEST(OfflineFramesTest, CanGenerateBwuSafeToClose) { type: BANDWIDTH_UPGRADE_NEGOTIATION bandwidth_upgrade_negotiation: < event_type: SAFE_TO_CLOSE_PRIOR_CHANNEL > >)pb"; - ByteArray bytes = ForBwuSafeToClose(); - auto response = FromBytes(bytes); + auto response = FromBytes(ForBwuSafeToClose()); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -695,9 +683,8 @@ TEST(OfflineFramesTest, CanGenerateBwuIntroduction) { > > >)pb"; - ByteArray bytes = ForBwuIntroduction( - std::string(kEndpointId), false /* supports_disabling_encryption */); - auto response = FromBytes(bytes); + auto response = FromBytes(ForBwuIntroduction( + std::string(kEndpointId), false /* supports_disabling_encryption */)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -711,8 +698,7 @@ TEST(OfflineFramesTest, CanGenerateKeepAlive) { type: KEEP_ALIVE keep_alive: <> >)pb"; - ByteArray bytes = ForKeepAlive(); - auto response = FromBytes(bytes); + auto response = FromBytes(ForKeepAlive()); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -729,9 +715,9 @@ TEST(OfflineFramesTest, CanGenerateDisconnection) { ack_safe_to_disconnect: true > >)pb"; - ByteArray bytes = ForDisconnection(/* request_safe_to_disconnect */ true, - /* ack_safe_to_disconnect */ true); - auto response = FromBytes(bytes); + auto response = + FromBytes(ForDisconnection(/* request_safe_to_disconnect */ true, + /* ack_safe_to_disconnect */ true)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); @@ -760,8 +746,7 @@ TEST(OfflineFramesTest, CanGenerateBwuPathRequest) { mediums.push_back(Medium::WIFI_HOTSPOT); MediumRole medium_role; medium_role.set_support_wifi_hotspot_client(true); - ByteArray bytes = ForBwuPathRequest(mediums, medium_role); - auto response = FromBytes(bytes); + auto response = FromBytes(ForBwuPathRequest(mediums, medium_role)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); diff --git a/connections/implementation/offline_frames_validator_test.cc b/connections/implementation/offline_frames_validator_test.cc index 7695b64c..0a1376d7 100644 --- a/connections/implementation/offline_frames_validator_test.cc +++ b/connections/implementation/offline_frames_validator_test.cc @@ -66,24 +66,24 @@ constexpr int kKeepAliveTimeoutMillis = 5000; class OfflineFramesConnectionRequestTest : public testing::Test { protected: - ConnectionInfo connection_info_{std::string(kEndpointId), - ByteArray{std::string(kEndpointName)}, - kNonce, - kSupports5ghz, - std::string(kBssid), - kApFrequency, - std::vector>( - kMediums.begin(), kMediums.end()), - kKeepAliveIntervalMillis, - kKeepAliveTimeoutMillis}; + ConnectionInfo connection_info_{ + std::string(kEndpointId), + ByteArray{std::string(kEndpointName)}, + kNonce, + kSupports5ghz, + std::string(kBssid), + kApFrequency, + std::vector(kMediums.begin(), kMediums.end()), + kKeepAliveIntervalMillis, + kKeepAliveTimeoutMillis}; }; TEST_F(OfflineFramesConnectionRequestTest, ValidatesAsOkWithValidConnectionRequestFrame) { OfflineFrame offline_frame; - ByteArray bytes = ForConnectionRequestConnections({}, connection_info_); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForConnectionRequestConnections({}, connection_info_); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -94,8 +94,8 @@ TEST_F(OfflineFramesConnectionRequestTest, ValidatesAsFailWithNullConnectionRequestFrame) { OfflineFrame offline_frame; - ByteArray bytes = ForConnectionRequestConnections({}, connection_info_); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForConnectionRequestConnections({}, connection_info_); + offline_frame.ParseFromString(bytes); auto* v1_frame = offline_frame.mutable_v1(); v1_frame->clear_connection_request(); @@ -110,8 +110,8 @@ TEST_F(OfflineFramesConnectionRequestTest, OfflineFrame offline_frame; connection_info_.local_endpoint_id = ""; - ByteArray bytes = ForConnectionRequestConnections({}, connection_info_); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForConnectionRequestConnections({}, connection_info_); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -121,9 +121,9 @@ TEST_F(OfflineFramesConnectionRequestTest, TEST_F(OfflineFramesConnectionRequestTest, ValidatesAsFailWithEmptyEndpointIdInConnectionRequestFrame) { connection_info_.local_endpoint_id = ""; - ByteArray bytes = ForConnectionRequestConnections({}, connection_info_); + std::string bytes = ForConnectionRequestConnections({}, connection_info_); location::nearby::connections::OfflineFrame frame; - frame.ParseFromString(bytes.AsStringView()); + frame.ParseFromString(bytes); frame.mutable_v1()->mutable_connection_request()->set_endpoint_id(""); ASSERT_TRUE(frame.v1().connection_request().has_endpoint_id()); @@ -140,8 +140,8 @@ TEST_F(OfflineFramesConnectionRequestTest, OfflineFrame offline_frame; connection_info_.local_endpoint_info = ByteArray{""}; - ByteArray bytes = ForConnectionRequestConnections({}, connection_info_); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForConnectionRequestConnections({}, connection_info_); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -153,8 +153,8 @@ TEST_F(OfflineFramesConnectionRequestTest, OfflineFrame offline_frame; connection_info_.bssid = ""; - ByteArray bytes = ForConnectionRequestConnections({}, connection_info_); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForConnectionRequestConnections({}, connection_info_); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -166,8 +166,8 @@ TEST_F(OfflineFramesConnectionRequestTest, OfflineFrame offline_frame; connection_info_.supported_mediums = {}; - ByteArray bytes = ForConnectionRequestConnections({}, connection_info_); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForConnectionRequestConnections({}, connection_info_); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -179,9 +179,9 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; OsInfo os_info; - ByteArray bytes = ForConnectionResponse(kStatusAccepted, os_info, + std::string bytes = ForConnectionResponse(kStatusAccepted, os_info, /*multiplex_socket_bitmask=*/0); - offline_frame.ParseFromString(std::string(bytes)); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -193,9 +193,9 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; OsInfo os_info; - ByteArray bytes = ForConnectionResponse(kStatusAccepted, os_info, + std::string bytes = ForConnectionResponse(kStatusAccepted, os_info, /*multiplex_socket_bitmask=*/0); - offline_frame.ParseFromString(std::string(bytes)); + offline_frame.ParseFromString(bytes); auto* v1_frame = offline_frame.mutable_v1(); v1_frame->clear_connection_response(); @@ -210,9 +210,9 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; OsInfo os_info; - ByteArray bytes = + std::string bytes = ForConnectionResponse(-1, os_info, /*multiplex_socket_bitmask=*/0); - offline_frame.ParseFromString(std::string(bytes)); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -234,8 +234,8 @@ TEST(OfflineFramesValidatorTest, ValidatesAsOkWithValidPayloadTransferFrame) { OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -259,8 +259,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -284,8 +284,8 @@ TEST(OfflineFramesValidatorTest, ValidatesAsOkTypeFileWithLegalFilePath) { OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -309,8 +309,8 @@ TEST(OfflineFramesValidatorTest, ValidatesAsFailedTypeFileWithIllegalFilePath) { OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -334,8 +334,8 @@ TEST(OfflineFramesValidatorTest, ValidatesAsOkTypeFileWithLegalParentFolder) { OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -360,8 +360,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -377,8 +377,8 @@ TEST(OfflineFramesValidatorTest, ValidatesAsFailWithNullPayloadTransferFrame) { OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto* v1_frame = offline_frame.mutable_v1(); v1_frame->clear_payload_transfer(); @@ -401,8 +401,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto* v1_frame = offline_frame.mutable_v1(); auto* payload_transfer = v1_frame->mutable_payload_transfer(); @@ -426,8 +426,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -447,8 +447,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto* v1_frame = offline_frame.mutable_v1(); auto* payload_transfer = v1_frame->mutable_payload_transfer(); @@ -472,8 +472,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -493,8 +493,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -514,8 +514,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); auto* v1_frame = offline_frame.mutable_v1(); auto* payload_transfer = v1_frame->mutable_payload_transfer(); auto* payload_chunk = payload_transfer->mutable_payload_chunk(); @@ -539,8 +539,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForControlPayloadTransfer(header, control); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForControlPayloadTransfer(header, control); + offline_frame.ParseFromString(bytes); auto* v1_frame = offline_frame.mutable_v1(); auto* payload_transfer = v1_frame->mutable_payload_transfer(); @@ -564,8 +564,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForControlPayloadTransfer(header, control); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForControlPayloadTransfer(header, control); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -584,8 +584,8 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; - ByteArray bytes = ForControlPayloadTransfer(header, control); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForControlPayloadTransfer(header, control); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -603,9 +603,9 @@ TEST(OfflineFramesValidatorTest, credentials.set_port(kPort); credentials.set_frequency(kHotspotFrequency); credentials.set_gateway(kWifiHotspotGateway); - ByteArray bytes = ForBwuWifiHotspotPathAvailable( + std::string bytes = ForBwuWifiHotspotPathAvailable( std::move(credentials), kSupportsDisablingEncryption); - offline_frame.ParseFromString(std::string(bytes)); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -628,9 +628,9 @@ TEST(OfflineFramesValidatorTest, candidate = credentials.mutable_address_candidates()->Add(); candidate->set_ip_address(std::string("\xc0\xa8\x00\x01", 4)); candidate->set_port(kPort); - ByteArray bytes = ForBwuWifiHotspotPathAvailable( + std::string bytes = ForBwuWifiHotspotPathAvailable( std::move(credentials), kSupportsDisablingEncryption); - offline_frame.ParseFromString(std::string(bytes)); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -650,9 +650,9 @@ TEST(OfflineFramesValidatorTest, candidate->set_ip_address(std::string( "\xfe\x80\x00\x00\x00\x00\x00\x00\x4d\xb2\xb3\x5c\x22\x03\x98\xa1", 12)); candidate->set_port(kPort); - ByteArray bytes = ForBwuWifiHotspotPathAvailable( + std::string bytes = ForBwuWifiHotspotPathAvailable( std::move(credentials), kSupportsDisablingEncryption); - offline_frame.ParseFromString(std::string(bytes)); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -671,9 +671,9 @@ TEST(OfflineFramesValidatorTest, auto* candidate = credentials.mutable_address_candidates()->Add(); candidate->set_ip_address(std::string( "\xfe\x80\x00\x00\x00\x00\x00\x00\x4d\xb2\xb3\x5c\x22\x03\x98\xa1", 16)); - ByteArray bytes = ForBwuWifiHotspotPathAvailable( + std::string bytes = ForBwuWifiHotspotPathAvailable( std::move(credentials), kSupportsDisablingEncryption); - offline_frame.ParseFromString(std::string(bytes)); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -689,8 +689,8 @@ TEST(OfflineFramesValidatorTest, kPort}, {{'\xc0', '\xa8', '\x00', '\x01'}, kPort}, }; - ByteArray bytes = ForBwuWifiLanPathAvailable(address_candidates); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = ForBwuWifiLanPathAvailable(address_candidates); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -708,9 +708,9 @@ TEST(OfflineFramesValidatorTest, credentials.set_port(kPort); credentials.set_frequency(kHotspotFrequency); credentials.set_gateway(kWifiHotspotGateway); - ByteArray bytes = ForBwuWifiHotspotPathAvailable( + std::string bytes = ForBwuWifiHotspotPathAvailable( std::move(credentials), kSupportsDisablingEncryption); - offline_frame.ParseFromString(std::string(bytes)); + offline_frame.ParseFromString(bytes); auto* v1_frame = offline_frame.mutable_v1(); v1_frame->clear_bandwidth_upgrade_negotiation(); @@ -723,11 +723,11 @@ TEST(OfflineFramesValidatorTest, TEST(OfflineFramesValidatorTest, ValidatesAsOkBandwidthUpgradeWifiDirect) { OfflineFrame offline_frame; - ByteArray bytes = ForBwuWifiDirectPathAvailable( + std::string bytes = ForBwuWifiDirectPathAvailable( std::string(kWifiDirectSsid), std::string(kWifiDirectPassword), kPort, kWifiDirectFrequency, kSupportsDisablingEncryption, std::string(kGateway), std::string(kWifiDirectServiceName), std::string(kWifiDirectPin)); - offline_frame.ParseFromString(std::string(bytes)); + offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -740,11 +740,11 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame_2; // Anything less than -1 is invalid - ByteArray bytes = ForBwuWifiDirectPathAvailable( + std::string bytes = ForBwuWifiDirectPathAvailable( std::string(kWifiDirectSsid), std::string(kWifiDirectPassword), kPort, -2, kSupportsDisablingEncryption, std::string(kGateway), std::string(kWifiDirectServiceName), std::string(kWifiDirectPin)); - offline_frame_1.ParseFromString(std::string(bytes)); + offline_frame_1.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame_1); @@ -755,7 +755,7 @@ TEST(OfflineFramesValidatorTest, std::string(kWifiDirectSsid), std::string(kWifiDirectPassword), kPort, -1, kSupportsDisablingEncryption, std::string(kGateway), std::string(kWifiDirectServiceName), std::string(kWifiDirectPin)); - offline_frame_2.ParseFromString(std::string(bytes)); + offline_frame_2.ParseFromString(bytes); ret_value = EnsureValidOfflineFrame(offline_frame_2); @@ -769,12 +769,12 @@ TEST(OfflineFramesValidatorTest, std::string wifi_direct_ssid{"DIRECT-A*-0123456789AB"}; std::string wifi_direct_pin_wrong_length = "abc"; - ByteArray bytes = ForBwuWifiDirectPathAvailable( + std::string bytes = ForBwuWifiDirectPathAvailable( wifi_direct_ssid, std::string(kWifiDirectPassword), kPort, kWifiDirectFrequency, kSupportsDisablingEncryption, std::string(kGateway), std::string(kWifiDirectServiceName), wifi_direct_pin_wrong_length); - offline_frame_1.ParseFromString(std::string(bytes)); + offline_frame_1.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame_1); @@ -790,7 +790,7 @@ TEST(OfflineFramesValidatorTest, kWifiDirectFrequency, kSupportsDisablingEncryption, std::string(kGateway), wifi_direct_service_name_wrong_length, std::string(kWifiDirectPin)); - offline_frame_2.ParseFromString(std::string(bytes)); + offline_frame_2.ParseFromString(bytes); ret_value = EnsureValidOfflineFrame(offline_frame_2); @@ -804,12 +804,12 @@ TEST(OfflineFramesValidatorTest, std::string short_wifi_direct_password{"Test"}; std::string short_wifi_direct_pin{"abc"}; - ByteArray bytes = ForBwuWifiDirectPathAvailable( + std::string bytes = ForBwuWifiDirectPathAvailable( std::string(kWifiDirectSsid), short_wifi_direct_password, kPort, kWifiDirectFrequency, kSupportsDisablingEncryption, std::string(kGateway), std::string(kWifiDirectServiceName), short_wifi_direct_pin); - offline_frame_1.ParseFromString(std::string(bytes)); + offline_frame_1.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame_1); @@ -826,7 +826,7 @@ TEST(OfflineFramesValidatorTest, kWifiDirectFrequency, kSupportsDisablingEncryption, std::string(kGateway), std::string(kWifiDirectServiceName), long_wifi_direct_pin); - offline_frame_2.ParseFromString(std::string(bytes)); + offline_frame_2.ParseFromString(bytes); ret_value = EnsureValidOfflineFrame(offline_frame_2); diff --git a/connections/implementation/payload_manager_test.cc b/connections/implementation/payload_manager_test.cc index 6605112c..612d69df 100644 --- a/connections/implementation/payload_manager_test.cc +++ b/connections/implementation/payload_manager_test.cc @@ -113,8 +113,8 @@ class PayloadSimulationUser : public SimulationUser { OfflineFrame offline_frame; - ByteArray bytes = parser::ForDataPayloadTransfer(header, chunk); - offline_frame.ParseFromString(std::string(bytes)); + std::string bytes = parser::ForDataPayloadTransfer(header, chunk); + offline_frame.ParseFromString(bytes); PacketMetaData packet_meta_data; diff --git a/connections/implementation/webrtc_bwu_handler.cc b/connections/implementation/webrtc_bwu_handler.cc index 6f1d07ce..50a38814 100644 --- a/connections/implementation/webrtc_bwu_handler.cc +++ b/connections/implementation/webrtc_bwu_handler.cc @@ -30,7 +30,6 @@ #include "connections/implementation/offline_frames.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "connections/implementation/webrtc_endpoint_channel.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" #include "internal/platform/logging.h" @@ -132,7 +131,7 @@ void WebrtcBwuHandler::HandleRevertInitiatorStateForService( // Called by BWU initiator. Set up WebRTC upgraded medium for this endpoint, // and returns a upgrade path info (PeerId, LocationHint) for remote party to // perform discovery. -ByteArray WebrtcBwuHandler::HandleInitializeUpgradedMediumForEndpoint( +std::string WebrtcBwuHandler::HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) { LocationHint location_hint = diff --git a/connections/implementation/webrtc_bwu_handler.h b/connections/implementation/webrtc_bwu_handler.h index c865420e..5220ef18 100644 --- a/connections/implementation/webrtc_bwu_handler.h +++ b/connections/implementation/webrtc_bwu_handler.h @@ -28,7 +28,6 @@ #include "connections/implementation/mediums/webrtc.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "connections/medium_selector.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" namespace nearby { @@ -69,7 +68,7 @@ class WebrtcBwuHandler : public BaseBwuHandler { const std::string& endpoint_id) final {} // BaseBwuHandler implementation: - ByteArray HandleInitializeUpgradedMediumForEndpoint( + std::string HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) final; void HandleRevertInitiatorStateForService( diff --git a/connections/implementation/webrtc_bwu_handler_stub.cc b/connections/implementation/webrtc_bwu_handler_stub.cc index 1b37f9e3..062ca77c 100644 --- a/connections/implementation/webrtc_bwu_handler_stub.cc +++ b/connections/implementation/webrtc_bwu_handler_stub.cc @@ -65,7 +65,7 @@ void WebrtcBwuHandler::HandleRevertInitiatorStateForService( // Called by BWU initiator. Set up WebRTC upgraded medium for this endpoint, // and returns a upgrade path info (PeerId, LocationHint) for remote party to // perform discovery. -ByteArray WebrtcBwuHandler::HandleInitializeUpgradedMediumForEndpoint( +std::string WebrtcBwuHandler::HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) { return {}; diff --git a/connections/implementation/webrtc_bwu_handler_stub.h b/connections/implementation/webrtc_bwu_handler_stub.h index f20b4898..6ee6635f 100644 --- a/connections/implementation/webrtc_bwu_handler_stub.h +++ b/connections/implementation/webrtc_bwu_handler_stub.h @@ -68,7 +68,7 @@ class WebrtcBwuHandler : public BaseBwuHandler { const std::string& endpoint_id) final {} // BaseBwuHandler implementation: - ByteArray HandleInitializeUpgradedMediumForEndpoint( + std::string HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) final; void HandleRevertInitiatorStateForService( diff --git a/connections/implementation/wifi_direct_bwu_handler.cc b/connections/implementation/wifi_direct_bwu_handler.cc index d637e0e4..ce314b09 100644 --- a/connections/implementation/wifi_direct_bwu_handler.cc +++ b/connections/implementation/wifi_direct_bwu_handler.cc @@ -28,7 +28,6 @@ #include "connections/implementation/wifi_direct_endpoint_channel.h" #include "connections/strategy.h" #include "internal/base/masker.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" #include "internal/platform/logging.h" #include "internal/platform/wifi_credential.h" @@ -49,7 +48,7 @@ WifiDirectBwuHandler::WifiDirectBwuHandler( // Called by BWU initiator. Set up WifiDirect upgraded medium for this // endpoint, and returns an upgrade path info (ServiceName, Pin for Wifi WPS, // Gateway used as IPAddress, Port) for remote party to perform connection. -ByteArray WifiDirectBwuHandler::HandleInitializeUpgradedMediumForEndpoint( +std::string WifiDirectBwuHandler::HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) { // Create WifiDirect GO diff --git a/connections/implementation/wifi_direct_bwu_handler.h b/connections/implementation/wifi_direct_bwu_handler.h index 34623d83..823edc12 100644 --- a/connections/implementation/wifi_direct_bwu_handler.h +++ b/connections/implementation/wifi_direct_bwu_handler.h @@ -24,7 +24,6 @@ #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/wifi_direct.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" #include "internal/platform/wifi_direct.h" @@ -73,7 +72,7 @@ class WifiDirectBwuHandler : public BaseBwuHandler { // Called by BWU initiator. Set up WifiDirect upgraded medium for this // endpoint, and returns a upgrade path info (SSID, Password, Gateway used as // IPAddress, Port) for remote party to perform connection. - ByteArray HandleInitializeUpgradedMediumForEndpoint( + std::string HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) final; diff --git a/connections/implementation/wifi_direct_bwu_test.cc b/connections/implementation/wifi_direct_bwu_test.cc index f9eed52f..e125c418 100644 --- a/connections/implementation/wifi_direct_bwu_test.cc +++ b/connections/implementation/wifi_direct_bwu_test.cc @@ -28,7 +28,6 @@ #include "connections/implementation/offline_frames.h" #include "connections/implementation/wifi_direct_bwu_handler.h" #include "internal/flags/nearby_flags.h" -#include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" #include "internal/platform/expected.h" @@ -98,10 +97,10 @@ TEST_F(WifiDirectTest, WFDGOBWUInit_GCCreateEndpointChannel) { SingleThreadExecutor wfd_go_executor; wfd_go_executor.Execute([&]() { - ByteArray upgrade_path_available_frame = + std::string upgrade_path_available_frame = wfd_go_bwu_handler->InitializeUpgradedMediumForEndpoint( &wifi_direct_go, std::string(kServiceID), std::string(kEndpointID)); - EXPECT_FALSE(upgrade_path_available_frame.Empty()); + EXPECT_FALSE(upgrade_path_available_frame.empty()); upgrade_frame = parser::FromBytes(upgrade_path_available_frame); start_latch.CountDown(); diff --git a/connections/implementation/wifi_hotspot_bwu_handler.cc b/connections/implementation/wifi_hotspot_bwu_handler.cc index f369a3aa..9d2da68d 100644 --- a/connections/implementation/wifi_hotspot_bwu_handler.cc +++ b/connections/implementation/wifi_hotspot_bwu_handler.cc @@ -37,7 +37,6 @@ #include "connections/implementation/wifi_hotspot_endpoint_channel.h" #include "connections/strategy.h" #include "internal/base/masker.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" #include "internal/platform/implementation/wifi_utils.h" #include "internal/platform/logging.h" @@ -74,7 +73,7 @@ WifiHotspotBwuHandler::WifiHotspotBwuHandler( // Called by BWU initiator. Set up WifiHotspot upgraded medium for this // endpoint, and returns a upgrade path info (SSID, Password, Gateway used as // IPAddress, Port) for remote party to perform connection. -ByteArray WifiHotspotBwuHandler::HandleInitializeUpgradedMediumForEndpoint( +std::string WifiHotspotBwuHandler::HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) { // Create SoftAP diff --git a/connections/implementation/wifi_hotspot_bwu_handler.h b/connections/implementation/wifi_hotspot_bwu_handler.h index a21705b9..9af42e93 100644 --- a/connections/implementation/wifi_hotspot_bwu_handler.h +++ b/connections/implementation/wifi_hotspot_bwu_handler.h @@ -24,7 +24,6 @@ #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/wifi_hotspot.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" #include "internal/platform/wifi_hotspot.h" @@ -68,7 +67,7 @@ class WifiHotspotBwuHandler : public BaseBwuHandler { }; // BaseBwuHandler implementation: - ByteArray HandleInitializeUpgradedMediumForEndpoint( + std::string HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) final; void HandleRevertInitiatorStateForService( diff --git a/connections/implementation/wifi_hotspot_bwu_test.cc b/connections/implementation/wifi_hotspot_bwu_test.cc index 125e4028..f1d300d6 100644 --- a/connections/implementation/wifi_hotspot_bwu_test.cc +++ b/connections/implementation/wifi_hotspot_bwu_test.cc @@ -27,7 +27,6 @@ #include "connections/implementation/offline_frames.h" #include "connections/implementation/wifi_hotspot_bwu_handler.h" #include "internal/flags/nearby_flags.h" -#include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" #include "internal/platform/expected.h" @@ -100,11 +99,11 @@ TEST_F(WifiHotspotTest, SoftAPBWUInit_STACreateEndpointChannel) { // client_hotspot_ap works as Hotspot SoftAP SingleThreadExecutor server_executor; server_executor.Execute([&]() { - ByteArray upgrade_path_available_frame = + std::string upgrade_path_available_frame = handler_1->InitializeUpgradedMediumForEndpoint( &client_hotspot_ap, std::string(kServiceID), std::string(kEndpointID)); - EXPECT_FALSE(upgrade_path_available_frame.Empty()); + EXPECT_FALSE(upgrade_path_available_frame.empty()); upgrade_frame = parser::FromBytes(upgrade_path_available_frame); start_latch.CountDown(); diff --git a/connections/implementation/wifi_lan_bwu_handler.cc b/connections/implementation/wifi_lan_bwu_handler.cc index 1a31c931..bedac087 100644 --- a/connections/implementation/wifi_lan_bwu_handler.cc +++ b/connections/implementation/wifi_lan_bwu_handler.cc @@ -27,7 +27,6 @@ #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/wifi_lan_endpoint_channel.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" #include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/logging.h" @@ -118,7 +117,7 @@ WifiLanBwuHandler::CreateUpgradedEndpointChannel( // Called by BWU initiator. Set up WifiLan upgraded medium for this endpoint, // and returns a upgrade path info (ip address, port) for remote party to // perform discovery. -ByteArray WifiLanBwuHandler::HandleInitializeUpgradedMediumForEndpoint( +std::string WifiLanBwuHandler::HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) { if (!wifi_lan_medium_.IsAcceptingConnections(upgrade_service_id)) { diff --git a/connections/implementation/wifi_lan_bwu_handler.h b/connections/implementation/wifi_lan_bwu_handler.h index 2e00bf79..abf0f26d 100644 --- a/connections/implementation/wifi_lan_bwu_handler.h +++ b/connections/implementation/wifi_lan_bwu_handler.h @@ -24,7 +24,6 @@ #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/wifi_lan.h" -#include "internal/platform/byte_array.h" #include "internal/platform/expected.h" #include "internal/platform/wifi_lan.h" @@ -68,7 +67,7 @@ class WifiLanBwuHandler : public BaseBwuHandler { }; // BaseBwuHandler implementation: - ByteArray HandleInitializeUpgradedMediumForEndpoint( + std::string HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) final; void HandleRevertInitiatorStateForService( diff --git a/connections/implementation/wifi_lan_bwu_handler_test.cc b/connections/implementation/wifi_lan_bwu_handler_test.cc index f6623db9..27d31a22 100644 --- a/connections/implementation/wifi_lan_bwu_handler_test.cc +++ b/connections/implementation/wifi_lan_bwu_handler_test.cc @@ -29,7 +29,6 @@ #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" @@ -271,12 +270,12 @@ TEST_F(WifiLanBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { address_candidate->set_port(8888); upgrade_path_info->set_supports_client_introduction_ack(true); - ByteArray result = handler_.InitializeUpgradedMediumForEndpoint( + std::string result = handler_.InitializeUpgradedMediumForEndpoint( &client, std::string(kServiceId), std::string(kEndpointId)); - EXPECT_FALSE(result.Empty()); + EXPECT_FALSE(result.empty()); OfflineFrame result_frame; - EXPECT_TRUE(result_frame.ParseFromString(std::string(result))); + EXPECT_TRUE(result_frame.ParseFromString(result)); EXPECT_THAT(result_frame, EqualsProto(expected_frame)); constexpr absl::string_view kClientSessionLog = R"pb( From b533dd834cf7156dffbb8f2db7971dd5f80ed4f3 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Thu, 16 Apr 2026 17:02:55 -0700 Subject: [PATCH 054/151] Fix tsan error. PiperOrigin-RevId: 900978318 --- connections/implementation/analytics/BUILD | 2 +- .../analytics/packet_meta_data.h | 17 +- .../analytics/throughput_recorder.cc | 363 ++++++++++-------- .../analytics/throughput_recorder.h | 202 ++++++---- .../analytics/throughput_recorder_test.cc | 170 ++++---- .../implementation/endpoint_manager.cc | 7 +- connections/implementation/payload_manager.cc | 31 +- 7 files changed, 428 insertions(+), 364 deletions(-) diff --git a/connections/implementation/analytics/BUILD b/connections/implementation/analytics/BUILD index 903272ff..019db88e 100644 --- a/connections/implementation/analytics/BUILD +++ b/connections/implementation/analytics/BUILD @@ -43,9 +43,9 @@ cc_library( "//proto:connections_enums_cc_proto", "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/base:no_destructor", "@com_google_absl//absl/container:btree", "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/meta:type_traits", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/time", diff --git a/connections/implementation/analytics/packet_meta_data.h b/connections/implementation/analytics/packet_meta_data.h index 09d2a85a..ea29c856 100644 --- a/connections/implementation/analytics/packet_meta_data.h +++ b/connections/implementation/analytics/packet_meta_data.h @@ -19,7 +19,6 @@ #include "absl/time/time.h" #include "internal/platform/implementation/system_clock.h" -#include "internal/platform/system_clock.h" namespace nearby { namespace analytics { @@ -35,7 +34,7 @@ struct PacketMetaData { void Reset() { file_io_start_time = SystemClock::ElapsedRealtime(); - socket_io_start_time = SystemClock::ElapsedRealtime(); + encryption_start_time = SystemClock::ElapsedRealtime(); socket_io_start_time = SystemClock::ElapsedRealtime(); packet_size = 0; } @@ -44,7 +43,7 @@ struct PacketMetaData { this->packet_size = packet_size; } - int GetPacketSize() { + int GetPacketSize() const { return packet_size; } @@ -72,27 +71,27 @@ struct PacketMetaData { socket_io_end_time = SystemClock::ElapsedRealtime(); } - int64_t GetEncryptionTimeInMillis() { + int64_t GetEncryptionTimeInMillis() const { if (encryption_end_time > encryption_start_time) { return absl::ToInt64Milliseconds(encryption_end_time - encryption_start_time); } - return 0L; + return 0; } - int64_t GetFileIoTimeInMillis() { + int64_t GetFileIoTimeInMillis() const { if (file_io_end_time > file_io_start_time) { return absl::ToInt64Milliseconds(file_io_end_time - file_io_start_time); } - return 0L; + return 0; } - int64_t GetSocketIoTimeInMillis() { + int64_t GetSocketIoTimeInMillis() const { if (socket_io_end_time > socket_io_start_time) { return absl::ToInt64Milliseconds(socket_io_end_time - socket_io_start_time); } - return 0L; + return 0; } }; diff --git a/connections/implementation/analytics/throughput_recorder.cc b/connections/implementation/analytics/throughput_recorder.cc index 7833d4ad..ab467d12 100644 --- a/connections/implementation/analytics/throughput_recorder.cc +++ b/connections/implementation/analytics/throughput_recorder.cc @@ -14,18 +14,17 @@ #include "connections/implementation/analytics/throughput_recorder.h" -#include - -#include -#include +#include +#include #include -#include #include +#include "absl/base/no_destructor.h" #include "absl/container/flat_hash_map.h" -#include "absl/meta/type_traits.h" #include "absl/strings/str_format.h" #include "absl/time/time.h" +#include "connections/implementation/analytics/packet_meta_data.h" +#include "connections/payload_type.h" #include "internal/platform/implementation/system_clock.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" @@ -33,61 +32,73 @@ namespace nearby { namespace analytics { +using Medium = ::location::nearby::proto::connections::Medium; +using ::nearby::connections::PayloadDirection; +using ::nearby::connections::PayloadType; + namespace { constexpr int kDefaultThroughoutKbps = 0; constexpr int kKbInBytes = 1024; constexpr int kSecInMs = 1000; + +int64_t CalculateThroughputKBps(int64_t total_byte_size, int64_t total_millis) { + if (total_millis > 0) { + return total_byte_size * kSecInMs / kKbInBytes / total_millis; + } + return kDefaultThroughoutKbps; +} + +int64_t CalculateThroughputMBps(int64_t throughputKBps) { + return throughputKBps / kKbInBytes; +} + +std::string ToString(PayloadType type) { + switch (type) { + case PayloadType::kBytes: + return std::string("Bytes"); + case PayloadType::kStream: + return std::string("Stream"); + case PayloadType::kFile: + return std::string("File"); + case PayloadType::kUnknown: + return std::string("Unknown"); + } +} } // namespace -ThroughputRecorder::ThroughputRecorder(int64_t payload_id) - : payload_id_(payload_id) {} - ThroughputRecorderContainer& ThroughputRecorderContainer::GetInstance() { - alignas(ThroughputRecorderContainer) static char - storage[sizeof(ThroughputRecorderContainer)]; - static ThroughputRecorderContainer* env = - new (&storage) ThroughputRecorderContainer(); - return *env; + static absl::NoDestructor instance; + return *instance; } -void ThroughputRecorder::Start(PayloadType payload_type, - PayloadDirection payload_direction) { - std::string direction = - (payload_direction == PayloadDirection::INCOMING_PAYLOAD) ? "; Receive" - : "; Send"; +ThroughputRecorderContainer::ThroughputRecorder::ThroughputRecorder( + int64_t payload_id, PayloadDirection payload_direction, + PayloadType payload_type) + : payload_id_(payload_id), + payload_direction_(payload_direction), + payload_type_(payload_type) { + LOG_IF(DFATAL, payload_type_ == PayloadType::kUnknown) + << "Invalid payload type"; +} - VLOG(1) << "Start TP profiling for payload_id:" << payload_id_ << direction; - - if (payload_type == PayloadType::kUnknown) { - VLOG(1) << "Ignore ThroughputRecorder::start for Unknown Payload type"; - return; +void ThroughputRecorderContainer::ThroughputRecorder::Start() { + if (VLOG_IS_ON(1)) { + std::string direction = + (payload_direction_ == PayloadDirection::INCOMING_PAYLOAD) ? "; Receive" + : "; Send"; + VLOG(1) << "Start TP profiling for payload_id:" << payload_id_ << direction; } - MutexLock lock(&mutex_); start_timestamp_ = SystemClock::ElapsedRealtime(); - payload_type_ = payload_type; - payload_direction_ = payload_direction; - // Add packetLostAlarm later } -bool ThroughputRecorder::Stop() { - MutexLock lock(&mutex_); +bool ThroughputRecorderContainer::ThroughputRecorder::Stop() { VLOG(1) << "Stop TP profiling for payload_id:" << payload_id_; - if (payload_type_ == PayloadType::kUnknown) { - VLOG(1) << "Ignore ThroughputRecorder::stop as it never start"; - return false; - } { - // Add packetLostAlarm stop process later absl::Time stop_timestamp = SystemClock::ElapsedRealtime(); int64_t total_byte_size = 0; int medium_size = throughputs_.size(); - // The worse case is the socket/connect blocking the write request, never - // got return when writing a frame out, it would get a very good data rate - // for this case. e.g. use 60 seconds to send a file and failed, the counter - // only get the duration as 30 seconds because the last write request - // blocked. if (!success_) { if (!throughputs_.empty()) { for (auto& tp : throughputs_) { @@ -96,9 +107,8 @@ bool ThroughputRecorder::Stop() { } } - // calculate throughput by medium for (auto& tp : throughputs_) { - tp.second.dump(); + tp.second.dump(payload_direction_, payload_type_); total_byte_size += tp.second.GetTotalByteSize(); } @@ -107,17 +117,16 @@ bool ThroughputRecorder::Stop() { int64_t total_millis = absl::ToInt64Milliseconds(stop_timestamp - start_timestamp_); throughput_kbps_ = CalculateThroughputKBps(total_byte_size, total_millis); - int throughput_mbps = CalculateThroughputMBps(throughput_kbps_); + int64_t throughput_mbps = CalculateThroughputMBps(throughput_kbps_); - // calculate overall throughput if there are multiple mediums if (medium_size > 1) { if (throughput_kbps_ != kDefaultThroughoutKbps) { std::string dump_content = absl::StrFormat( - "%s %s data(%d bytes) %s, overall used %d milliseconds, " + "%s %s data(%lld bytes) %s, overall used %lld milliseconds, " "throughput " - "is %d MB/s (%d KB/s), File IO takes %d ms, %s takes %d " + "is %lld MB/s (%lld KB/s), File IO takes %lld ms, %s takes %lld " "ms, " - "Socket IO takes %d ms", + "Socket IO takes %lld ms", (payload_direction_ == PayloadDirection::INCOMING_PAYLOAD) ? "Received" : "Sent", @@ -135,93 +144,79 @@ bool ThroughputRecorder::Stop() { return true; } -void ThroughputRecorder::MarkAsSuccess() { - MutexLock lock(&mutex_); +void ThroughputRecorderContainer::ThroughputRecorder::MarkAsSuccess() { success_ = true; } -int ThroughputRecorder::CalculateThroughputKBps(int64_t total_byte_size, - int64_t total_millis) { - if (total_millis > 0) { - return (int)(total_byte_size * kSecInMs / kKbInBytes / total_millis); - } - return kDefaultThroughoutKbps; -} - -int ThroughputRecorder::CalculateThroughputMBps(int throughputKBps) { - return throughputKBps / kKbInBytes; -} - -void ThroughputRecorder::Throughput::Add(int frame_size, int64_t file_io_time, - int64_t encryption_time, - int64_t socket_io_time) { +void ThroughputRecorderContainer::ThroughputRecorder::Throughput::Add( + int frame_size, int64_t file_io_time, int64_t encryption_time, + int64_t socket_io_time) { total_byte_size_ += frame_size; - // reset the last timestamp last_timestamp_ = SystemClock::ElapsedRealtime(); file_io_time_ += file_io_time; encryption_time_ += encryption_time; socket_io_time_ += socket_io_time; } -bool ThroughputRecorder::Throughput::dump() { +bool ThroughputRecorderContainer::ThroughputRecorder::Throughput::dump( + PayloadDirection payload_direction, PayloadType payload_type) { int64_t total_millis = absl::ToInt64Milliseconds(last_timestamp_ - start_timestamp_); - int throughput_kbps = CalculateThroughputKBps(total_byte_size_, total_millis); + int64_t throughput_kbps = + CalculateThroughputKBps(total_byte_size_, total_millis); if (throughput_kbps == kDefaultThroughoutKbps) { return false; } - int throughpu_mbps = CalculateThroughputMBps(throughput_kbps); + int64_t throughput_mbps = CalculateThroughputMBps(throughput_kbps); int64_t other = total_millis - file_io_time_ - encryption_time_ - socket_io_time_; std::string dump_content = absl::StrFormat( - "%s %s data(%ld bytes) via %s used %ld milliseconds, throughput is %d " - "MB/s (%d KB/s), File IO takes %ld ms, %s takes %ld ms, " - "Socket IO takes %ld ms, " - "Other takes %ld ms", - (payload_direction_ == PayloadDirection::INCOMING_PAYLOAD) ? "Received" - : "Sent", - ToString(payload_type_), total_byte_size_, + "%s %s data(%lld bytes) via %s used %lld ms, throughput is %lld " + "MB/s (%lld KB/s), File IO takes %lld ms, %s takes %lld ms, " + "Socket IO takes %lld ms, " + "Other takes %lld ms", + (payload_direction == PayloadDirection::INCOMING_PAYLOAD) ? "Received" + : "Sent", + ToString(payload_type), total_byte_size_, location::nearby::proto::connections::Medium_Name(medium_), total_millis, - throughpu_mbps, throughput_kbps, file_io_time_, - (payload_direction_ == PayloadDirection::INCOMING_PAYLOAD) ? "Decryption" - : "Encryption", + throughput_mbps, throughput_kbps, file_io_time_, + (payload_direction == PayloadDirection::INCOMING_PAYLOAD) ? "Decryption" + : "Encryption", encryption_time_, socket_io_time_, other); LOG(INFO) << dump_content; return true; } -ThroughputRecorder::Throughput& ThroughputRecorder::GetThroughput( +ThroughputRecorderContainer::ThroughputRecorder::Throughput& +ThroughputRecorderContainer::ThroughputRecorder::GetThroughput( Medium medium, int64_t duration_millis) { auto it = throughputs_.find(medium); if (it == throughputs_.end()) { - auto throughput = new Throughput( - medium, - SystemClock::ElapsedRealtime() - absl::Milliseconds(duration_millis), - payload_type_, payload_direction_); - throughputs_.emplace(medium, std::move(*throughput)); - delete throughput; + throughputs_.emplace( + medium, Throughput(medium, SystemClock::ElapsedRealtime() - + absl::Milliseconds(duration_millis))); return throughputs_.find(medium)->second; } return it->second; } -int ThroughputRecorder::GetThroughputsSize() { - MutexLock lock(&mutex_); +int ThroughputRecorderContainer::ThroughputRecorder::GetThroughputsSize() + const { return throughputs_.size(); } -int ThroughputRecorder::GetThroughputKbps() { return throughput_kbps_; } +int64_t ThroughputRecorderContainer::ThroughputRecorder::GetThroughputKbps() + const { + return throughput_kbps_; +} -int64_t ThroughputRecorder::GetDurationMillis() { return duration_millis_; } - -void ThroughputRecorder::OnFrameSent(Medium medium, - PacketMetaData& packetMetaData) { - MutexLock lock(&mutex_); - if (payload_type_ == PayloadType::kUnknown) { - VLOG(1) << "PayloadType is invalid, return"; - return; - } +int64_t ThroughputRecorderContainer::ThroughputRecorder::GetDurationMillis() + const { + return duration_millis_; +} +void ThroughputRecorderContainer::ThroughputRecorder::UpdateFrameData( + Medium medium, PacketMetaData& packetMetaData) { duration_millis_ = packetMetaData.GetEncryptionTimeInMillis() + packetMetaData.GetFileIoTimeInMillis() + packetMetaData.GetSocketIoTimeInMillis(); @@ -232,96 +227,69 @@ void ThroughputRecorder::OnFrameSent(Medium medium, CalculateDurationTimes(packetMetaData); } -void ThroughputRecorder::OnFrameReceived(Medium medium, - PacketMetaData& packetMetaData) { - MutexLock lock(&mutex_); - if (payload_type_ == PayloadType::kUnknown) { - VLOG(1) << "PayloadType is invalid, return"; - return; - } - - // Add packetLostAlarm process later - duration_millis_ = packetMetaData.GetEncryptionTimeInMillis() + - packetMetaData.GetFileIoTimeInMillis() + - packetMetaData.GetSocketIoTimeInMillis(); - GetThroughput(medium, duration_millis_) - .Add(packetMetaData.packet_size, packetMetaData.GetFileIoTimeInMillis(), - packetMetaData.GetEncryptionTimeInMillis(), - packetMetaData.GetSocketIoTimeInMillis()); - CalculateDurationTimes(packetMetaData); -} - -void ThroughputRecorder::CalculateDurationTimes(PacketMetaData packetMetaData) { +void ThroughputRecorderContainer::ThroughputRecorder::CalculateDurationTimes( + const PacketMetaData& packetMetaData) { encryption_time_ += packetMetaData.GetEncryptionTimeInMillis(); socket_io_time_ += packetMetaData.GetSocketIoTimeInMillis(); file_io_time_ += packetMetaData.GetFileIoTimeInMillis(); } -std::string ThroughputRecorder::ToString(PayloadType type) { - switch (type) { - case PayloadType::kBytes: - return std::string("Bytes"); - case PayloadType::kStream: - return std::string("Stream"); - case PayloadType::kFile: - return std::string("File"); - case PayloadType::kUnknown: - return std::string("Unknown"); +// Implementation for ThroughputRecorderContainer + +void ThroughputRecorderContainer::Start(int64_t payload_id, + PayloadDirection payload_direction, + PayloadType payload_type) { + if (payload_type == PayloadType::kUnknown) { + return; } -} - -// Inplementation for ThroughputRecorderContainer - -void ThroughputRecorderContainer::Shutdown() { - MutexLock lock(&mutex_); - VLOG(1) << __func__ << ". Num of Instance:" << throughput_recorders_.size(); - for (auto& throughput_recorder : throughput_recorders_) { - VLOG(1) << "Stop instance: " << throughput_recorder.second; - throughput_recorder.second->Stop(); - delete throughput_recorder.second; - } - throughput_recorders_.clear(); -} - -ThroughputRecorder* ThroughputRecorderContainer::GetTPRecorder( - const int64_t payload_id, PayloadDirection payload_direction) { MutexLock lock(&mutex_); auto it = throughput_recorders_.find( std::pair(payload_id, payload_direction)); if (it == throughput_recorders_.end()) { - auto instance = new ThroughputRecorder(payload_id); - std::string direction = - (payload_direction == PayloadDirection::INCOMING_PAYLOAD) ? "; Receive" - : "; Send"; - VLOG(1) << "Add ThroughputRecorder instance : " << instance - << " for payload_id:" << payload_id << direction; + auto instance = std::make_unique( + payload_id, payload_direction, payload_type); + instance->Start(); throughput_recorders_.emplace( std::pair(payload_id, payload_direction), - instance); - return instance; + std::move(instance)); + } else { + it->second->Start(); } - - return it->second; } -void ThroughputRecorderContainer::StopTPRecorder( - const int64_t payload_id, PayloadDirection payload_direction) { +void ThroughputRecorderContainer::UpdateFrameData( + int64_t payload_id, PayloadDirection payload_direction, Medium medium, + PacketMetaData& packet_meta_data) { MutexLock lock(&mutex_); - std::string direction = - (payload_direction == PayloadDirection::INCOMING_PAYLOAD) ? "; Receive" - : "; Send"; auto it = throughput_recorders_.find( std::pair(payload_id, payload_direction)); if (it != throughput_recorders_.end()) { - VLOG(1) << "Found and stop/delete ThroughputRecorder instance : " - << &(it->second) << " for payload_id:" << payload_id << direction; - it->second->Stop(); - delete it->second; - throughput_recorders_.erase( - std::pair(payload_id, payload_direction)); - return; + it->second->UpdateFrameData(medium, packet_meta_data); } - VLOG(1) << "No ThroughputRecorder found for :" << payload_id; +} + +void ThroughputRecorderContainer::MarkAsSuccess( + int64_t payload_id, PayloadDirection payload_direction) { + MutexLock lock(&mutex_); + auto it = throughput_recorders_.find( + std::pair(payload_id, payload_direction)); + if (it != throughput_recorders_.end()) { + it->second->MarkAsSuccess(); + } +} + +int64_t ThroughputRecorderContainer::StopTPRecorder( + int64_t payload_id, PayloadDirection payload_direction) { + MutexLock lock(&mutex_); + auto it = throughput_recorders_.find( + std::pair(payload_id, payload_direction)); + if (it != throughput_recorders_.end()) { + it->second->Stop(); + int64_t throughput_kbps = it->second->GetThroughputKbps(); + throughput_recorders_.erase(it); + return throughput_kbps; + } + return 0; } int ThroughputRecorderContainer::GetSize() { @@ -329,5 +297,66 @@ int ThroughputRecorderContainer::GetSize() { return throughput_recorders_.size(); } +void ThroughputRecorderContainer::ClearForTest() { + MutexLock lock(&mutex_); + throughput_recorders_.clear(); +} + +int64_t ThroughputRecorderContainer::GetTotalByteSizeForTesting( + int64_t payload_id, PayloadDirection payload_direction, Medium medium) { + MutexLock lock(&mutex_); + auto it = throughput_recorders_.find( + std::pair(payload_id, payload_direction)); + if (it != throughput_recorders_.end()) { + return it->second->GetThroughput(medium, 0).GetTotalByteSize(); + } + return 0; +} + +int ThroughputRecorderContainer::GetThroughputsSizeForTesting( + int64_t payload_id, PayloadDirection payload_direction) { + MutexLock lock(&mutex_); + auto it = throughput_recorders_.find( + std::pair(payload_id, payload_direction)); + if (it != throughput_recorders_.end()) { + return it->second->GetThroughputsSize(); + } + return 0; +} + +int64_t ThroughputRecorderContainer::GetDurationMillisForTesting( + int64_t payload_id, PayloadDirection payload_direction) { + MutexLock lock(&mutex_); + auto it = throughput_recorders_.find( + std::pair(payload_id, payload_direction)); + if (it != throughput_recorders_.end()) { + return it->second->GetDurationMillis(); + } + return 0; +} + +int64_t ThroughputRecorderContainer::GetThroughputKbpsForTesting( + int64_t payload_id, PayloadDirection payload_direction) { + MutexLock lock(&mutex_); + auto it = throughput_recorders_.find( + std::pair(payload_id, payload_direction)); + if (it != throughput_recorders_.end()) { + return it->second->GetThroughputKbps(); + } + return 0; +} + +bool ThroughputRecorderContainer::DumpForTesting( + int64_t payload_id, PayloadDirection payload_direction, Medium medium) { + MutexLock lock(&mutex_); + auto it = throughput_recorders_.find( + std::pair(payload_id, payload_direction)); + if (it != throughput_recorders_.end()) { + return it->second->GetThroughput(medium, 0).dump( + payload_direction, it->second->GetPayloadType()); + } + return false; +} + } // namespace analytics } // namespace nearby diff --git a/connections/implementation/analytics/throughput_recorder.h b/connections/implementation/analytics/throughput_recorder.h index e6dcdc05..f8dd5d19 100644 --- a/connections/implementation/analytics/throughput_recorder.h +++ b/connections/implementation/analytics/throughput_recorder.h @@ -16,125 +16,159 @@ #define NEARBY_CONNECTIONS_IMPLEMENTATION_ANALYTICS_THROUGHPUT_RECORDER_H_ #include -#include +#include #include +#include "absl/base/no_destructor.h" #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" #include "absl/time/time.h" #include "connections/implementation/analytics/packet_meta_data.h" #include "connections/payload_type.h" #include "internal/platform/mutex.h" -#include "proto/connections_enums.pb.h" namespace nearby { namespace analytics { -// The following aliases are only for users' convenience. -using ::location::nearby::proto::connections::Medium; -using ::nearby::connections::PayloadType; -// Enum to represent if a payload is incoming or outgoing. -using ::nearby::connections::PayloadDirection; - -class ThroughputRecorder { +// Container class to manage ThroughputRecorder instances. +// This class is a singleton and provides thread-safe proxy methods to record +// throughput for different payloads. +class ThroughputRecorderContainer { public: - explicit ThroughputRecorder(int64_t payload_id); - ~ThroughputRecorder() = default; + static ThroughputRecorderContainer& GetInstance(); - void Start(PayloadType payload_type, PayloadDirection payload_direction); - bool Stop() ABSL_LOCKS_EXCLUDED(mutex_); - static int CalculateThroughputKBps(int64_t total_byte_size, - int64_t total_millis); - static int CalculateThroughputMBps(int throughputKBps); + // Records the start of a payload transfer. + void Start(int64_t payload_id, + connections::PayloadDirection payload_direction, + connections::PayloadType payload_type) ABSL_LOCKS_EXCLUDED(mutex_); - class Throughput { + // Records when a frame is sent or received. + void UpdateFrameData(int64_t payload_id, + connections::PayloadDirection payload_direction, + location::nearby::proto::connections::Medium medium, + PacketMetaData& packet_meta_data) + ABSL_LOCKS_EXCLUDED(mutex_); + + // Marks a payload transfer as successful. + void MarkAsSuccess(int64_t payload_id, + connections::PayloadDirection payload_direction) + ABSL_LOCKS_EXCLUDED(mutex_); + + // Stops and removes the throughput recorder for a given payload. + // This calculates and logs the final throughput statistics. + // Returns the throughput in KBps. + int64_t StopTPRecorder(int64_t payload_id, + connections::PayloadDirection payload_direction) + ABSL_LOCKS_EXCLUDED(mutex_); + + // Returns the number of active recorder instances. + int GetSize() ABSL_LOCKS_EXCLUDED(mutex_); + + // Clear all recorders. Used for testing. + void ClearForTest() ABSL_LOCKS_EXCLUDED(mutex_); + + // Testing proxy methods + int64_t GetTotalByteSizeForTesting( + int64_t payload_id, connections::PayloadDirection payload_direction, + location::nearby::proto::connections::Medium medium) + ABSL_LOCKS_EXCLUDED(mutex_); + int GetThroughputsSizeForTesting( + int64_t payload_id, connections::PayloadDirection payload_direction) + ABSL_LOCKS_EXCLUDED(mutex_); + int64_t GetDurationMillisForTesting( + int64_t payload_id, connections::PayloadDirection payload_direction) + ABSL_LOCKS_EXCLUDED(mutex_); + int64_t GetThroughputKbpsForTesting( + int64_t payload_id, connections::PayloadDirection payload_direction) + ABSL_LOCKS_EXCLUDED(mutex_); + bool DumpForTesting(int64_t payload_id, + connections::PayloadDirection payload_direction, + location::nearby::proto::connections::Medium medium) + ABSL_LOCKS_EXCLUDED(mutex_); + + private: + friend class absl::NoDestructor; + + class ThroughputRecorder { public: - Throughput() = default; - ~Throughput() = default; - Throughput(Medium medium, absl::Time start_timestamp, - PayloadType payload_type, PayloadDirection payload_direction) - : medium_(medium), - start_timestamp_(start_timestamp), - payload_type_(payload_type), - payload_direction_(payload_direction) {} + ThroughputRecorder(int64_t payload_id, + connections::PayloadDirection payload_direction, + connections::PayloadType payload_type); + ~ThroughputRecorder() = default; - void Add(int frame_size, int64_t file_io_time, int64_t encryption_time, - int64_t socket_io_time); + void Start(); + bool Stop() ABSL_LOCKS_EXCLUDED(mutex_); - void SetLastTimestamp(absl::Time time_stamp) { - last_timestamp_ = time_stamp; - } + class Throughput { + public: + Throughput() = default; + ~Throughput() = default; + Throughput(location::nearby::proto::connections::Medium medium, + absl::Time start_timestamp) + : medium_(medium), start_timestamp_(start_timestamp) {} - int64_t GetTotalByteSize() { return total_byte_size_; } + void Add(int frame_size, int64_t file_io_time, int64_t encryption_time, + int64_t socket_io_time); - bool dump(); + void SetLastTimestamp(absl::Time time_stamp) { + last_timestamp_ = time_stamp; + } + + int64_t GetTotalByteSize() const { return total_byte_size_; } + + bool dump(connections::PayloadDirection payload_direction, + connections::PayloadType payload_type); + + private: + const ::location::nearby::proto::connections::Medium medium_; + const absl::Time start_timestamp_; + int64_t total_byte_size_ = 0; + absl::Time last_timestamp_; + int64_t file_io_time_ = 0; + int64_t encryption_time_ = 0; + int64_t socket_io_time_ = 0; + }; + + Throughput& GetThroughput( + location::nearby::proto::connections::Medium medium, + int64_t duration_millis); + int GetThroughputsSize() const; + int64_t GetThroughputKbps() const; + int64_t GetDurationMillis() const; + void UpdateFrameData(location::nearby::proto::connections::Medium medium, + PacketMetaData& packetMetaData); + void MarkAsSuccess(); + connections::PayloadType GetPayloadType() const { return payload_type_; } private: - Medium medium_; + void CalculateDurationTimes(const PacketMetaData& packetMetaData); + + const int64_t payload_id_; + const connections::PayloadDirection payload_direction_; + const connections::PayloadType payload_type_; absl::Time start_timestamp_; - PayloadType payload_type_; - int64_t total_byte_size_ = 0; - absl::Time last_timestamp_; - PayloadDirection payload_direction_ = PayloadDirection::INCOMING_PAYLOAD; + absl::flat_hash_map + throughputs_; + bool success_ = false; + int64_t file_io_time_ = 0; int64_t encryption_time_ = 0; int64_t socket_io_time_ = 0; + int64_t duration_millis_ = 0; + int64_t throughput_kbps_ = 0; }; - Throughput& GetThroughput(Medium medium, int64_t duration_millis); - int GetThroughputsSize(); - int GetThroughputKbps(); - int64_t GetDurationMillis(); - void OnFrameSent(Medium medium, PacketMetaData& packetMetaData); - void OnFrameReceived(Medium medium, PacketMetaData& packetMetaData); - void MarkAsSuccess(); - - private: - void CalculateDurationTimes(PacketMetaData packetMetaData); - static std::string ToString(PayloadType type); - - Mutex mutex_; - int64_t payload_id_ = 0; - absl::Time start_timestamp_; - PayloadType payload_type_ = PayloadType::kUnknown; - PayloadDirection payload_direction_ = PayloadDirection::INCOMING_PAYLOAD; - absl::flat_hash_map throughputs_; - bool success_ = false; - - int64_t file_io_time_ = 0; - int64_t encryption_time_ = 0; - int64_t socket_io_time_ = 0; - int64_t duration_millis_ = 0; - int throughput_kbps_ = 0; -}; - -class ThroughputRecorderContainer { - public: + ThroughputRecorderContainer() = default; ThroughputRecorderContainer(const ThroughputRecorderContainer&) = delete; ThroughputRecorderContainer& operator=(const ThroughputRecorderContainer&) = delete; - - static ThroughputRecorderContainer& GetInstance(); - void Shutdown() ABSL_LOCKS_EXCLUDED(mutex_); - - ThroughputRecorder* GetTPRecorder(int64_t payload_id, - PayloadDirection payload_direction) - ABSL_LOCKS_EXCLUDED(mutex_); - void StopTPRecorder(int64_t payload_id, PayloadDirection payload_direction) - ABSL_LOCKS_EXCLUDED(mutex_); - int GetSize() ABSL_LOCKS_EXCLUDED(mutex_); - - private: - // This is a singleton object, for which destructor will never be called. - // Constructor will be invoked once from Instance() static method. - // Object is create in-place (with a placement new) to guarantee that - // destructor is not scheduled for execution at exit. - ThroughputRecorderContainer() = default; ~ThroughputRecorderContainer() = default; Mutex mutex_; // std::pair for - absl::flat_hash_map, ThroughputRecorder*> + absl::flat_hash_map, + std::unique_ptr> throughput_recorders_ ABSL_GUARDED_BY(mutex_); }; diff --git a/connections/implementation/analytics/throughput_recorder_test.cc b/connections/implementation/analytics/throughput_recorder_test.cc index 8b31add3..c28d8c8d 100644 --- a/connections/implementation/analytics/throughput_recorder_test.cc +++ b/connections/implementation/analytics/throughput_recorder_test.cc @@ -16,35 +16,29 @@ #include -#include #include #include "gtest/gtest.h" #include "absl/time/clock.h" #include "absl/time/time.h" +#include "connections/implementation/analytics/packet_meta_data.h" +#include "connections/payload_type.h" #include "internal/platform/logging.h" #include "proto/connections_enums.pb.h" namespace nearby { namespace analytics { namespace { -// TODO(b/246693797): Add unit tests coverage for throughput recorder code constexpr int64_t kPayloadIdA = 123456789; constexpr int64_t kPayloadIdB = 987654321; constexpr int kFrameSize = 10 * 64 * 1024; -constexpr int64_t kTotalByteSize1GB = 1024 * 1024 * 1024; -constexpr int64_t kTotalMillis10Sec = 10 * 1000; -constexpr int kTPResultKBPerSec = 1024 * 1024 / 10; -constexpr int kTPKBPerSec = 100 * 1024; -constexpr int kTPResultMBPerSec = 100; -// class ThroughputRecorderTest : public testing::Test { class ThroughputRecorderTest : public testing::TestWithParam { protected: ThroughputRecorderTest() = default; ~ThroughputRecorderTest() override { - ThroughputRecorderContainer::GetInstance().Shutdown(); + ThroughputRecorderContainer::GetInstance().ClearForTest(); } ThroughputRecorderContainer& tp_recorder_container_ = @@ -54,70 +48,71 @@ class ThroughputRecorderTest : public testing::TestWithParam { INSTANTIATE_TEST_SUITE_P(ParametrisedTestThroughputRecorderTest, ThroughputRecorderTest, testing::Values(true, false)); -TEST(ThroughputRecorder, CalculateThroughputKBps) { - EXPECT_EQ(ThroughputRecorder::CalculateThroughputKBps(kTotalByteSize1GB, - kTotalMillis10Sec), - kTPResultKBPerSec); - EXPECT_EQ(ThroughputRecorder::CalculateThroughputKBps(kTotalByteSize1GB, 0), - 0); -} - -TEST(ThroughputRecorder, CalculateThroughputMBps) { - EXPECT_EQ(ThroughputRecorder::CalculateThroughputMBps(kTPKBPerSec), - kTPResultMBPerSec); -} - TEST(ThroughputRecorderContainer, InstanceCreate_ContainerSize) { ThroughputRecorderContainer& TPRecorderContainer = ThroughputRecorderContainer::GetInstance(); - TPRecorderContainer.GetTPRecorder(kPayloadIdA, - PayloadDirection::OUTGOING_PAYLOAD); - TPRecorderContainer.GetTPRecorder(kPayloadIdB, - PayloadDirection::INCOMING_PAYLOAD); + TPRecorderContainer.Start(kPayloadIdA, + connections::PayloadDirection::OUTGOING_PAYLOAD, + connections::PayloadType::kFile); + TPRecorderContainer.Start(kPayloadIdB, + connections::PayloadDirection::INCOMING_PAYLOAD, + connections::PayloadType::kFile); EXPECT_EQ(ThroughputRecorderContainer::GetInstance().GetSize(), 2); - ThroughputRecorderContainer::GetInstance().Shutdown(); + ThroughputRecorderContainer::GetInstance().ClearForTest(); EXPECT_EQ(ThroughputRecorderContainer::GetInstance().GetSize(), 0); } TEST_F(ThroughputRecorderTest, OnFrameSentSaveTransferredSize) { - auto TPRecorder = tp_recorder_container_.GetTPRecorder( - kPayloadIdA, PayloadDirection::OUTGOING_PAYLOAD); - TPRecorder->Start(PayloadType::kFile, PayloadDirection::OUTGOING_PAYLOAD); + tp_recorder_container_.Start(kPayloadIdA, + connections::PayloadDirection::OUTGOING_PAYLOAD, + connections::PayloadType::kFile); PacketMetaData packet_meta_data; packet_meta_data.SetPacketSize(kFrameSize); - TPRecorder->OnFrameSent(location::nearby::proto::connections::BLE, - packet_meta_data); - TPRecorder->OnFrameSent(location::nearby::proto::connections::BLE, - packet_meta_data); - TPRecorder->OnFrameSent(location::nearby::proto::connections::BLE, - packet_meta_data); + tp_recorder_container_.UpdateFrameData( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, + location::nearby::proto::connections::BLE, packet_meta_data); + tp_recorder_container_.UpdateFrameData( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, + location::nearby::proto::connections::BLE, packet_meta_data); + tp_recorder_container_.UpdateFrameData( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, + location::nearby::proto::connections::BLE, packet_meta_data); - auto throughput = - TPRecorder->GetThroughput(location::nearby::proto::connections::BLE, 0); - EXPECT_EQ(throughput.GetTotalByteSize(), kFrameSize * 3); + EXPECT_EQ(tp_recorder_container_.GetTotalByteSizeForTesting( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, + location::nearby::proto::connections::BLE), + kFrameSize * 3); } TEST_F(ThroughputRecorderTest, OnIgnoreUnkownPaylaodType) { - auto TPRecorder = tp_recorder_container_.GetTPRecorder( - kPayloadIdA, PayloadDirection::OUTGOING_PAYLOAD); - TPRecorder->Start(PayloadType::kUnknown, PayloadDirection::OUTGOING_PAYLOAD); + tp_recorder_container_.Start(kPayloadIdA, + connections::PayloadDirection::OUTGOING_PAYLOAD, + connections::PayloadType::kUnknown); PacketMetaData packet_meta_data; - TPRecorder->OnFrameSent(location::nearby::proto::connections::BLE, - packet_meta_data); - EXPECT_EQ(TPRecorder->GetThroughputsSize(), 0); + tp_recorder_container_.UpdateFrameData( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, + location::nearby::proto::connections::BLE, packet_meta_data); + EXPECT_EQ(tp_recorder_container_.GetThroughputsSizeForTesting( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD), + 0); - TPRecorder->Start(PayloadType::kUnknown, PayloadDirection::INCOMING_PAYLOAD); - TPRecorder->OnFrameReceived(location::nearby::proto::connections::BLE, - packet_meta_data); - EXPECT_EQ(TPRecorder->GetThroughputsSize(), 0); + tp_recorder_container_.Start(kPayloadIdA, + connections::PayloadDirection::INCOMING_PAYLOAD, + connections::PayloadType::kUnknown); + tp_recorder_container_.UpdateFrameData( + kPayloadIdA, connections::PayloadDirection::INCOMING_PAYLOAD, + location::nearby::proto::connections::BLE, packet_meta_data); + EXPECT_EQ(tp_recorder_container_.GetThroughputsSizeForTesting( + kPayloadIdA, connections::PayloadDirection::INCOMING_PAYLOAD), + 0); } TEST_P(ThroughputRecorderTest, OnFrameSentStopAndDump) { - auto TPRecorder = tp_recorder_container_.GetTPRecorder( - kPayloadIdA, PayloadDirection::OUTGOING_PAYLOAD); - TPRecorder->Start(PayloadType::kFile, PayloadDirection::OUTGOING_PAYLOAD); + tp_recorder_container_.Start(kPayloadIdA, + connections::PayloadDirection::OUTGOING_PAYLOAD, + connections::PayloadType::kFile); PacketMetaData packet_meta_data; packet_meta_data.SetPacketSize(kFrameSize); @@ -130,9 +125,11 @@ TEST_P(ThroughputRecorderTest, OnFrameSentStopAndDump) { packet_meta_data.StartSocketIo(); absl::SleepFor(absl::Milliseconds(7)); packet_meta_data.StopSocketIo(); - TPRecorder->OnFrameSent(location::nearby::proto::connections::BLE, - packet_meta_data); - EXPECT_EQ(TPRecorder->GetDurationMillis(), + tp_recorder_container_.UpdateFrameData( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, + location::nearby::proto::connections::BLE, packet_meta_data); + EXPECT_EQ(tp_recorder_container_.GetDurationMillisForTesting( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD), packet_meta_data.GetEncryptionTimeInMillis() + packet_meta_data.GetFileIoTimeInMillis() + packet_meta_data.GetSocketIoTimeInMillis()); @@ -147,21 +144,25 @@ TEST_P(ThroughputRecorderTest, OnFrameSentStopAndDump) { packet_meta_data.StartSocketIo(); absl::SleepFor(absl::Milliseconds(17)); packet_meta_data.StopSocketIo(); - TPRecorder->OnFrameSent(location::nearby::proto::connections::BLE, - packet_meta_data); + tp_recorder_container_.UpdateFrameData( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, + location::nearby::proto::connections::BLE, packet_meta_data); if (GetParam() == true) { LOG(INFO) << "MarkAsSuccess"; - TPRecorder->MarkAsSuccess(); + tp_recorder_container_.MarkAsSuccess( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD); } - EXPECT_TRUE(TPRecorder->Stop()); - EXPECT_NE(TPRecorder->GetThroughputKbps(), 0); + int throughput_kbps = tp_recorder_container_.StopTPRecorder( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD); + EXPECT_NE(throughput_kbps, 0); + EXPECT_EQ(tp_recorder_container_.GetSize(), 0); } TEST_F(ThroughputRecorderTest, OnFrameSentStopAndDumpForMultiMeadium) { - auto TPRecorder = tp_recorder_container_.GetTPRecorder( - kPayloadIdA, PayloadDirection::OUTGOING_PAYLOAD); - TPRecorder->Start(PayloadType::kFile, PayloadDirection::OUTGOING_PAYLOAD); + tp_recorder_container_.Start(kPayloadIdA, + connections::PayloadDirection::OUTGOING_PAYLOAD, + connections::PayloadType::kFile); PacketMetaData packet_meta_data1; packet_meta_data1.SetPacketSize(kFrameSize); @@ -174,8 +175,9 @@ TEST_F(ThroughputRecorderTest, OnFrameSentStopAndDumpForMultiMeadium) { packet_meta_data1.StartSocketIo(); absl::SleepFor(absl::Milliseconds(7)); packet_meta_data1.StopSocketIo(); - TPRecorder->OnFrameSent(location::nearby::proto::connections::BLE, - packet_meta_data1); + tp_recorder_container_.UpdateFrameData( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, + location::nearby::proto::connections::BLE, packet_meta_data1); PacketMetaData packet_meta_data2; packet_meta_data2.SetPacketSize(kFrameSize); @@ -188,18 +190,21 @@ TEST_F(ThroughputRecorderTest, OnFrameSentStopAndDumpForMultiMeadium) { packet_meta_data2.StartSocketIo(); absl::SleepFor(absl::Milliseconds(17)); packet_meta_data2.StopSocketIo(); - TPRecorder->OnFrameSent(location::nearby::proto::connections::WIFI_LAN, - packet_meta_data2); + tp_recorder_container_.UpdateFrameData( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, + location::nearby::proto::connections::WIFI_LAN, packet_meta_data2); - TPRecorder->MarkAsSuccess(); - EXPECT_TRUE(TPRecorder->Stop()); - EXPECT_NE(TPRecorder->GetThroughputKbps(), 0); + tp_recorder_container_.MarkAsSuccess( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD); + int throughput_kbps = tp_recorder_container_.StopTPRecorder( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD); + EXPECT_NE(throughput_kbps, 0); } TEST_F(ThroughputRecorderTest, OnFrameReceivedCheckDurationMillis) { - auto TPRecorder = tp_recorder_container_.GetTPRecorder( - kPayloadIdA, PayloadDirection::INCOMING_PAYLOAD); - TPRecorder->Start(PayloadType::kFile, PayloadDirection::INCOMING_PAYLOAD); + tp_recorder_container_.Start(kPayloadIdA, + connections::PayloadDirection::INCOMING_PAYLOAD, + connections::PayloadType::kFile); PacketMetaData packet_meta_data; packet_meta_data.SetPacketSize(kFrameSize); @@ -212,20 +217,23 @@ TEST_F(ThroughputRecorderTest, OnFrameReceivedCheckDurationMillis) { packet_meta_data.StartSocketIo(); absl::SleepFor(absl::Milliseconds(7)); packet_meta_data.StopSocketIo(); - TPRecorder->OnFrameReceived(location::nearby::proto::connections::BLE, - packet_meta_data); - EXPECT_EQ(TPRecorder->GetDurationMillis(), + tp_recorder_container_.UpdateFrameData( + kPayloadIdA, connections::PayloadDirection::INCOMING_PAYLOAD, + location::nearby::proto::connections::BLE, packet_meta_data); + EXPECT_EQ(tp_recorder_container_.GetDurationMillisForTesting( + kPayloadIdA, connections::PayloadDirection::INCOMING_PAYLOAD), packet_meta_data.GetEncryptionTimeInMillis() + packet_meta_data.GetFileIoTimeInMillis() + packet_meta_data.GetSocketIoTimeInMillis()); } TEST_F(ThroughputRecorderTest, OnTPRecorderNotStarted) { - auto TPRecorder = tp_recorder_container_.GetTPRecorder( - kPayloadIdA, PayloadDirection::OUTGOING_PAYLOAD); - auto throughput = - TPRecorder->GetThroughput(location::nearby::proto::connections::BLE, 0); - EXPECT_FALSE(throughput.dump()); + tp_recorder_container_.Start(kPayloadIdA, + connections::PayloadDirection::OUTGOING_PAYLOAD, + connections::PayloadType::kUnknown); + EXPECT_FALSE(tp_recorder_container_.DumpForTesting( + kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, + location::nearby::proto::connections::BLE)); } } // namespace diff --git a/connections/implementation/endpoint_manager.cc b/connections/implementation/endpoint_manager.cc index 1c950387..a93f4688 100644 --- a/connections/implementation/endpoint_manager.cc +++ b/connections/implementation/endpoint_manager.cc @@ -457,7 +457,6 @@ EndpointManager::~EndpointManager() { MutexLock lock(&mutex_); is_shutdown_ = true; } - analytics::ThroughputRecorderContainer::GetInstance().Shutdown(); CountDownLatch latch(1); RunOnEndpointManagerThread("bring-down-endpoints", [this, &latch]() { LOG(INFO) << "Bringing down endpoints"; @@ -961,9 +960,9 @@ std::vector EndpointManager::SendTransferFrameBytes( LOG(INFO) << "Failed to send packet; endpoint_id=" << endpoint_id; continue; } - analytics::ThroughputRecorderContainer::GetInstance() - .GetTPRecorder(payload_id, PayloadDirection::OUTGOING_PAYLOAD) - ->OnFrameSent(channel->GetMedium(), packet_meta_data); + analytics::ThroughputRecorderContainer::GetInstance().UpdateFrameData( + payload_id, PayloadDirection::OUTGOING_PAYLOAD, channel->GetMedium(), + packet_meta_data); } return failed_endpoint_ids; diff --git a/connections/implementation/payload_manager.cc b/connections/implementation/payload_manager.cc index 9dbf2521..5cd26943 100644 --- a/connections/implementation/payload_manager.cc +++ b/connections/implementation/payload_manager.cc @@ -209,10 +209,9 @@ bool PayloadManager::SendPayloadLoop( VLOG(1) << "Payload xfer done: payload_id=" << pending_payload.GetInternalPayload()->GetId() << "; size=" << next_chunk_offset; - ThroughputRecorderContainer::GetInstance() - .GetTPRecorder(pending_payload.GetInternalPayload()->GetId(), - PayloadDirection::OUTGOING_PAYLOAD) - ->MarkAsSuccess(); + ThroughputRecorderContainer::GetInstance().MarkAsSuccess( + pending_payload.GetInternalPayload()->GetId(), + PayloadDirection::OUTGOING_PAYLOAD); return false; } } @@ -364,7 +363,6 @@ void PayloadManager::DisconnectFromEndpointManager() { PayloadManager::~PayloadManager() { VLOG(1) << "PayloadManager: going down; self=" << this; - ThroughputRecorderContainer::GetInstance().Shutdown(); DisconnectFromEndpointManager(); CancelAllPayloads(); VLOG(1) << "PayloadManager: turn down payload executors; self=" << this; @@ -481,9 +479,8 @@ void PayloadManager::SendPayload(ClientProxy* client, std::int64_t next_chunk_offset = 0; int index = 0; - ThroughputRecorderContainer::GetInstance() - .GetTPRecorder(payload_id, PayloadDirection::OUTGOING_PAYLOAD) - ->Start(payload_type, PayloadDirection::OUTGOING_PAYLOAD); + ThroughputRecorderContainer::GetInstance().Start( + payload_id, PayloadDirection::OUTGOING_PAYLOAD, payload_type); while (should_continue && !shutdown_.Get()) { should_continue = SendPayloadLoop(client, *pending_payload, payload_header, @@ -1326,10 +1323,9 @@ void PayloadManager::ProcessDataPacket( Payload::Id payload_id = payload_header.id(); PendingPayloadHandle pending_payload; if (payload_chunk.offset() == 0) { - ThroughputRecorderContainer::GetInstance() - .GetTPRecorder(payload_id, PayloadDirection::INCOMING_PAYLOAD) - ->Start((PayloadType)payload_header.type(), - PayloadDirection::INCOMING_PAYLOAD); + ThroughputRecorderContainer::GetInstance().Start( + payload_id, PayloadDirection::INCOMING_PAYLOAD, + (PayloadType)payload_header.type()); packet_meta_data.Reset(); RunOnStatusUpdateThread( "process-data-packet", [to_client, from_endpoint_id, payload_header, @@ -1439,13 +1435,12 @@ void PayloadManager::ProcessDataPacket( payload_chunk.flags(), payload_chunk.offset(), payload_body_size); - ThroughputRecorderContainer::GetInstance() - .GetTPRecorder(payload_header.id(), PayloadDirection::INCOMING_PAYLOAD) - ->OnFrameReceived(medium, packet_meta_data); + ThroughputRecorderContainer::GetInstance().UpdateFrameData( + payload_header.id(), PayloadDirection::INCOMING_PAYLOAD, medium, + packet_meta_data); if (is_last_chunk) { - ThroughputRecorderContainer::GetInstance() - .GetTPRecorder(payload_header.id(), PayloadDirection::INCOMING_PAYLOAD) - ->MarkAsSuccess(); + ThroughputRecorderContainer::GetInstance().MarkAsSuccess( + payload_header.id(), PayloadDirection::INCOMING_PAYLOAD); } } From a7dd5feebb7ca908a07c9f47a86f48a9db7b86dc Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 20 Apr 2026 17:35:16 -0700 Subject: [PATCH 055/151] Automated Code Change PiperOrigin-RevId: 902903748 --- connections/implementation/client_proxy.cc | 18 ------ .../implementation/client_proxy_test.cc | 60 ++----------------- .../mediums/bluetooth_classic.cc | 8 +-- .../mediums/bluetooth_classic.h | 3 +- connections/implementation/mediums/wifi_lan.h | 6 +- .../implementation/mediums/wifi_lan_test.cc | 8 --- internal/platform/blocking_queue_stream.h | 4 +- .../platform/blocking_queue_stream_test.cc | 42 +++---------- 8 files changed, 16 insertions(+), 133 deletions(-) diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index a1a5ce88..f35d9f6d 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -1207,24 +1207,6 @@ OsInfo::OsType ClientProxy::OSNameToOsInfoType(api::OSName osName) { } std::int32_t ClientProxy::GetLocalMultiplexSocketBitmask() const { - if (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplex)) { - std::int32_t multiplex_bitmask = - (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexBluetooth) - ? kBtMultiplexEnabled - : 0) | - (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexWifiLan) - ? kWifiLanMultiplexEnabled - : 0); - LOG(INFO) << "ClientProxy [GetLocalMultiplexSocketBitmask]: " - << multiplex_bitmask; - return multiplex_bitmask; - } return 0; } diff --git a/connections/implementation/client_proxy_test.cc b/connections/implementation/client_proxy_test.cc index 172a58d8..5da9aabd 100644 --- a/connections/implementation/client_proxy_test.cc +++ b/connections/implementation/client_proxy_test.cc @@ -1484,51 +1484,10 @@ TEST_F(ClientProxyTest, TestAutoBwuWhenListeningWithAutoBwu) { } TEST_F(ClientProxyTest, TestMultiplexSocketBitmask) { - if (!NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplex)) { - EXPECT_EQ(client1()->GetLocalMultiplexSocketBitmask(), 0); - } - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature::kEnableMultiplex, - true); EXPECT_EQ(client1()->GetLocalMultiplexSocketBitmask(), 0); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexBluetooth, - true); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexWifiLan, - true); - EXPECT_EQ( - client1()->GetLocalMultiplexSocketBitmask(), - ClientProxy::kBtMultiplexEnabled | ClientProxy::kWifiLanMultiplexEnabled); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature::kEnableMultiplex, - false); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexBluetooth, - false); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexWifiLan, - false); } TEST_F(ClientProxyTest, TestRemoteMultiplexSocketBitmask) { - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature::kEnableMultiplex, - true); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexBluetooth, - true); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexWifiLan, - true); Endpoint advertising_endpoint = StartAdvertising(client1(), advertising_connection_listener_); OnAdvertisingConnectionInitiated(client1(), advertising_endpoint); @@ -1543,23 +1502,12 @@ TEST_F(ClientProxyTest, TestRemoteMultiplexSocketBitmask) { ->GetRemoteMultiplexSocketBitmask(advertising_endpoint.id) .value(), ClientProxy::kBtMultiplexEnabled | ClientProxy::kWifiLanMultiplexEnabled); - EXPECT_TRUE(client1()->IsMultiplexSocketSupported(advertising_endpoint.id, - Medium::BLUETOOTH)); - EXPECT_TRUE(client1()->IsMultiplexSocketSupported(advertising_endpoint.id, - Medium::WIFI_LAN)); + EXPECT_FALSE(client1()->IsMultiplexSocketSupported(advertising_endpoint.id, + Medium::BLUETOOTH)); + EXPECT_FALSE(client1()->IsMultiplexSocketSupported(advertising_endpoint.id, + Medium::WIFI_LAN)); EXPECT_FALSE(client1()->IsMultiplexSocketSupported(advertising_endpoint.id, Medium::WIFI_AWARE)); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature::kEnableMultiplex, - false); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexBluetooth, - false); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexWifiLan, - false); } TEST_F(ClientProxyTest, SaveClientInfoFromPreferences) { diff --git a/connections/implementation/mediums/bluetooth_classic.cc b/connections/implementation/mediums/bluetooth_classic.cc index 2ee55c30..f38dc278 100644 --- a/connections/implementation/mediums/bluetooth_classic.cc +++ b/connections/implementation/mediums/bluetooth_classic.cc @@ -65,13 +65,7 @@ BluetoothClassic::BluetoothClassic( : radio_(radio), adapter_(radio_.GetBluetoothAdapter()), medium_(std::move(medium)) { - is_multiplex_enabled_ = - NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplex) && - NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexBluetooth); + is_multiplex_enabled_ = false; } BluetoothClassic::~BluetoothClassic() { diff --git a/connections/implementation/mediums/bluetooth_classic.h b/connections/implementation/mediums/bluetooth_classic.h index d4221a1c..f16cf65f 100644 --- a/connections/implementation/mediums/bluetooth_classic.h +++ b/connections/implementation/mediums/bluetooth_classic.h @@ -236,8 +236,7 @@ class BluetoothClassic { discovery_callbacks_ ABSL_GUARDED_BY(discovery_callbacks_mutex_); // Whether the multiplex feature is enabled. - bool is_multiplex_enabled_ = NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature::kEnableMultiplex); + bool is_multiplex_enabled_ = false; // A map of Bluetooth MacAddress -> MultiplexSocket. absl::flat_hash_map diff --git a/connections/implementation/mediums/wifi_lan.h b/connections/implementation/mediums/wifi_lan.h index 990439ce..3637b158 100644 --- a/connections/implementation/mediums/wifi_lan.h +++ b/connections/implementation/mediums/wifi_lan.h @@ -219,11 +219,7 @@ class WifiLan { ABSL_GUARDED_BY(mutex_); // Whether the multiplex feature is enabled. - bool is_multiplex_enabled_ = NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature::kEnableMultiplex) && - NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexWifiLan); + bool is_multiplex_enabled_ = false; // A map of IpAddress -> MultiplexSocket. absl::flat_hash_map diff --git a/connections/implementation/mediums/wifi_lan_test.cc b/connections/implementation/mediums/wifi_lan_test.cc index 95bbfa5c..2f2ac8c9 100644 --- a/connections/implementation/mediums/wifi_lan_test.cc +++ b/connections/implementation/mediums/wifi_lan_test.cc @@ -168,11 +168,6 @@ TEST_P(WifiLanTest, CanConnect) { } TEST_P(WifiLanTest, CanConnectWithMultiplex) { - bool is_multiplex_enabled = NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature::kEnableMultiplex); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature::kEnableMultiplex, - true); bool is_multiplex_enabled_wifi_lan = NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature:: kEnableMultiplexWifiLan); @@ -235,9 +230,6 @@ TEST_P(WifiLanTest, CanConnectWithMultiplex) { EXPECT_TRUE(socket_for_server.IsValid()); EXPECT_TRUE(socket_for_client.IsValid()); env_.Stop(); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature::kEnableMultiplex, - is_multiplex_enabled); NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature:: kEnableMultiplexWifiLan, diff --git a/internal/platform/blocking_queue_stream.h b/internal/platform/blocking_queue_stream.h index 79030bc9..f898ce04 100644 --- a/internal/platform/blocking_queue_stream.h +++ b/internal/platform/blocking_queue_stream.h @@ -41,9 +41,7 @@ class BlockingQueueStream : public InputStream { private: mutable Mutex mutex_; - bool is_multiplex_enabled_ = NearbyFlags::GetInstance().GetBoolFlag( - connections::config_package_nearby::nearby_connections_feature:: - kEnableMultiplex); + bool is_multiplex_enabled_ = false; ArrayBlockingQueue blocking_queue_{ FeatureFlags::GetInstance() .GetFlags() diff --git a/internal/platform/blocking_queue_stream_test.cc b/internal/platform/blocking_queue_stream_test.cc index bf1d73ef..3064c002 100644 --- a/internal/platform/blocking_queue_stream_test.cc +++ b/internal/platform/blocking_queue_stream_test.cc @@ -24,47 +24,21 @@ namespace nearby { namespace { TEST(BlockingQueueStreamTest, ReadSuccess) { - bool is_multiplex_enabled = NearbyFlags::GetInstance().GetBoolFlag( - connections::config_package_nearby::nearby_connections_feature:: - kEnableMultiplex); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - connections::config_package_nearby::nearby_connections_feature:: - kEnableMultiplex, true); - - BlockingQueueStream stream; - ByteArray bytes = ByteArray("test1test2test3"); - stream.Write(bytes); - ExceptionOr result = stream.Read(5); - EXPECT_EQ(result.result(), ByteArray("test1")); - result = stream.Read(5); - EXPECT_EQ(result.result(), ByteArray("test2")); - result = stream.Read(5); - EXPECT_EQ(result.result(), ByteArray("test3")); - stream.Close(); - - NearbyFlags::GetInstance().OverrideBoolFlagValue( - connections::config_package_nearby::nearby_connections_feature:: - kEnableMultiplex, is_multiplex_enabled); -} - -TEST(BlockingQueueStreamTest, MultiplexDisabled) { - bool is_multiplex_enabled = NearbyFlags::GetInstance().GetBoolFlag( - connections::config_package_nearby::nearby_connections_feature:: - kEnableMultiplex); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - connections::config_package_nearby::nearby_connections_feature:: - kEnableMultiplex, false); - BlockingQueueStream stream; ByteArray bytes = ByteArray("test1test2test3"); stream.Write(bytes); ExceptionOr result = stream.Read(5); EXPECT_EQ(result, ExceptionOr(Exception::kExecution)); stream.Close(); +} - NearbyFlags::GetInstance().OverrideBoolFlagValue( - connections::config_package_nearby::nearby_connections_feature:: - kEnableMultiplex, is_multiplex_enabled); +TEST(BlockingQueueStreamTest, MultiplexDisabled) { + BlockingQueueStream stream; + ByteArray bytes = ByteArray("test1test2test3"); + stream.Write(bytes); + ExceptionOr result = stream.Read(5); + EXPECT_EQ(result, ExceptionOr(Exception::kExecution)); + stream.Close(); } } // namespace From c577ccaf4f5db23ef68639c62f7e13a0102cf562 Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 23 Apr 2026 21:01:07 -0700 Subject: [PATCH 056/151] Automated Code Change PiperOrigin-RevId: 904780249 --- .../platform/implementation/windows/BUILD | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index d9b860c6..b754eaf9 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -151,10 +151,7 @@ cc_library( "WINVER=_WIN32_WINNT_WIN10", ], tags = ["windows"], - visibility = [ - "//:__subpackages__", - "//location/nearby:__subpackages__", - ], + visibility = ["//:__subpackages__"], deps = [ ":socket_address", ":string_utils", @@ -175,10 +172,7 @@ cc_library( ], compatible_with = ["//buildenv/target:non_prod"], tags = ["windows"], - visibility = [ - "//:__subpackages__", - "//location/nearby:__subpackages__", - ], + visibility = ["//location/nearby:__subpackages__"], ) cc_library( @@ -191,10 +185,7 @@ cc_library( ], compatible_with = ["//buildenv/target:non_prod"], tags = ["windows"], - visibility = [ - "//:__subpackages__", - "//location/nearby:__subpackages__", - ], + visibility = ["//location/nearby:__subpackages__"], deps = [ ":scoped_wlan_memory", "//internal/platform:logging", @@ -413,9 +404,7 @@ cc_library( "WINVER=_WIN32_WINNT_WIN10", ], tags = ["windows"], - visibility = [ - "//:__subpackages__", - ], + visibility = ["//visibility:private"], deps = [ "//internal/platform:base", "//internal/platform:logging", From 04022d0db357a684b8e8edbc5ea7540b7acd8c14 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Fri, 24 Apr 2026 02:06:26 -0700 Subject: [PATCH 057/151] Refactor MediumEnvironment to improve FakeClock usage. PiperOrigin-RevId: 904891357 --- .../analytics/analytics_recorder_test.cc | 371 +++++++++--------- .../implementation/client_proxy_test.cc | 5 +- .../ble/discovered_peripheral_tracker_test.cc | 21 +- .../implementation/g3/scheduled_executor.cc | 35 +- .../implementation/g3/system_clock.cc | 17 +- internal/platform/medium_environment.cc | 55 ++- internal/platform/medium_environment.h | 11 +- internal/platform/scheduled_executor_test.cc | 32 +- internal/test/fake_clock.cc | 4 + internal/test/fake_clock.h | 1 + internal/test/fake_clock_test.cc | 3 +- 11 files changed, 277 insertions(+), 278 deletions(-) diff --git a/connections/implementation/analytics/analytics_recorder_test.cc b/connections/implementation/analytics/analytics_recorder_test.cc index c431e862..5b46b4ea 100644 --- a/connections/implementation/analytics/analytics_recorder_test.cc +++ b/connections/implementation/analytics/analytics_recorder_test.cc @@ -151,10 +151,6 @@ class AnalyticsRecorderTest : public ::testing::Test { } void TearDown() override { MediumEnvironment::Instance().Stop(); } - - FakeClock& GetFakeClock() const { - return *MediumEnvironment::Instance().GetSimulatedClock().value(); - } }; // Test if session_was_logged_ is reset by checking if LogSession can take @@ -190,19 +186,19 @@ TEST_F(AnalyticsRecorderTest, SetFieldsCorrectlyForNestedAdvertisingCalls) { analytics_recorder.BuildAdvertisingMetadataParams(); advertising_metadata_params->operation_result_with_mediums = { operation_result}; - GetFakeClock().FastForward(absl::Milliseconds(50)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(50)); analytics_recorder.OnStartAdvertising(strategy, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStopAdvertising(); operation_result.set_medium(BLE); advertising_metadata_params->operation_result_with_mediums = { operation_result}; - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnStartAdvertising(strategy, /*mediums=*/{BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -273,16 +269,16 @@ TEST_F(AnalyticsRecorderTest, SetFieldsCorrectlyForNestedDiscoveryCalls) { /*is_extended_advertisement_supported*/ true, /*connected_ap_frequency*/ 1, /*is_nfc_available=*/false, {operation_result, operation_result2}); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartDiscovery(strategy, /*mediums=*/{BLE, BLUETOOTH}, discovery_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnStopDiscovery(); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnEndpointFound(BLUETOOTH); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnEndpointFound(BLE); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); auto discovery_metadata_params2 = analytics_recorder.BuildDiscoveryMetadataParams( @@ -291,7 +287,7 @@ TEST_F(AnalyticsRecorderTest, SetFieldsCorrectlyForNestedDiscoveryCalls) { {operation_result}); analytics_recorder.OnStartDiscovery(strategy, /*mediums=*/{BLUETOOTH}, discovery_metadata_params2.get()); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -307,14 +303,8 @@ TEST_F(AnalyticsRecorderTest, SetFieldsCorrectlyForNestedDiscoveryCalls) { duration_millis: 200 medium: BLE medium: BLUETOOTH - discovered_endpoint { - medium: BLUETOOTH - latency_millis: 500 - } - discovered_endpoint { - medium: BLE - latency_millis: 900 - } + discovered_endpoint { medium: BLUETOOTH latency_millis: 500 } + discovered_endpoint { medium: BLE latency_millis: 900 } discovery_metadata { supports_extended_ble_advertisements: true connected_ap_frequency: 1 @@ -364,38 +354,38 @@ TEST_F(AnalyticsRecorderTest, auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(strategy, mediums, advertising_metadata_params.get()); auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnStartDiscovery(strategy, mediums, discovery_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnStopAdvertising(); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnStopDiscovery(); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnStartAdvertising(strategy, mediums, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.OnStopAdvertising(); - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.OnStartDiscovery(strategy, mediums, discovery_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(800)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); analytics_recorder.OnStopDiscovery(); - GetFakeClock().FastForward(absl::Milliseconds(900)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); analytics_recorder.OnStartDiscovery(strategy, mediums, {}); - GetFakeClock().FastForward(absl::Milliseconds(1000)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1000)); analytics_recorder.OnStartAdvertising(strategy, mediums, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(1100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1100)); analytics_recorder.OnStopDiscovery(); - GetFakeClock().FastForward(absl::Milliseconds(1200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1200)); analytics_recorder.OnStopAdvertising(); - GetFakeClock().FastForward(absl::Milliseconds(1300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1300)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -503,35 +493,35 @@ TEST_F(AnalyticsRecorderTest, AdvertiserConnectionRequestsWorks) { analytics_recorder.BuildAdvertisingMetadataParams(); advertising_metadata_params->operation_result_with_mediums = { operation_result}; - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnConnectionRequestReceived(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnLocalEndpointAccepted(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnConnectionRequestReceived(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.OnRemoteEndpointRejected(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(800)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); analytics_recorder.OnConnectionRequestReceived(endpoint_id_2); - GetFakeClock().FastForward(absl::Milliseconds(900)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); analytics_recorder.OnLocalEndpointRejected(endpoint_id_2); - GetFakeClock().FastForward(absl::Milliseconds(1000)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1000)); analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_2); - GetFakeClock().FastForward(absl::Milliseconds(1100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1100)); analytics_recorder.OnConnectionRequestReceived(endpoint_id_3); - GetFakeClock().FastForward(absl::Milliseconds(1200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1200)); analytics_recorder.OnLocalEndpointRejected(endpoint_id_3); - GetFakeClock().FastForward(absl::Milliseconds(1300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1300)); analytics_recorder.OnRemoteEndpointRejected(endpoint_id_3); - GetFakeClock().FastForward(absl::Milliseconds(1400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1400)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -606,36 +596,36 @@ TEST_F(AnalyticsRecorderTest, DiscoveryConnectionRequestsWorks) { auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); discovery_metadata_params->operation_result_with_mediums = {operation_result}; - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, discovery_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnConnectionRequestSent(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnLocalEndpointAccepted(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnConnectionRequestSent(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.OnRemoteEndpointRejected(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(800)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); analytics_recorder.OnConnectionRequestSent(endpoint_id_2); - GetFakeClock().FastForward(absl::Milliseconds(900)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); analytics_recorder.OnLocalEndpointRejected(endpoint_id_2); - GetFakeClock().FastForward(absl::Milliseconds(1000)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1000)); analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_2); - GetFakeClock().FastForward(absl::Milliseconds(1100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1100)); analytics_recorder.OnConnectionRequestSent(endpoint_id_3); - GetFakeClock().FastForward(absl::Milliseconds(1200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1200)); analytics_recorder.OnLocalEndpointRejected(endpoint_id_3); - GetFakeClock().FastForward(absl::Milliseconds(1300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1300)); analytics_recorder.OnRemoteEndpointRejected(endpoint_id_3); - GetFakeClock().FastForward(absl::Milliseconds(1400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1400)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -712,26 +702,26 @@ TEST_F(AnalyticsRecorderTest, analytics_recorder.BuildAdvertisingMetadataParams(); advertising_metadata_params->operation_result_with_mediums = { operation_result}; - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); // Ignored by local. - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnConnectionRequestReceived(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); // Ignored by remote. analytics_recorder.OnConnectionRequestReceived(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); // Ignored by both. analytics_recorder.OnConnectionRequestReceived(endpoint_id_2); - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -801,27 +791,27 @@ TEST_F(AnalyticsRecorderTest, auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); discovery_metadata_params->operation_result_with_mediums = {operation_result}; - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, discovery_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); // Ignored by local. analytics_recorder.OnConnectionRequestSent(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); // Ignored by remote. analytics_recorder.OnConnectionRequestSent(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); // Ignored by both. analytics_recorder.OnConnectionRequestSent(endpoint_id_2); - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -887,7 +877,7 @@ TEST_F(AnalyticsRecorderTest, SuccessfulIncomingConnectionAttempt) { analytics_recorder.BuildAdvertisingMetadataParams(); advertising_metadata_params->operation_result_with_mediums = { operation_result}; - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); @@ -896,13 +886,13 @@ TEST_F(AnalyticsRecorderTest, SuccessfulIncomingConnectionAttempt) { std::make_unique(); connections_attempt_metadata_params->operation_result_code = OperationResultCode::DETAIL_SUCCESS; - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnIncomingConnectionAttempt( INITIAL, BLUETOOTH, RESULT_SUCCESS, absl::Duration{}, /*connection_token=*/"", connections_attempt_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnStopAdvertising(); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -982,17 +972,17 @@ TEST_F(AnalyticsRecorderTest, OperationResultCode::CONNECTIVITY_BT_CLIENT_SOCKET_CREATION_FAILURE); auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, discovery_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnConnectionRequestSent(endpoint_id); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnOutgoingConnectionAttempt( endpoint_id, INITIAL, BLUETOOTH, RESULT_ERROR, absl::Duration{}, /*connection_token=*/"", connections_attempt_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1063,21 +1053,21 @@ TEST_F(AnalyticsRecorderTest, auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnConnectionEstablished(endpoint_id, BLUETOOTH, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnConnectionClosed( endpoint_id, BLUETOOTH, UPGRADED, ConnectionsLog::EstablishedConnection::UNKNOWN_SAFE_DISCONNECTION_RESULT); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnConnectionEstablished(endpoint_id, WIFI_LAN, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1139,41 +1129,41 @@ TEST_F(AnalyticsRecorderTest, OutgoingPayloadUpgraded) { auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnConnectionEstablished(endpoint_id, BLUETOOTH, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnOutgoingPayloadStarted( {endpoint_id}, payload_id, connections::PayloadType::kFile, 50); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnPayloadChunkSent(endpoint_id, payload_id, 10); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnPayloadChunkSent(endpoint_id, payload_id, 10); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.OnConnectionClosed( endpoint_id, BLUETOOTH, UPGRADED, ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.OnConnectionEstablished(endpoint_id, WIFI_LAN, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(800)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); analytics_recorder.OnPayloadChunkSent(endpoint_id, payload_id, 10); - GetFakeClock().FastForward(absl::Milliseconds(900)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); analytics_recorder.OnPayloadChunkSent(endpoint_id, payload_id, 10); - GetFakeClock().FastForward(absl::Milliseconds(1000)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1000)); analytics_recorder.OnPayloadChunkSent(endpoint_id, payload_id, 10); - GetFakeClock().FastForward(absl::Milliseconds(1100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1100)); analytics_recorder.OnOutgoingPayloadDone(endpoint_id, payload_id, SUCCESS, OperationResultCode::DETAIL_SUCCESS); - GetFakeClock().FastForward(absl::Milliseconds(1200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1200)); analytics_recorder.OnConnectionClosed( endpoint_id, WIFI_LAN, LOCAL_DISCONNECTION, ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); - GetFakeClock().FastForward(absl::Milliseconds(1300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1300)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1260,31 +1250,31 @@ TEST_F(AnalyticsRecorderTest, UpgradeAttemptWorks) { auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnBandwidthUpgradeStarted(endpoint_id, BLE, WIFI_LAN, INCOMING, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnBandwidthUpgradeStarted( endpoint_id_1, BLUETOOTH, WIFI_LAN, INCOMING, connection_token); // Error to upgrade. - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnBandwidthUpgradeError( endpoint_id, WIFI_LAN_MEDIUM_ERROR, WIFI_LAN_SOCKET_CREATION, OperationResultCode::CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL); // Success to upgrade. - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnBandwidthUpgradeSuccess(endpoint_id_1); // Upgrade is unfinished. - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.OnBandwidthUpgradeStarted( endpoint_id_2, BLUETOOTH, WIFI_LAN, INCOMING, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1362,26 +1352,26 @@ TEST_F(AnalyticsRecorderTest, StartListeningForIncomingConnectionsWorks) { FakeEventLogger event_logger(client_session_done_latch); AnalyticsRecorder analytics_recorder(&event_logger); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartedIncomingConnectionListening( connections::Strategy::kP2pStar); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnBandwidthUpgradeStarted(endpoint_id, BLE, WIFI_LAN, INCOMING, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnBandwidthUpgradeStarted( endpoint_id_1, BLUETOOTH, WIFI_LAN, INCOMING, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); // Error to upgrade. analytics_recorder.OnBandwidthUpgradeError( endpoint_id, WIFI_LAN_MEDIUM_ERROR, WIFI_LAN_SOCKET_CREATION, OperationResultCode::CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); // Success to upgrade. analytics_recorder.OnBandwidthUpgradeSuccess(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.LogSession(); // ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1432,7 +1422,7 @@ TEST_F(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectly) { auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, /*mediums=*/{WEB_RTC}, discovery_metadata_params.get()); @@ -1440,9 +1430,9 @@ TEST_F(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectly) { ErrorCodeParams error_code_params = ErrorCodeRecorder::BuildErrorCodeParams( WEB_RTC, DISCONNECT, DISCONNECT_NETWORK_FAILED, TACHYON_SEND_MESSAGE_STATUS_EXCEPTION, "", "connection_token"); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnErrorCode(error_code_params); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1466,7 +1456,7 @@ TEST_F(AnalyticsRecorderTest, auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, /*mediums=*/{BLUETOOTH}, discovery_metadata_params.get()); @@ -1477,9 +1467,9 @@ TEST_F(AnalyticsRecorderTest, error_code_params.event = START_DISCOVERING; error_code_params.start_discovering_error = START_EXTENDED_DISCOVERING_FAILED; error_code_params.connection_token = "connection_token"; - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnErrorCode(error_code_params); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1502,7 +1492,7 @@ TEST_F(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectlyForCommonError) { auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, /*mediums=*/{BLUETOOTH}, discovery_metadata_params.get()); @@ -1510,9 +1500,9 @@ TEST_F(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectlyForCommonError) { ErrorCodeParams error_code_params = ErrorCodeRecorder::BuildErrorCodeParams( BLUETOOTH, START_DISCOVERING, INVALID_PARAMETER, NULL_BLUETOOTH_DEVICE_NAME, "", "connection_token"); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnErrorCode(error_code_params); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1533,7 +1523,7 @@ TEST_F(AnalyticsRecorderTest, CheckIfSessionWasLogged) { FakeEventLogger event_logger(client_session_done_latch); AnalyticsRecorder analytics_recorder(&event_logger); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); // LogSession to count down client_session_done_latch. analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1635,17 +1625,17 @@ TEST_F(AnalyticsRecorderTest, auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnConnectionRequestReceived(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnLocalEndpointAccepted(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); // LogSession analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces @@ -1684,7 +1674,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch new_start_client_session_done_latch(1); event_logger.SetStartClientSessionDoneLatchPtr( &new_start_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.LogStartSession(); ASSERT_TRUE( new_start_client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1693,13 +1683,13 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch new_client_session_done_latch(1); event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); std::string endpoint_id_1 = "endpoint_id_1"; - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.OnConnectionRequestReceived(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(800)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(900)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(1000)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1000)); analytics_recorder.LogSession(); ASSERT_TRUE(new_client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1767,18 +1757,18 @@ TEST_F(AnalyticsRecorderTest, auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, discovery_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnConnectionRequestSent(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnLocalEndpointAccepted(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); // LogSession analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces @@ -1825,13 +1815,13 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch new_client_session_done_latch(1); event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); std::string endpoint_id_1 = "endpoint_id_1"; - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.OnConnectionRequestSent(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(800)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_1); - GetFakeClock().FastForward(absl::Milliseconds(900)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1901,14 +1891,14 @@ TEST_F(AnalyticsRecorderTest, ClearcActiveConnectionsAfterSessionWasLogged) { auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(strategy, mediums, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnConnectionEstablished(endpoint_id, BLUETOOTH, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); // LogSession analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces @@ -1951,7 +1941,7 @@ TEST_F(AnalyticsRecorderTest, ClearcActiveConnectionsAfterSessionWasLogged) { CountDownLatch new_start_client_session_done_latch(1); event_logger.SetStartClientSessionDoneLatchPtr( &new_start_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.LogStartSession(); ASSERT_TRUE( new_start_client_session_done_latch.Await(kDefaultTimeout).result()); @@ -1959,7 +1949,7 @@ TEST_F(AnalyticsRecorderTest, ClearcActiveConnectionsAfterSessionWasLogged) { // LogSession again CountDownLatch new_client_session_done_latch(1); event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2024,33 +2014,33 @@ TEST_F(AnalyticsRecorderTest, auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnBandwidthUpgradeStarted(endpoint_id, BLE, WIFI_LAN, INCOMING, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnBandwidthUpgradeStarted( endpoint_id_1, BLUETOOTH, WIFI_LAN, INCOMING, connection_token); // - Error to upgrade. - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnBandwidthUpgradeError( endpoint_id, WIFI_LAN_MEDIUM_ERROR, WIFI_LAN_SOCKET_CREATION, OperationResultCode::CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL); // - Success to upgrade. - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnBandwidthUpgradeSuccess(endpoint_id_1); // - Upgrade is unfinished. - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.OnBandwidthUpgradeStarted( endpoint_id_2, BLUETOOTH, WIFI_LAN, INCOMING, connection_token); - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); // LogSession analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2123,7 +2113,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch new_start_client_session_done_latch(1); event_logger.SetStartClientSessionDoneLatchPtr( &new_start_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(800)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); analytics_recorder.LogStartSession(); ASSERT_TRUE( new_start_client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2131,7 +2121,7 @@ TEST_F(AnalyticsRecorderTest, // LogSession again CountDownLatch new_client_session_done_latch(1); event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(900)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2216,14 +2206,14 @@ TEST_F(AnalyticsRecorderTest, auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnStopAdvertising(); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); // LogSession analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2237,7 +2227,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch new_start_client_session_done_latch(1); event_logger.SetStartClientSessionDoneLatchPtr( &new_start_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.LogStartSession(); ASSERT_TRUE( new_start_client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2246,12 +2236,12 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch new_client_session_done_latch(1); event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnStartAdvertising(strategy, /*mediums=*/{BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.OnStopAdvertising(); - GetFakeClock().FastForward(absl::Milliseconds(700)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.LogSession(); ASSERT_TRUE(new_client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2272,13 +2262,13 @@ TEST_F(AnalyticsRecorderTest, // UpdateStrategySessionLocked. auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnStopAdvertising(); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); // LogSession analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2310,7 +2300,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch new_start_client_session_done_latch(1); event_logger.SetStartClientSessionDoneLatchPtr( &new_start_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.LogStartSession(); ASSERT_TRUE( new_start_client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2320,7 +2310,7 @@ TEST_F(AnalyticsRecorderTest, // strategy_session_proto will be logged. CountDownLatch new_client_session_done_latch(1); event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.LogSession(); ASSERT_TRUE(new_client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2337,14 +2327,14 @@ TEST_F(AnalyticsRecorderTest, auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising( connections::Strategy::kP2pStar, /*mediums=*/{BLUETOOTH}, advertising_metadata_params.get()); // set current_advertising_phase_ - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnStopAdvertising(); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); // LogSession analytics_recorder.LogSession(); @@ -2376,7 +2366,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch new_start_client_session_done_latch(1); event_logger.SetStartClientSessionDoneLatchPtr( &new_start_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.LogStartSession(); ASSERT_TRUE( new_start_client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2387,7 +2377,7 @@ TEST_F(AnalyticsRecorderTest, // be logged. CountDownLatch new_client_session_done_latch(1); event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2434,15 +2424,15 @@ TEST_F(AnalyticsRecorderTest, analytics_recorder.BuildDiscoveryMetadataParams( /*is_extended_advertisement_supported*/ true, /*connected_ap_frequency*/ 1, /*is_nfc_available=*/false); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartDiscovery( strategy, {BLUETOOTH}, discovery_metadata_params.get()); // set current_discovery_phase_ - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnStopDiscovery(); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); analytics_recorder.OnEndpointFound(BLUETOOTH); - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); // LogSession analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2457,10 +2447,7 @@ TEST_F(AnalyticsRecorderTest, discovery_phase { duration_millis: 200 medium: BLUETOOTH - discovered_endpoint { - medium: BLUETOOTH - latency_millis: 500 - } + discovered_endpoint { medium: BLUETOOTH latency_millis: 500 } discovery_metadata { supports_extended_ble_advertisements: true connected_ap_frequency: 1 @@ -2477,7 +2464,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch new_start_client_session_done_latch(1); event_logger.SetStartClientSessionDoneLatchPtr( &new_start_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.LogStartSession(); ASSERT_TRUE( new_start_client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2488,7 +2475,7 @@ TEST_F(AnalyticsRecorderTest, // logged. CountDownLatch new_client_session_done_latch(1); event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.LogSession(); ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); @@ -2536,13 +2523,13 @@ TEST_F(AnalyticsRecorderTest, // UpdateStrategySessionLocked. auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); - GetFakeClock().FastForward(absl::Milliseconds(100)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, /*mediums=*/{BLE, BLUETOOTH}, advertising_metadata_params.get()); - GetFakeClock().FastForward(absl::Milliseconds(200)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); analytics_recorder.OnStopAdvertising(); - GetFakeClock().FastForward(absl::Milliseconds(300)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); // LogSession analytics_recorder.LogSession(); @@ -2573,14 +2560,14 @@ TEST_F(AnalyticsRecorderTest, // Without calling OnStartAdvertising won't create new // current_strategy_session_. - GetFakeClock().FastForward(absl::Milliseconds(400)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnConnectionEstablished(endpoint_id, BLUETOOTH, /*connection_token=*/""); - GetFakeClock().FastForward(absl::Milliseconds(500)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnConnectionClosed( endpoint_id, BLUETOOTH, UPGRADED, ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); - GetFakeClock().FastForward(absl::Milliseconds(600)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.LogSession(); // The proto won't change. diff --git a/connections/implementation/client_proxy_test.cc b/connections/implementation/client_proxy_test.cc index 5da9aabd..5ea52f45 100644 --- a/connections/implementation/client_proxy_test.cc +++ b/connections/implementation/client_proxy_test.cc @@ -360,10 +360,7 @@ class ClientProxyTest : public ::testing::TestWithParam { ClientProxy* client2() { return client2_.get(); } void FastForward(absl::Duration duration) { - (*env_.GetSimulatedClock()) - ->FastForward( - ClientProxy::kHighPowerAdvertisementEndpointIdCacheTimeout + - absl::Milliseconds(100)); + env_.FastForward(duration); // make sure the timer based callback is executed. absl::SleepFor(absl::Milliseconds(100)); } diff --git a/connections/implementation/mediums/ble/discovered_peripheral_tracker_test.cc b/connections/implementation/mediums/ble/discovered_peripheral_tracker_test.cc index 79fd120f..c34120ae 100644 --- a/connections/implementation/mediums/ble/discovered_peripheral_tracker_test.cc +++ b/connections/implementation/mediums/ble/discovered_peripheral_tracker_test.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -53,7 +52,6 @@ #include "internal/platform/mutex.h" #include "internal/platform/mutex_lock.h" #include "internal/platform/uuid.h" -#include "internal/test/fake_clock.h" namespace nearby { namespace connections { @@ -1628,9 +1626,6 @@ TEST_P(DiscoveredPeripheralTrackerTest, TEST_P(DiscoveredPeripheralTrackerTest, OnlyGattAdvertisementReceivedOnDeviceWithExtended) { - std::optional fake_clock = - MediumEnvironment::Instance().GetSimulatedClock(); - std::vector service_ids = {std::string(kServiceIdA)}; ByteArray advertisement_hash = GenerateRandomAdvertisementHash(); ByteArray advertisement_header_bytes = @@ -1668,7 +1663,7 @@ TEST_P(DiscoveredPeripheralTrackerTest, // 2. Receive GATT advertisement data again after 4 seconds, it should access // GATT server. - (*fake_clock)->FastForward(absl::Seconds(4)); + MediumEnvironment::Instance().FastForward(absl::Seconds(4)); FindAdvertisement(advertisement_data, {advertisement_bytes}, fetch_latch); // We should receive a client callback of a peripheral discovery. @@ -1678,9 +1673,6 @@ TEST_P(DiscoveredPeripheralTrackerTest, } TEST_P(DiscoveredPeripheralTrackerTest, SkipExpiredGattAdvertisement) { - std::optional fake_clock = - MediumEnvironment::Instance().GetSimulatedClock(); - std::vector service_ids = {std::string(kServiceIdA)}; ByteArray advertisement_hash = GenerateRandomAdvertisementHash(); ByteArray advertisement_header_bytes = @@ -1718,7 +1710,7 @@ TEST_P(DiscoveredPeripheralTrackerTest, SkipExpiredGattAdvertisement) { // 2. The GATT advertisement is already queued and will be skipped. FindAdvertisement(advertisement_data, {advertisement_bytes}, fetch_latch); - (*fake_clock)->FastForward(absl::Seconds(20)); + MediumEnvironment::Instance().FastForward(absl::Seconds(20)); discovered_peripheral_tracker_->StartFetchExecutorForTesting(); // We should not receive a client callback of a peripheral discovery. @@ -1729,9 +1721,6 @@ TEST_P(DiscoveredPeripheralTrackerTest, SkipExpiredGattAdvertisement) { TEST_P(DiscoveredPeripheralTrackerTest, DiscoveredOnceWhenGattAndExtendedAdvertisementReceived) { - std::optional fake_clock = - MediumEnvironment::Instance().GetSimulatedClock(); - std::vector service_ids = {std::string(kServiceIdA)}; ByteArray advertisement_hash = GenerateRandomAdvertisementHash(); ByteArray advertisement_header_bytes = @@ -1756,7 +1745,7 @@ TEST_P(DiscoveredPeripheralTrackerTest, }, }, bleutils::kCopresenceServiceUuid); - (*fake_clock)->FastForward(absl::Seconds(4)); + MediumEnvironment::Instance().FastForward(absl::Seconds(4)); discovered_peripheral_tracker_->StartFetchExecutorForTesting(); // 1. Received extended advertisement. @@ -1784,8 +1773,6 @@ TEST_P(DiscoveredPeripheralTrackerTest, TEST_P(DiscoveredPeripheralTrackerTest, FindGattAdvertisementInHigherPriorityThanExtendedGattAdvertisement) { - std::optional fake_clock = - MediumEnvironment::Instance().GetSimulatedClock(); std::vector service_ids = {std::string(kServiceIdA)}; ByteArray advertisement_hash_a = GenerateRandomAdvertisementHash(); ByteArray advertisement_header_a = @@ -1823,7 +1810,7 @@ TEST_P(DiscoveredPeripheralTrackerTest, }, }, bleutils::kCopresenceServiceUuid); - (*fake_clock)->FastForward(absl::Seconds(4)); + MediumEnvironment::Instance().FastForward(absl::Seconds(4)); discovered_peripheral_tracker_->StartFetchExecutorForTesting(); // 1. Find peripheral A with GATT advertisement. diff --git a/internal/platform/implementation/g3/scheduled_executor.cc b/internal/platform/implementation/g3/scheduled_executor.cc index f82d6f7b..34e7fed9 100644 --- a/internal/platform/implementation/g3/scheduled_executor.cc +++ b/internal/platform/implementation/g3/scheduled_executor.cc @@ -16,16 +16,15 @@ #include #include -#include #include #include "absl/strings/str_format.h" #include "absl/synchronization/mutex.h" #include "absl/time/time.h" #include "internal/platform/implementation/cancelable.h" +#include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" #include "internal/platform/runnable.h" -#include "internal/test/fake_clock.h" namespace nearby { namespace g3 { @@ -66,20 +65,13 @@ class ScheduledCancelable : public api::Cancelable { } // namespace ScheduledExecutor::ScheduledExecutor() { - std::optional fake_clock = - MediumEnvironment::Instance().GetSimulatedClock(); - if (fake_clock.has_value()) { - name_ = absl::StrFormat("G3 scheduled executor %p", this); - (*fake_clock)->AddObserver(name_, [this]() { RunReadyTasks(); }); - } + name_ = absl::StrFormat("G3 scheduled executor %p", this); + MediumEnvironment::Instance().AddSimulatedClockObserver( + name_, [this]() { RunReadyTasks(); }); } ScheduledExecutor::~ScheduledExecutor() { - std::optional fake_clock = - MediumEnvironment::Instance().GetSimulatedClock(); - if (fake_clock.has_value()) { - (*fake_clock)->RemoveObserver(name_); - } + MediumEnvironment::Instance().RemoveSimulatedClockObserver(name_); executor_.Shutdown(); } @@ -96,10 +88,10 @@ std::shared_ptr ScheduledExecutor::Schedule( runnable(); } }; - std::optional fake_clock = - MediumEnvironment::Instance().GetSimulatedClock(); - if (fake_clock.has_value()) { - absl::Time trigger_time = (*fake_clock)->Now() + delay; + if (MediumEnvironment::Instance() + .GetEnvironmentConfig() + .use_simulated_clock) { + absl::Time trigger_time = MediumEnvironment::Instance().Now() + delay; absl::MutexLock lock(mutex_); tasks_.insert(std::pair>( trigger_time, std::make_unique(std::move(task)))); @@ -110,15 +102,12 @@ std::shared_ptr ScheduledExecutor::Schedule( } void ScheduledExecutor::RunReadyTasks() { - std::optional fake_clock = - MediumEnvironment::Instance().GetSimulatedClock(); if (executor_.InShutdown()) { return; } - if (!fake_clock.has_value()) { - return; - } - absl::Time current_time = (*fake_clock)->Now(); + CHECK( + MediumEnvironment::Instance().GetEnvironmentConfig().use_simulated_clock); + absl::Time current_time = MediumEnvironment::Instance().Now(); absl::MutexLock lock(mutex_); for (auto it = tasks_.begin(); it != tasks_.end();) { if (it->first <= current_time) { diff --git a/internal/platform/implementation/g3/system_clock.cc b/internal/platform/implementation/g3/system_clock.cc index b3cc53c1..430ba5a4 100644 --- a/internal/platform/implementation/g3/system_clock.cc +++ b/internal/platform/implementation/g3/system_clock.cc @@ -15,26 +15,21 @@ #include "internal/platform/implementation/system_clock.h" #include "absl/time/clock.h" +#include "absl/time/time.h" #include "internal/platform/exception.h" #include "internal/platform/medium_environment.h" -#include "internal/test/fake_clock.h" namespace nearby { absl::Time SystemClock::ElapsedRealtime() { - absl::optional fake_clock = - MediumEnvironment::Instance().GetSimulatedClock(); - if (fake_clock.has_value()) { - return (*fake_clock)->Now(); - } - return absl::Now(); + return MediumEnvironment::Instance().Now(); } Exception SystemClock::Sleep(absl::Duration duration) { - absl::optional fake_clock = - MediumEnvironment::Instance().GetSimulatedClock(); - if (fake_clock.has_value()) { - (*fake_clock)->FastForward(duration); + if (MediumEnvironment::Instance() + .GetEnvironmentConfig() + .use_simulated_clock) { + MediumEnvironment::Instance().FastForward(duration); } else { absl::SleepFor(duration); } diff --git a/internal/platform/medium_environment.cc b/internal/platform/medium_environment.cc index f932bfc4..3f1617b0 100644 --- a/internal/platform/medium_environment.cc +++ b/internal/platform/medium_environment.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include "absl/status/status.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" +#include "absl/time/clock.h" #include "absl/time/time.h" #include "internal/platform/borrowable.h" #include "internal/platform/byte_array.h" @@ -46,6 +48,7 @@ #include "internal/platform/nsd_service_info.h" #include "internal/platform/prng.h" #include "internal/platform/runnable.h" +#include "internal/platform/service_address.h" #include "internal/platform/uuid.h" #include "internal/platform/wifi_credential.h" #include "internal/test/fake_clock.h" @@ -69,10 +72,14 @@ MediumEnvironment& MediumEnvironment::Instance() { void MediumEnvironment::Start(EnvironmentConfig config) { if (!enabled_.exchange(true)) { LOG(INFO) << "MediumEnvironment::Start()"; - config_ = std::move(config); - if (config_.use_simulated_clock) { + { MutexLock lock(&mutex_); - simulated_clock_ = std::make_unique(); + config_ = std::move(config); + if (config_.use_simulated_clock) { + simulated_clock_ = std::make_shared(); + } else { + simulated_clock_.reset(); + } } Reset(); } @@ -82,8 +89,8 @@ void MediumEnvironment::Stop() { if (enabled_.exchange(false)) { LOG(INFO) << "MediumEnvironment::Stop()"; Sync(false); + MutexLock lock(&mutex_); if (config_.use_simulated_clock) { - MutexLock lock(&mutex_); simulated_clock_.reset(); } config_ = {}; @@ -132,7 +139,8 @@ void MediumEnvironment::Sync(bool enable_notifications) { LOG(INFO) << "MediumEnvironment::Sync(): done [count=" << count << "]"; } -const EnvironmentConfig& MediumEnvironment::GetEnvironmentConfig() { +EnvironmentConfig MediumEnvironment::GetEnvironmentConfig() { + MutexLock lock(&mutex_); return config_; } @@ -1150,12 +1158,43 @@ void MediumEnvironment::SetFeatureFlags(const FeatureFlags::Flags& flags) { FeatureFlags::GetMutableInstanceForTesting().SetFlags(flags); } -std::optional MediumEnvironment::GetSimulatedClock() { +absl::Time MediumEnvironment::Now() { MutexLock lock(&mutex_); if (simulated_clock_) { - return std::optional(simulated_clock_.get()); + return simulated_clock_->Now(); + } + return absl::Now(); +} + +// If simulated_clock_ is valid, it will be advanced by the given duration. +// If simulated_clock_ is not valid, this method will do nothing. +void MediumEnvironment::FastForward(absl::Duration duration) { + std::shared_ptr sim_clock; + { + MutexLock lock(&mutex_); + if (simulated_clock_) { + sim_clock = simulated_clock_; + } + } + if (sim_clock) { + // Mutex is unlocked before calling FastForward to prevent deadlocks. + sim_clock->FastForward(duration); + } +} + +void MediumEnvironment::AddSimulatedClockObserver( + const std::string& name, std::function observer) { + MutexLock lock(&mutex_); + if (simulated_clock_) { + simulated_clock_->AddObserver(name, std::move(observer)); + } +} + +void MediumEnvironment::RemoveSimulatedClockObserver(const std::string& name) { + MutexLock lock(&mutex_); + if (simulated_clock_) { + simulated_clock_->RemoveObserver(name); } - return std::nullopt; } void MediumEnvironment::RegisterGattServer( diff --git a/internal/platform/medium_environment.h b/internal/platform/medium_environment.h index a5bf530d..3a345a5a 100644 --- a/internal/platform/medium_environment.h +++ b/internal/platform/medium_environment.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -162,7 +163,7 @@ class MediumEnvironment { // Returns a Bluetooth Device object matching given mac address to nullptr. api::BluetoothDevice* FindBluetoothDevice(MacAddress mac_address); - const EnvironmentConfig& GetEnvironmentConfig(); + EnvironmentConfig GetEnvironmentConfig(); #ifndef NO_WEBRTC // Registers |message_callback| to receive messages sent to device with id // |self_id|, and |complete_callback| to notify when signaling is complete. @@ -334,7 +335,11 @@ class MediumEnvironment { void SetFeatureFlags(const FeatureFlags::Flags& flags); - std::optional GetSimulatedClock(); + absl::Time Now(); + void FastForward(absl::Duration duration); + void AddSimulatedClockObserver(const std::string& name, + std::function observer); + void RemoveSimulatedClockObserver(const std::string& name); api::ble::BleMedium* FindBleMedium(api::ble::BlePeripheral::UniqueId id); @@ -516,7 +521,7 @@ class MediumEnvironment { bool use_valid_peer_connection_ = true; absl::Duration peer_connection_latency_ = absl::ZeroDuration(); - std::unique_ptr simulated_clock_ ABSL_GUARDED_BY(mutex_); + std::shared_ptr simulated_clock_ ABSL_GUARDED_BY(mutex_); ObserverList observers_; bool ble_extended_advertisements_available_ = false; }; diff --git a/internal/platform/scheduled_executor_test.cc b/internal/platform/scheduled_executor_test.cc index efc9f77a..80d79c25 100644 --- a/internal/platform/scheduled_executor_test.cc +++ b/internal/platform/scheduled_executor_test.cc @@ -25,13 +25,12 @@ #include "internal/platform/cancelable.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/medium_environment.h" -#include "internal/test/fake_clock.h" namespace nearby { // kShortDelay must be significant enough to guarantee that OS under heavy load // should be able to execute the non-blocking test paths within this time. -absl::Duration kShortDelay = absl::Milliseconds(100); +absl::Duration kShortDelay = absl::Milliseconds(200); // kLongDelay must be long enough to make sure that under OS under heavy load // will let kShortDelay fire and jobs scheduled before the kLongDelay fires. @@ -212,8 +211,6 @@ TEST(ScheduledExecutorTest, ExecuteDuringShutdownFails) { TEST(ScheduledExecutorTest, SimulatedClockCanSchedule) { MediumEnvironment::Instance().Start({.use_simulated_clock = true}); - FakeClock* fake_clock = - MediumEnvironment::Instance().GetSimulatedClock().value(); ScheduledExecutor executor; std::atomic_int value = 0; CountDownLatch first_task_latch(1); @@ -235,24 +232,23 @@ TEST(ScheduledExecutorTest, SimulatedClockCanSchedule) { }, kShortDelay); EXPECT_EQ(value, 0); - fake_clock->FastForward(kShortDelay - absl::Milliseconds(1)); + MediumEnvironment::Instance().FastForward(kShortDelay - + absl::Milliseconds(1)); EXPECT_EQ(value, 0); - fake_clock->FastForward(absl::Milliseconds(1)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1)); second_task_latch.Await(); EXPECT_EQ(value, 1); - fake_clock->FastForward(kLongDelay - kShortDelay); + MediumEnvironment::Instance().FastForward(kLongDelay - kShortDelay); first_task_latch.Await(); EXPECT_EQ(value, 5); // Very long sleep to make sure that the sleep is truly simulated. - fake_clock->FastForward(absl::Minutes(30)); + MediumEnvironment::Instance().FastForward(absl::Minutes(30)); MediumEnvironment::Instance().Stop(); } TEST(ScheduledExecutorTest, DestroyExecutorWithSimulatedClockIgnoresPendingTasks) { MediumEnvironment::Instance().Start({.use_simulated_clock = true}); - FakeClock* fake_clock = - MediumEnvironment::Instance().GetSimulatedClock().value(); { ScheduledExecutor executor; executor.Schedule( @@ -262,7 +258,7 @@ TEST(ScheduledExecutorTest, }, kShortDelay); } - fake_clock->FastForward(absl::Minutes(30)); + MediumEnvironment::Instance().FastForward(absl::Minutes(30)); MediumEnvironment::Instance().Stop(); } @@ -403,8 +399,6 @@ TEST(ScheduledExecutorTest, CanCancelOneOfTwoRepeatedTasks) { TEST(ScheduledExecutorTest, SimulatedClockCanScheduleRepeatedly) { MediumEnvironment::Instance().Start({.use_simulated_clock = true}); - FakeClock* fake_clock = - MediumEnvironment::Instance().GetSimulatedClock().value(); ScheduledExecutor executor; std::atomic_int value = 0; std::atomic_int i = 0; @@ -419,11 +413,12 @@ TEST(ScheduledExecutorTest, SimulatedClockCanScheduleRepeatedly) { EXPECT_EQ(value, 0); // Advance to just before the first execution. - fake_clock->FastForward(kShortDelay - absl::Milliseconds(1)); + MediumEnvironment::Instance().FastForward(kShortDelay - + absl::Milliseconds(1)); EXPECT_EQ(value, 0); // Advance past the first execution. - fake_clock->FastForward(absl::Milliseconds(1)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1)); latch[0].Await(absl::Seconds(1)); EXPECT_EQ(value, 1); @@ -431,11 +426,12 @@ TEST(ScheduledExecutorTest, SimulatedClockCanScheduleRepeatedly) { absl::SleepFor(kShortDelay); // Advance to just before the second execution. - fake_clock->FastForward(kShortDelay - absl::Milliseconds(1)); + MediumEnvironment::Instance().FastForward(kShortDelay - + absl::Milliseconds(1)); EXPECT_EQ(value, 1); // Advance past the second execution. - fake_clock->FastForward(absl::Milliseconds(1)); + MediumEnvironment::Instance().FastForward(absl::Milliseconds(1)); latch[1].Await(absl::Seconds(1)); EXPECT_EQ(value, 2); @@ -443,7 +439,7 @@ TEST(ScheduledExecutorTest, SimulatedClockCanScheduleRepeatedly) { cancelable.Cancel(); // Advance a long time and make sure it doesn't run again. - fake_clock->FastForward(kLongDelay * 5); + MediumEnvironment::Instance().FastForward(kLongDelay * 5); EXPECT_EQ(value, 2); MediumEnvironment::Instance().Stop(); diff --git a/internal/test/fake_clock.cc b/internal/test/fake_clock.cc index edb26a7f..8df56432 100644 --- a/internal/test/fake_clock.cc +++ b/internal/test/fake_clock.cc @@ -19,6 +19,10 @@ #include #include +#include "absl/strings/string_view.h" +#include "absl/synchronization/mutex.h" +#include "absl/time/time.h" + namespace nearby { FakeClock::~FakeClock() { diff --git a/internal/test/fake_clock.h b/internal/test/fake_clock.h index 5b7a9af8..b5fbeea6 100644 --- a/internal/test/fake_clock.h +++ b/internal/test/fake_clock.h @@ -53,6 +53,7 @@ class FakeClock : public Clock { absl::flat_hash_map> observers_ ABSL_GUARDED_BY(mutex_); }; + } // namespace nearby #endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_CLOCK_H_ diff --git a/internal/test/fake_clock_test.cc b/internal/test/fake_clock_test.cc index 0f57ce56..770f78ed 100644 --- a/internal/test/fake_clock_test.cc +++ b/internal/test/fake_clock_test.cc @@ -14,9 +14,8 @@ #include "internal/test/fake_clock.h" -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "absl/time/time.h" namespace nearby { namespace { From 32f1ed5ac550eaa207343abda57bb68a94de0c67 Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 24 Apr 2026 22:01:06 -0700 Subject: [PATCH 058/151] add isForcedUsb logging PiperOrigin-RevId: 905371058 --- internal/proto/analytics/connections_log.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/proto/analytics/connections_log.proto b/internal/proto/analytics/connections_log.proto index 3be13ef3..fd0ab10d 100644 --- a/internal/proto/analytics/connections_log.proto +++ b/internal/proto/analytics/connections_log.proto @@ -590,6 +590,9 @@ message ConnectionsLog { // The number of times the upgrade attempt is tried. // This count is reset to 0 when the upgrade is successful. optional int32 try_count = 14; + // If true, the upgrade attempt is forced to use the USB medium, regardless + // of the available mediums. + optional bool is_forced_usb = 15; } // Next Id: 22 From b8ef0d45cf34f35620485a35ed2c6582e244fa3b Mon Sep 17 00:00:00 2001 From: hai007 Date: Sun, 26 Apr 2026 20:52:40 -0700 Subject: [PATCH 059/151] add isForcedUsb logging PiperOrigin-RevId: 906108772 --- internal/proto/analytics/connections_log.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/proto/analytics/connections_log.proto b/internal/proto/analytics/connections_log.proto index fd0ab10d..cff0fc1f 100644 --- a/internal/proto/analytics/connections_log.proto +++ b/internal/proto/analytics/connections_log.proto @@ -458,6 +458,9 @@ message ConnectionsLog { // The RSSI (radio signal strength indicator) in dBm. // INTERNET_RSSI_UNKNOWN (-127) if unknown. optional int32 rssi = 17; + + // If this connection is forced over USB. + optional bool is_forced_usb = 18; } message SpeedTestReport { From 3311c2c07fe21d7a24b0237b2b9f2647ea95dbab Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 27 Apr 2026 10:34:53 -0700 Subject: [PATCH 060/151] Automated Code Change PiperOrigin-RevId: 906432793 --- sharing/nearby_sharing_service_impl.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 4f0c3086..dbcb557b 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -1921,9 +1921,7 @@ void NearbySharingServiceImpl::InvalidateReceiveSurfaceState() { void NearbySharingServiceImpl::InvalidateAdvertisingState() { // Do not advertise on lock screen unless Self Share is enabled. - if (is_screen_locked_ && - !NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_sharing_feature::kEnableSelfShareUi)) { + if (is_screen_locked_) { StopAdvertising(); VLOG(1) << __func__ << ": Stopping advertising because the screen is locked."; From b4551e8d0a3a04ee0cb492b587e4ebc85782456d Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 27 Apr 2026 14:04:07 -0700 Subject: [PATCH 061/151] Fix flaky MultiplexSocketTest by using CountDownLatch. PiperOrigin-RevId: 906533858 --- .../mediums/bluetooth_classic.cc | 49 +++++------ .../mediums/bluetooth_classic.h | 8 +- .../mediums/multiplex/multiplex_socket.cc | 41 +++++---- .../mediums/multiplex/multiplex_socket.h | 17 ++-- .../multiplex/multiplex_socket_test.cc | 84 +++++++++++-------- .../implementation/mediums/wifi_lan.cc | 43 +++++----- connections/implementation/mediums/wifi_lan.h | 8 +- 7 files changed, 144 insertions(+), 106 deletions(-) diff --git a/connections/implementation/mediums/bluetooth_classic.cc b/connections/implementation/mediums/bluetooth_classic.cc index f38dc278..290defb5 100644 --- a/connections/implementation/mediums/bluetooth_classic.cc +++ b/connections/implementation/mediums/bluetooth_classic.cc @@ -64,9 +64,7 @@ BluetoothClassic::BluetoothClassic( BluetoothRadio& radio, std::unique_ptr medium) : radio_(radio), adapter_(radio_.GetBluetoothAdapter()), - medium_(std::move(medium)) { - is_multiplex_enabled_ = false; -} + medium_(std::move(medium)) {} BluetoothClassic::~BluetoothClassic() { // Destructor is not taking locks, but methods it is calling are. @@ -382,10 +380,10 @@ ErrorOr BluetoothClassic::StartAcceptingConnections( MultiplexSocket::ListenForIncomingConnection( service_id, Medium::BLUETOOTH, [&callback](const std::string& listening_service_id, - MediumSocket* virtual_socket) mutable { + std::shared_ptr virtual_socket) mutable { if (callback) { callback(listening_service_id, - *(down_cast(virtual_socket))); + *(down_cast(virtual_socket.get()))); } }); } @@ -415,20 +413,21 @@ ErrorOr BluetoothClassic::StartAcceptingConnections( MultiplexSocket::CreateIncomingSocket(physical_socket_ptr, service_id, 0); - if (multiplex_socket != nullptr && - multiplex_socket->GetVirtualSocket(service_id)) { - multiplex_sockets_.emplace( - client_socket.GetRemoteDevice().GetAddress(), - multiplex_socket); - MultiplexSocket::StopListeningForIncomingConnection( - service_id, Medium::BLUETOOTH); - LOG(INFO) << "Multiplex virtaul socket created for " - << client_socket.GetRemoteDevice().GetName(); - if (callback) { - callback(service_id, - *(down_cast( - multiplex_socket->GetVirtualSocket(service_id)))); - callback_called = true; + if (multiplex_socket != nullptr) { + if (auto virtual_socket = + multiplex_socket->GetVirtualSocket(service_id)) { + multiplex_sockets_.emplace( + client_socket.GetRemoteDevice().GetAddress(), + multiplex_socket); + MultiplexSocket::StopListeningForIncomingConnection( + service_id, Medium::BLUETOOTH); + LOG(INFO) << "Multiplex virtaul socket created for " + << client_socket.GetRemoteDevice().GetName(); + if (callback) { + callback(service_id, *(down_cast( + virtual_socket.get()))); + callback_called = true; + } } } } @@ -509,10 +508,11 @@ ErrorOr BluetoothClassic::Connect( if (it != multiplex_sockets_.end()) { MultiplexSocket* multiplex_socket = it->second; if (multiplex_socket->IsEnabled()) { - auto* virtual_socket = + std::shared_ptr virtual_socket = multiplex_socket->EstablishVirtualSocket(service_id); // Should not happen. - auto* bluetooth_socket = down_cast(virtual_socket); + auto* bluetooth_socket = + down_cast(virtual_socket.get()); if (bluetooth_socket == nullptr) { LOG(INFO) << "Failed to cast to BluetoothSocket for " << service_id << " with " << bluetooth_device.GetName(); @@ -607,9 +607,10 @@ ErrorOr BluetoothClassic::AttemptToConnect( MultiplexSocket* multiplex_socket = MultiplexSocket::CreateOutgoingSocket( std::move(physical_socket_ptr), service_id); - auto* virtual_socket = multiplex_socket->GetVirtualSocket(service_id); - // Should not happen. - auto* bluetooth_socket = down_cast(virtual_socket); + std::shared_ptr virtual_socket = + multiplex_socket->GetVirtualSocket(service_id); + + auto* bluetooth_socket = down_cast(virtual_socket.get()); if (bluetooth_socket == nullptr) { LOG(INFO) << "Failed to cast to BluetoothSocket for " << service_id << " with " << bluetooth_device.GetName(); diff --git a/connections/implementation/mediums/bluetooth_classic.h b/connections/implementation/mediums/bluetooth_classic.h index f16cf65f..a521d9bb 100644 --- a/connections/implementation/mediums/bluetooth_classic.h +++ b/connections/implementation/mediums/bluetooth_classic.h @@ -236,7 +236,13 @@ class BluetoothClassic { discovery_callbacks_ ABSL_GUARDED_BY(discovery_callbacks_mutex_); // Whether the multiplex feature is enabled. - bool is_multiplex_enabled_ = false; + bool is_multiplex_enabled_ = + NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kEnableMultiplex) && + NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kEnableMultiplexBluetooth); // A map of Bluetooth MacAddress -> MultiplexSocket. absl::flat_hash_map diff --git a/connections/implementation/mediums/multiplex/multiplex_socket.cc b/connections/implementation/mediums/multiplex/multiplex_socket.cc index befe36e9..888efb82 100644 --- a/connections/implementation/mediums/multiplex/multiplex_socket.cc +++ b/connections/implementation/mediums/multiplex/multiplex_socket.cc @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -215,7 +214,7 @@ MultiplexSocket* MultiplexSocket::CreateOutgoingSocket( Utils::GenerateSalt()); } -MediumSocket* MultiplexSocket::CreateFirstVirtualSocket( +std::shared_ptr MultiplexSocket::CreateFirstVirtualSocket( const std::string& service_id, const std::string& service_id_hash_salt) { auto output_stream = multiplex_output_stream_.CreateVirtualOutputStreamForFirstVirtualSocket( @@ -227,9 +226,14 @@ MediumSocket* MultiplexSocket::CreateFirstVirtualSocket( LOG(INFO) << __func__ << " for service_id=" << service_id << ", salt=" << service_id_hash_salt << ", salted_service_id_hash_key=" << salted_service_id_hash_key; - MediumSocket* virtual_socket = physical_socket_ptr_->CreateVirtualSocket( + MediumSocket* virtual_socket_ptr = physical_socket_ptr_->CreateVirtualSocket( salted_service_id_hash_key, output_stream, medium_, &virtual_sockets_); + if (virtual_socket_ptr == nullptr) { + return nullptr; + } + std::shared_ptr virtual_socket = + virtual_sockets_[salted_service_id_hash_key]; virtual_socket->AddOnSocketClosedListener( std::make_unique>( [this, service_id]() { OnVirtualSocketClosed(service_id); })); @@ -242,7 +246,7 @@ MediumSocket* MultiplexSocket::CreateFirstVirtualSocket( return virtual_socket; } -MediumSocket* MultiplexSocket::CreateVirtualSocket( +std::shared_ptr MultiplexSocket::CreateVirtualSocket( const std::string& service_id, const std::string& service_id_hash_salt) { auto output_stream = multiplex_output_stream_.CreateVirtualOutputStream( service_id, service_id_hash_salt); @@ -254,9 +258,14 @@ MediumSocket* MultiplexSocket::CreateVirtualSocket( << ", salt=" << service_id_hash_salt << ", salted_service_id_hash_key=" << salted_service_id_hash_key; - MediumSocket* virtual_socket = physical_socket_ptr_->CreateVirtualSocket( + MediumSocket* virtual_socket_ptr = physical_socket_ptr_->CreateVirtualSocket( salted_service_id_hash_key, output_stream, medium_, &virtual_sockets_); + if (virtual_socket_ptr == nullptr) { + return nullptr; + } + std::shared_ptr virtual_socket = + virtual_sockets_[salted_service_id_hash_key]; virtual_socket->AddOnSocketClosedListener( std::make_unique>( [this, service_id]() { OnVirtualSocketClosed(service_id); })); @@ -264,7 +273,8 @@ MediumSocket* MultiplexSocket::CreateVirtualSocket( return virtual_socket; } -MediumSocket* MultiplexSocket::GetVirtualSocket(const std::string& service_id) { +std::shared_ptr MultiplexSocket::GetVirtualSocket( + const std::string& service_id) { MutexLock lock(&virtual_socket_mutex_); LOG(INFO) << __func__ << " service_id=" << service_id << ", Salt=" << multiplex_output_stream_.GetServiceIdHashSalt(service_id) @@ -275,7 +285,7 @@ MediumSocket* MultiplexSocket::GetVirtualSocket(const std::string& service_id) { LOG(INFO) << "Not found!"; return nullptr; } - return item->second.get(); + return item->second; } int MultiplexSocket::GetVirtualSocketCount() { @@ -305,7 +315,7 @@ void MultiplexSocket::UnRegisterConnectionResponse( connection_response_futures_.erase(service_id); } -MediumSocket* MultiplexSocket::EstablishVirtualSocket( +std::shared_ptr MultiplexSocket::EstablishVirtualSocket( const std::string& service_id) { if (!IsEnabled()) { LOG(ERROR) @@ -555,7 +565,7 @@ void MultiplexSocket::HandleConnectionRequest( << "EstablishVirtualSocket after local device accept the connection " "with serviceId=" << listening_service_id; - MediumSocket* virtual_socket = + std::shared_ptr virtual_socket = CreateVirtualSocket(listening_service_id, service_id_hash_salt); (*incoming_connection_callback)(std::move(listening_service_id), virtual_socket); @@ -620,13 +630,13 @@ void MultiplexSocket::HandleDataFrame(const ByteArray& salted_service_id_hash, const MultiplexDataFrame& frame) { std::string salted_service_id_hash_key = GenerateServiceIdHashKey(salted_service_id_hash); - MediumSocket* virtual_socket = nullptr; + std::shared_ptr virtual_socket = nullptr; if (service_id_hash_salt.empty()) { { MutexLock lock(&virtual_socket_mutex_); auto item = virtual_sockets_.find(salted_service_id_hash_key); if (item != virtual_sockets_.end()) { - virtual_socket = item->second.get(); + virtual_socket = item->second; } } } else { @@ -659,7 +669,8 @@ void MultiplexSocket::OnVirtualSocketClosed(const std::string& service_id) { RunOffloadThread( "VirtualSocketClosed", [this, service_id, &latch, &shutdown]() { LOG(INFO) << "Try to close Virtual socket: " << service_id; - MediumSocket* virtual_socket = GetVirtualSocket(service_id); + std::shared_ptr virtual_socket = + GetVirtualSocket(service_id); { MutexLock lock(&virtual_socket_mutex_); LOG(INFO) << "virtual_socket:" << virtual_socket; @@ -700,7 +711,7 @@ void MultiplexSocket::OnVirtualSocketClosed(const std::string& service_id) { } } -MediumSocket* MultiplexSocket::ReMapAndGetVirtualSocket( +std::shared_ptr MultiplexSocket::ReMapAndGetVirtualSocket( const ByteArray& salted_service_id_hash, const std::string& service_id_hash_salt) { std::string salted_service_id_hash_key = @@ -722,7 +733,7 @@ MediumSocket* MultiplexSocket::ReMapAndGetVirtualSocket( } if ((service_id_hash_salt == kFakeSalt) || (hash_key == salted_service_id_hash_key)) { - return virtual_socket.get(); + return virtual_socket; } else { LOG(INFO) << "Remap the virtualSockets."; output_stream->SetserviceIdHashSalt(service_id_hash_salt); @@ -731,7 +742,7 @@ MediumSocket* MultiplexSocket::ReMapAndGetVirtualSocket( virtual_sockets_.erase(hash_key); virtual_sockets_[salted_service_id_hash_key] = virtual_socket_tmp; ListVirtualSocket(); - return virtual_socket_tmp.get(); + return virtual_socket_tmp; } } } diff --git a/connections/implementation/mediums/multiplex/multiplex_socket.h b/connections/implementation/mediums/multiplex/multiplex_socket.h index 5e65c5d4..ed3fdd7d 100644 --- a/connections/implementation/mediums/multiplex/multiplex_socket.h +++ b/connections/implementation/mediums/multiplex/multiplex_socket.h @@ -44,7 +44,7 @@ namespace multiplex { using MultiplexEnbaleCb = absl::AnyInvocable; using MultiplexIncomingConnectionCb = absl::AnyInvocable; + const std::string& service_id, std::shared_ptr socket)>; class MultiplexSocket { public: @@ -82,7 +82,7 @@ class MultiplexSocket { const std::string& service_id, ::location::nearby::proto::connections::Medium type, absl::AnyInvocable + std::shared_ptr socket)> incoming_connection_cb); // Stops listening for incoming multiplex connection for {@code service_id} on @@ -98,7 +98,7 @@ class MultiplexSocket { } // Gets the virtual socket by service id. - MediumSocket* GetVirtualSocket(const std::string& service_id); + std::shared_ptr GetVirtualSocket(const std::string& service_id); // Gets the virtual socket count. int GetVirtualSocketCount(); @@ -106,7 +106,8 @@ class MultiplexSocket { ABSL_EXCLUSIVE_LOCKS_REQUIRED(virtual_socket_mutex_); // Establishes the virtual socket by service id. - MediumSocket* EstablishVirtualSocket(const std::string& service_id); + std::shared_ptr EstablishVirtualSocket( + const std::string& service_id); // Shuts down the multiplex socket. void Shutdown(); bool IsShutdown() { return is_shutdown_; } @@ -118,11 +119,11 @@ class MultiplexSocket { // Creates the first virtual socket for the service id. The first virtual // socket is created by the sender. - MediumSocket* CreateFirstVirtualSocket( + std::shared_ptr CreateFirstVirtualSocket( const std::string& service_id, const std::string& service_id_hash_salt); // Creates the virtual socket for the service id. - MediumSocket* CreateVirtualSocket(const std::string& service_id, - const std::string& service_id_hash_salt); + std::shared_ptr CreateVirtualSocket( + const std::string& service_id, const std::string& service_id_hash_salt); // Registers the connection response future for the service id. std::shared_ptr> @@ -157,7 +158,7 @@ class MultiplexSocket { // Handles the physical socket closed. void OnPhysicalSocketClosed(); // Remaps and gets the virtual socket by service id hash. - MediumSocket* ReMapAndGetVirtualSocket( + std::shared_ptr ReMapAndGetVirtualSocket( const ByteArray& salted_service_id_hash, const std::string& service_id_hash_salt); // Handles the virtual socket closed. diff --git a/connections/implementation/mediums/multiplex/multiplex_socket_test.cc b/connections/implementation/mediums/multiplex/multiplex_socket_test.cc index aba53de0..cf382eef 100644 --- a/connections/implementation/mediums/multiplex/multiplex_socket_test.cc +++ b/connections/implementation/mediums/multiplex/multiplex_socket_test.cc @@ -38,6 +38,7 @@ #include "internal/platform/pipe.h" #include "internal/platform/single_thread_executor.h" #include "internal/platform/socket.h" +#include "internal/platform/types.h" #include "proto/connections_enums.proto.h" namespace nearby { @@ -89,9 +90,9 @@ class FakeSocket : public MediumSocket { InputStream& GetInputStream() override { return *reader_1_; } OutputStream& GetOutputStream() override { - return IsVirtualSocket() ? *virtual_output_stream_ - : *writer_2_; - } Exception Close() override { + return IsVirtualSocket() ? *virtual_output_stream_ : *writer_2_; + } + Exception Close() override { if (IsVirtualSocket()) { LOG(INFO) << "Multiplex: Closing virtual socket: " << this; CloseLocal(); @@ -117,8 +118,8 @@ class FakeSocket : public MediumSocket { } auto virtual_socket = std::make_shared(medium, outputstream); - LOG(WARNING) << "Created the virtual socket for Medium: " - << Medium_Name(virtual_socket->GetMedium()); + LOG(INFO) << "Created the virtual socket for Medium: " + << Medium_Name(virtual_socket->GetMedium()); if (virtual_sockets_ptr_ == nullptr) { virtual_sockets_ptr_ = virtual_sockets_ptr; @@ -163,12 +164,12 @@ TEST(MultiplexSocketTest, CreateIncomingSocketSuccess) { Medium::BLUETOOTH); MultiplexSocket::ListenForIncomingConnection( std::string(SERVICE_ID_1), Medium::BLUETOOTH, - [](const std::string& service_id, MediumSocket* socket) { + [](const std::string& service_id, std::shared_ptr socket) { LOG(INFO) << "Incoming connection for service_id: " << service_id; }); MultiplexSocket::ListenForIncomingConnection( std::string(SERVICE_ID_2), Medium::BLUETOOTH, - [](const std::string& service_id, MediumSocket* socket) { + [](const std::string& service_id, std::shared_ptr socket) { LOG(INFO) << "Incoming connection for service_id: " << service_id; }); @@ -181,13 +182,11 @@ TEST(MultiplexSocketTest, CreateIncomingSocketSuccess) { fake_socket_ptr, std::string(SERVICE_ID_2), /*first_frame_len*/ 0); ASSERT_EQ(multiplex_socket_incoming_2, multiplex_socket_incoming); + std::shared_ptr virtual_socket_shared = + multiplex_socket_incoming->GetVirtualSocket(std::string(SERVICE_ID_1)); + ASSERT_NE(virtual_socket_shared, nullptr); FakeSocket* virtual_socket = - (FakeSocket*)multiplex_socket_incoming->GetVirtualSocket( - std::string(SERVICE_ID_1)); - if (virtual_socket == nullptr) { - LOG(INFO) << "Virtual socket not found for " << SERVICE_ID_1; - return; - } + down_cast(virtual_socket_shared.get()); SingleThreadExecutor executor; FakeSocket* socket = fake_socket_ptr.get(); @@ -240,12 +239,12 @@ TEST(MultiplexSocketTest, CreateIncomingVirtualSocketSuccess) { Medium::WIFI_LAN); MultiplexSocket::ListenForIncomingConnection( std::string(SERVICE_ID_1), Medium::WIFI_LAN, - [](const std::string& service_id, MediumSocket* socket) { + [](const std::string& service_id, std::shared_ptr socket) { LOG(INFO) << "Incoming connection for service_id: " << service_id; }); MultiplexSocket::ListenForIncomingConnection( std::string(SERVICE_ID_2), Medium::WIFI_LAN, - [](const std::string& service_id, MediumSocket* socket) { + [](const std::string& service_id, std::shared_ptr socket) { LOG(INFO) << "Incoming connection for service_id: " << service_id; }); @@ -254,13 +253,11 @@ TEST(MultiplexSocketTest, CreateIncomingVirtualSocketSuccess) { fake_socket_ptr, std::string(SERVICE_ID_1), /*first_frame_len*/ 0); ASSERT_NE(multiplex_socket_incoming, nullptr); + std::shared_ptr virtual_socket_shared = + multiplex_socket_incoming->GetVirtualSocket(std::string(SERVICE_ID_1)); + ASSERT_NE(virtual_socket_shared, nullptr); FakeSocket* virtual_socket = - (FakeSocket*)multiplex_socket_incoming->GetVirtualSocket( - std::string(SERVICE_ID_1)); - if (virtual_socket == nullptr) { - LOG(INFO) << "Virtual socket not found for " << SERVICE_ID_1; - return; - } + down_cast(virtual_socket_shared.get()); SingleThreadExecutor executor; FakeSocket* socket = fake_socket_ptr.get(); @@ -296,42 +293,57 @@ TEST(MultiplexSocketTest, fake_socket_ptr, std::string(SERVICE_ID_2)); ASSERT_EQ(multiplex_socket_2, multiplex_socket); multiplex_socket->Enable(); - FakeSocket* virtual_socket = (FakeSocket*)multiplex_socket->GetVirtualSocket( - std::string(SERVICE_ID_1)); - if (virtual_socket == nullptr) { - LOG(INFO) << "Virtual socket not found for " << SERVICE_ID_1; - return; - } + std::shared_ptr virtual_socket_shared = + multiplex_socket->GetVirtualSocket(std::string(SERVICE_ID_1)); + ASSERT_NE(virtual_socket_shared, nullptr); + FakeSocket* virtual_socket = + down_cast(virtual_socket_shared.get()); + // This is a timeout test, the real timeout is 3s which is too long for a + // unit test, so we set a short timeout for flakiness test to avoid long wait + // time. + auto flags = FeatureFlags::GetInstance().GetFlags(); + auto original_flags = flags; + flags.multiplex_socket_connection_response_timeout_millis = + absl::Milliseconds(200); + FeatureFlags::GetMutableInstanceForTesting().SetFlags(flags); + + CountDownLatch latch(2); SingleThreadExecutor establish_socket_executor; - establish_socket_executor.Execute([&multiplex_socket]() { + establish_socket_executor.Execute([&multiplex_socket, &latch]() { LOG(INFO) << "EstablishVirtualSocket"; - MediumSocket* socket = + std::shared_ptr socket = multiplex_socket->EstablishVirtualSocket(std::string(SERVICE_ID_2)); LOG(INFO) << "EstablishVirtualSocket finished"; EXPECT_EQ(socket, nullptr); + latch.CountDown(); }); SingleThreadExecutor read_executor; - read_executor.Execute([&multiplex_socket, &fake_socket_ptr]() { + read_executor.Execute([&multiplex_socket, &fake_socket_ptr, &latch]() { auto reader = fake_socket_ptr->reader_2_.get(); LOG(INFO) << "reader_2_ Read start"; ExceptionOr read_int = Base64Utils::ReadInt(reader); if (!read_int.ok()) { ADD_FAILURE() << "Failed to read. Exception:" << read_int.exception(); + } else { + auto length = read_int.result(); + LOG(INFO) << " length:" << length; + EXPECT_GT(length, 0); } - auto length = read_int.result(); - LOG(INFO) << " length:" << length; - EXPECT_GT(length, 0); EXPECT_EQ(multiplex_socket->GetVirtualSocket(std::string(SERVICE_ID_2)), nullptr); + latch.CountDown(); }); - absl::SleepFor(absl::Milliseconds(300)); + EXPECT_TRUE(latch.Await(absl::Seconds(1)).result()); EXPECT_EQ(multiplex_socket->GetVirtualSocketCount(), 1); virtual_socket->Close(); EXPECT_EQ(multiplex_socket->GetVirtualSocketCount(), 0); multiplex_socket->ShutdownAll(); + + // Restore the original flags. + FeatureFlags::GetMutableInstanceForTesting().SetFlags(original_flags); } TEST(MultiplexSocketTest, EstablishVirtualSocket_RemoteAccepted) { @@ -352,7 +364,7 @@ TEST(MultiplexSocketTest, EstablishVirtualSocket_RemoteAccepted) { CountDownLatch latch(1); executor.Execute([&multiplex_socket, &latch]() { LOG(INFO) << "EstablishVirtualSocket"; - MediumSocket* socket = + std::shared_ptr socket = multiplex_socket->EstablishVirtualSocket(std::string(SERVICE_ID_2)); EXPECT_EQ(socket, nullptr); latch.CountDown(); @@ -362,7 +374,7 @@ TEST(MultiplexSocketTest, EstablishVirtualSocket_RemoteAccepted) { multiplex_socket->Enable(); executor.Execute([&multiplex_socket]() { LOG(INFO) << "EstablishVirtualSocket"; - MediumSocket* socket = + std::shared_ptr socket = multiplex_socket->EstablishVirtualSocket(std::string(SERVICE_ID_2)); EXPECT_NE(socket, nullptr); }); diff --git a/connections/implementation/mediums/wifi_lan.cc b/connections/implementation/mediums/wifi_lan.cc index ff3c58ad..9f30ea5d 100644 --- a/connections/implementation/mediums/wifi_lan.cc +++ b/connections/implementation/mediums/wifi_lan.cc @@ -270,10 +270,10 @@ ErrorOr WifiLan::StartAcceptingConnectionsLocked( MultiplexSocket::ListenForIncomingConnection( service_id, Medium::WIFI_LAN, [&callback](const std::string& listening_service_id, - MediumSocket* virtual_socket) mutable { + std::shared_ptr virtual_socket) mutable { if (callback) { callback(listening_service_id, - *(down_cast(virtual_socket))); + *(down_cast(virtual_socket.get()))); } }); } @@ -322,20 +322,21 @@ ErrorOr WifiLan::StartAcceptingConnectionsLocked( MultiplexSocket* multiplex_socket = MultiplexSocket::CreateIncomingSocket( physical_socket_ptr, service_id, read_int.result()); - if (multiplex_socket != nullptr && - multiplex_socket->GetVirtualSocket(service_id)) { - multiplex_sockets_.emplace(server_socket.GetIPAddress(), - multiplex_socket); - MultiplexSocket::StopListeningForIncomingConnection( - service_id, Medium::WIFI_LAN); - LOG(INFO) << "Multiplex virtaul socket created for " - << server_socket.GetIPAddress(); - if (callback) { - callback( - service_id, - *(down_cast( - multiplex_socket->GetVirtualSocket(service_id)))); - callback_called = true; + if (multiplex_socket != nullptr) { + std::shared_ptr virtual_socket = + multiplex_socket->GetVirtualSocket(service_id); + if (virtual_socket) { + multiplex_sockets_.emplace(server_socket.GetIPAddress(), + multiplex_socket); + MultiplexSocket::StopListeningForIncomingConnection( + service_id, Medium::WIFI_LAN); + LOG(INFO) << "Multiplex virtaul socket created for " + << server_socket.GetIPAddress(); + if (callback) { + callback(service_id, *(down_cast( + virtual_socket.get()))); + callback_called = true; + } } } } @@ -568,10 +569,10 @@ ExceptionOr WifiLan::ConnectWithMultiplexSocketLocked( return ExceptionOr(Exception::kFailed); } if (multiplex_socket->IsEnabled()) { - auto* virtual_socket = + std::shared_ptr virtual_socket = multiplex_socket->EstablishVirtualSocket(service_id); // Should not happen. - auto* wlan_socket = down_cast(virtual_socket); + auto* wlan_socket = down_cast(virtual_socket.get()); if (wlan_socket == nullptr) { LOG(INFO) << "Failed to cast to WifiLanSocket for " << service_id << " with ip_address: " @@ -595,9 +596,9 @@ ExceptionOr WifiLan::CreateOutgoingMultiplexSocketLocked( MultiplexSocket* multiplex_socket = MultiplexSocket::CreateOutgoingSocket(physical_socket_ptr, service_id); - auto* virtual_socket = multiplex_socket->GetVirtualSocket(service_id); - // Should not happen. - auto* wlan_socket = down_cast(virtual_socket); + std::shared_ptr virtual_socket = + multiplex_socket->GetVirtualSocket(service_id); + auto* wlan_socket = down_cast(virtual_socket.get()); if (wlan_socket == nullptr) { LOG(INFO) << "Failed to cast to WifiLanSocket for " << service_id << " with ip_address: " diff --git a/connections/implementation/mediums/wifi_lan.h b/connections/implementation/mediums/wifi_lan.h index 3637b158..4dffc2c1 100644 --- a/connections/implementation/mediums/wifi_lan.h +++ b/connections/implementation/mediums/wifi_lan.h @@ -219,7 +219,13 @@ class WifiLan { ABSL_GUARDED_BY(mutex_); // Whether the multiplex feature is enabled. - bool is_multiplex_enabled_ = false; + bool is_multiplex_enabled_ = + NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kEnableMultiplex) && + NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kEnableMultiplexWifiLan); // A map of IpAddress -> MultiplexSocket. absl::flat_hash_map From 6b2ca366c1412e2f796488b8d19cdc97d6cd0dc0 Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 27 Apr 2026 15:40:00 -0700 Subject: [PATCH 062/151] add isForcedUsb logging PiperOrigin-RevId: 906582951 --- internal/proto/analytics/connections_log.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/proto/analytics/connections_log.proto b/internal/proto/analytics/connections_log.proto index cff0fc1f..8da414dc 100644 --- a/internal/proto/analytics/connections_log.proto +++ b/internal/proto/analytics/connections_log.proto @@ -355,6 +355,9 @@ message ConnectionsLog { // The error code returned by Play Integrity API during device attestation. optional int64 play_integrity_error_code = 15; + + // If this connection is forced over USB. + optional bool is_forced_usb = 16; } message DeviceInfo { From e590a06f51d57ce4232ac4eeacb4a2b4d08b4c57 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 28 Apr 2026 08:42:40 -0700 Subject: [PATCH 063/151] Update flags. PiperOrigin-RevId: 906999696 --- .../flags/nearby_connections_feature_flags.h | 21 ++++--------------- .../mediums/bluetooth_classic.h | 10 +-------- connections/implementation/mediums/wifi_lan.h | 11 +--------- 3 files changed, 6 insertions(+), 36 deletions(-) diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h index 070062e1..7d17ab2b 100644 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -31,9 +31,6 @@ namespace nearby_connections_feature { // The timeout in millis to report peripheral device lost. constexpr auto kBlePeripheralLostTimeoutMillis = flags::Flag(kConfigPackage, "45411439", 12000); -// Disable instant on lost on BLE without extended feature. -constexpr auto kDisableInstantOnLostOnBleWithoutExtended = - flags::Flag(kConfigPackage, "45687098", true); // When true, enable advertising for instant on lost feature. constexpr auto kEnableAdvertisingForInstantOnLost = flags::Flag(kConfigPackage, "45708614", true); @@ -55,13 +52,6 @@ constexpr auto kEnableDynamicRoleSwitch = // Enable/Disable GATT client disconnection. constexpr auto kEnableGattClientDisconnection = flags::Flag(kConfigPackage, "45698964", false); -// When true, enable instant on lost feature. -// When true, enable multiplexing in NC. -constexpr auto kEnableMultiplex = - flags::Flag(kConfigPackage, "45647946", false); -// Enable/disable multiplex in NC for AWDL. -constexpr auto kEnableMultiplexAwdl = - flags::Flag(kConfigPackage, "45690761", false); // When true, enable multiplexing in NC for Bluetooth. constexpr auto kEnableMultiplexBluetooth = flags::Flag(kConfigPackage, "45676646", false); @@ -80,9 +70,10 @@ constexpr auto kEnablePayloadReceivedAck = // Enable/Disable safe-to-disconnect feature. constexpr auto kEnableSafeToDisconnect = flags::Flag(kConfigPackage, "45425789", false); -// When true, enable scanning for instant on lost feature. -constexpr auto kEnableScanningForInstantOnLost = - flags::Flag(kConfigPackage, "45708613", true); +// Enable/Disable usage of shared CBPeripheralManager for GATT and L2CAP +// servers. +constexpr auto kEnableSharedPeripheralManager = + flags::Flag(kConfigPackage, "45770787", false); // Stop BLE_V2 scanning when upgrading to WIFI Hotspot or WFD. constexpr auto kEnableStopBleScanningOnWifiUpgrade = flags::Flag(kConfigPackage, "45687902", false); @@ -101,10 +92,6 @@ constexpr auto kMediumMaxAllowedReadBytes = // Disable/Enable refactor of BLE/L2CAP in Nearby Connections SDK. constexpr auto kRefactorBleL2cap = flags::Flag(kConfigPackage, "45737079", false); -// Enable/Disable usage of shared CBPeripheralManager for GATT and L2CAP -// servers. -constexpr auto kEnableSharedPeripheralManager = - flags::Flag(kConfigPackage, "45770787", false); // Set the safe-to-disconnect version. // 0. Disabled all. 1. safe-to-disconnect 2. reserved 3. // auto-reconnect(deprecated) diff --git a/connections/implementation/mediums/bluetooth_classic.h b/connections/implementation/mediums/bluetooth_classic.h index a521d9bb..984112da 100644 --- a/connections/implementation/mediums/bluetooth_classic.h +++ b/connections/implementation/mediums/bluetooth_classic.h @@ -22,10 +22,8 @@ #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" -#include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/mediums/bluetooth_radio.h" #include "connections/implementation/mediums/multiplex/multiplex_socket.h" -#include "internal/flags/nearby_flags.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_classic.h" #include "internal/platform/cancellation_flag.h" @@ -236,13 +234,7 @@ class BluetoothClassic { discovery_callbacks_ ABSL_GUARDED_BY(discovery_callbacks_mutex_); // Whether the multiplex feature is enabled. - bool is_multiplex_enabled_ = - NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplex) && - NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexBluetooth); + bool is_multiplex_enabled_ = false; // A map of Bluetooth MacAddress -> MultiplexSocket. absl::flat_hash_map diff --git a/connections/implementation/mediums/wifi_lan.h b/connections/implementation/mediums/wifi_lan.h index 4dffc2c1..0307806f 100644 --- a/connections/implementation/mediums/wifi_lan.h +++ b/connections/implementation/mediums/wifi_lan.h @@ -18,15 +18,12 @@ #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 "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/mediums/multiplex/multiplex_socket.h" -#include "internal/flags/nearby_flags.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" #include "internal/platform/expected.h" @@ -219,13 +216,7 @@ class WifiLan { ABSL_GUARDED_BY(mutex_); // Whether the multiplex feature is enabled. - bool is_multiplex_enabled_ = - NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplex) && - NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexWifiLan); + bool is_multiplex_enabled_ = false; // A map of IpAddress -> MultiplexSocket. absl::flat_hash_map From ab4c1240f32f214a8e231a20335e0fbc14c70385 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Tue, 28 Apr 2026 18:00:07 -0700 Subject: [PATCH 064/151] fix go/tsan error (data_race) PiperOrigin-RevId: 907273869 --- connections/implementation/mediums/wifi_lan_test.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/connections/implementation/mediums/wifi_lan_test.cc b/connections/implementation/mediums/wifi_lan_test.cc index 2f2ac8c9..b8d47d04 100644 --- a/connections/implementation/mediums/wifi_lan_test.cc +++ b/connections/implementation/mediums/wifi_lan_test.cc @@ -185,6 +185,7 @@ TEST_P(WifiLanTest, CanConnectWithMultiplex) { std::string endpoint_info_name(kEndpointName); CountDownLatch discovered_latch(1); CountDownLatch accept_latch(1); + CountDownLatch connect_latch(1); WifiLanSocket socket_for_server; NsdServiceInfo nsd_service_info; @@ -221,10 +222,11 @@ TEST_P(WifiLanTest, CanConnectWithMultiplex) { ErrorOr socket_for_client_result = wifi_lan_client.Connect(service_id, discovered_service_info, &flag); socket_for_client = std::move(socket_for_client_result.value()); - Base64Utils::WriteInt(&socket_for_client_result.value().GetOutputStream(), - 4); + Base64Utils::WriteInt(&socket_for_client.GetOutputStream(), 4); + connect_latch.CountDown(); }); EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(connect_latch.Await(kWaitDuration).result()); EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); EXPECT_TRUE(socket_for_server.IsValid()); From 3fd8fbf2f191b63d140c7185ebba3c8e86789022 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Tue, 28 Apr 2026 18:08:39 -0700 Subject: [PATCH 065/151] Add enable_single_copy and fix_ble_server_socket_deadlock flags to Nearby Connections GCL. PiperOrigin-RevId: 907276860 --- .../implementation/flags/nearby_connections_feature_flags.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h index 7d17ab2b..9ac89ceb 100644 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -100,10 +100,10 @@ constexpr auto kSafeToDisconnectVersion = flags::Flag(kConfigPackage, "45425841", 0); // Enable/Disable single copy read/write for input/output buffers. constexpr auto kEnableSingleCopy = - flags::Flag(kConfigPackage, "45775979", true); + flags::Flag(kConfigPackage, "45782646", true); // When true, fix the BleServerSocket deadlock/use-after-free (b/494335036). constexpr auto kFixBleServerSocketDeadlock = - flags::Flag(kConfigPackage, "45775192", true); + flags::Flag(kConfigPackage, "45782647", true); } // namespace nearby_connections_feature } // namespace config_package_nearby From 4ae41f4cdfd1d1e5d22a9cfa2d9c887d0c697625 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Tue, 28 Apr 2026 18:13:28 -0700 Subject: [PATCH 066/151] Refactor EndpointChannel ownership to use shared_ptr. PiperOrigin-RevId: 907278448 --- .../base_endpoint_channel_test.cc | 130 ++++----- .../implementation/base_pcp_handler.cc | 249 ++++++++++++------ connections/implementation/base_pcp_handler.h | 25 +- .../implementation/base_pcp_handler_test.cc | 104 ++++---- .../connections_authentication_transport.cc | 11 +- .../connections_authentication_transport.h | 6 +- ...nnections_authentication_transport_test.cc | 35 +-- .../implementation/encryption_runner.cc | 103 +++++--- .../implementation/encryption_runner.h | 19 +- .../implementation/encryption_runner_test.cc | 91 +++---- .../endpoint_channel_manager.cc | 8 +- .../implementation/endpoint_channel_manager.h | 8 +- .../endpoint_channel_manager_test.cc | 22 +- .../implementation/endpoint_manager.cc | 168 ++++++------ connections/implementation/endpoint_manager.h | 5 +- 15 files changed, 546 insertions(+), 438 deletions(-) diff --git a/connections/implementation/base_endpoint_channel_test.cc b/connections/implementation/base_endpoint_channel_test.cc index cb05c1ff..1e3cbbde 100644 --- a/connections/implementation/base_endpoint_channel_test.cc +++ b/connections/implementation/base_endpoint_channel_test.cc @@ -108,20 +108,26 @@ std::function MakeDataMonitor(const std::string& label, std::pair, std::shared_ptr> -DoDhKeyExchange(BaseEndpointChannel* channel_a, - BaseEndpointChannel* channel_b) { +DoDhKeyExchange(std::shared_ptr channel_a, + std::shared_ptr channel_b) { std::shared_ptr context_a; std::shared_ptr context_b; EncryptionRunner crypto_a; EncryptionRunner crypto_b; ClientProxy proxy_a; ClientProxy proxy_b; - CountDownLatch latch(2); + std::shared_ptr shared_channel_a = channel_a; + std::shared_ptr shared_channel_b = channel_b; + + // Create a shared_ptr for the latch to prevent Use-After-Free if the + // negotiation times out and this function returns early. + auto latch = std::make_shared(2); + crypto_a.StartClient( - &proxy_a, "endpoint_id", channel_a, + &proxy_a, "endpoint_id", shared_channel_a, { .on_success_cb = - [&latch, &context_a]( + [latch, &context_a]( const std::string& endpoint_id, std::unique_ptr ukey2, const std::string& auth_token, @@ -131,20 +137,19 @@ DoDhKeyExchange(BaseEndpointChannel* channel_a, auto context = ukey2->ToConnectionContext(); EXPECT_NE(context, nullptr); context_a = std::move(context); - latch.CountDown(); + latch->CountDown(); }, .on_failure_cb = - [&latch](const std::string& endpoint_id, - EndpointChannel* channel) { + [latch](const std::string& endpoint_id) { LOG(INFO) << "client-A side key negotiation failed"; - latch.CountDown(); + latch->CountDown(); }, }); crypto_b.StartServer( - &proxy_b, "endpoint_id", channel_b, + &proxy_b, "endpoint_id", shared_channel_b, { .on_success_cb = - [&latch, &context_b]( + [latch, &context_b]( const std::string& endpoint_id, std::unique_ptr ukey2, const std::string& auth_token, @@ -154,16 +159,15 @@ DoDhKeyExchange(BaseEndpointChannel* channel_a, auto context = ukey2->ToConnectionContext(); EXPECT_NE(context, nullptr); context_b = std::move(context); - latch.CountDown(); + latch->CountDown(); }, .on_failure_cb = - [&latch](const std::string& endpoint_id, - EndpointChannel* channel) { + [latch](const std::string& endpoint_id) { LOG(INFO) << "client-B side key negotiation failed"; - latch.CountDown(); + latch->CountDown(); }, }); - EXPECT_TRUE(latch.Await(absl::Milliseconds(5000)).result()); + EXPECT_TRUE(latch->Await(absl::Milliseconds(5000)).result()); return std::make_pair(std::move(context_a), std::move(context_b)); } @@ -265,20 +269,22 @@ TEST_F(BaseEndpointChannelTest, TryDecrypt) { absl::string_view kMessage = "message"; auto pipe_a = CreatePipe(); // channel_a writes to pipe_a, reads from pipe_b. auto pipe_b = CreatePipe(); // channel_b writes to pipe_b, reads from pipe_a. - TestEndpointChannel channel_a(pipe_b.first.get(), pipe_a.second.get()); - TestEndpointChannel channel_b(pipe_a.first.get(), pipe_b.second.get()); - auto [context_a, context_b] = DoDhKeyExchange(&channel_a, &channel_b); + auto channel_a = std::make_shared(pipe_b.first.get(), + pipe_a.second.get()); + auto channel_b = std::make_shared(pipe_a.first.get(), + pipe_b.second.get()); + auto [context_a, context_b] = DoDhKeyExchange(channel_a, channel_b); ASSERT_NE(context_a, nullptr); ASSERT_NE(context_b, nullptr); - channel_a.EnableEncryption(context_a); - channel_b.EnableEncryption(context_b); + channel_a->EnableEncryption(context_a); + channel_b->EnableEncryption(context_b); std::unique_ptr encrypted_message = - channel_a.EncodeMessageForTests(kMessage); + channel_a->EncodeMessageForTests(kMessage); ExceptionOr decrypted_message = - channel_b.TryDecrypt(ByteArray(*encrypted_message)); + channel_b->TryDecrypt(ByteArray(*encrypted_message)); - EXPECT_TRUE(channel_b.IsEncrypted()); + EXPECT_TRUE(channel_b->IsEncrypted()); EXPECT_TRUE(decrypted_message.ok()); EXPECT_EQ(decrypted_message.result().AsStringView(), kMessage); } @@ -286,16 +292,18 @@ TEST_F(BaseEndpointChannelTest, TryDecrypt) { TEST_F(BaseEndpointChannelTest, TryDecryptFailsWhenDecryptionFails) { auto pipe_a = CreatePipe(); // channel_a writes to pipe_a, reads from pipe_b. auto pipe_b = CreatePipe(); // channel_b writes to pipe_b, reads from pipe_a. - TestEndpointChannel channel_a(pipe_b.first.get(), pipe_a.second.get()); - TestEndpointChannel channel_b(pipe_a.first.get(), pipe_b.second.get()); - auto [context_a, context_b] = DoDhKeyExchange(&channel_a, &channel_b); + auto channel_a = std::make_shared(pipe_b.first.get(), + pipe_a.second.get()); + auto channel_b = std::make_shared(pipe_a.first.get(), + pipe_b.second.get()); + auto [context_a, context_b] = DoDhKeyExchange(channel_a, channel_b); ASSERT_NE(context_a, nullptr); - channel_a.EnableEncryption(context_a); + channel_a->EnableEncryption(context_a); ExceptionOr result = - channel_a.TryDecrypt(ByteArray("invalid message")); + channel_a->TryDecrypt(ByteArray("invalid message")); - EXPECT_TRUE(channel_a.IsEncrypted()); + EXPECT_TRUE(channel_a->IsEncrypted()); EXPECT_FALSE(result.ok()); EXPECT_EQ(result.exception(), Exception::kExecution); } @@ -366,13 +374,15 @@ TEST_F(BaseEndpointChannelTest, EncryptedReadWriteCanNotBeIntercepted) { // to server "b". auto server_b = CreatePipe(); // Data pump "b" reads from client "b", writes // to server "a". - TestEndpointChannel channel_a(server_a.first.get(), client_a.second.get()); - TestEndpointChannel channel_b(server_b.first.get(), client_b.second.get()); + auto channel_a = std::make_shared(server_a.first.get(), + client_a.second.get()); + auto channel_b = std::make_shared(server_b.first.get(), + client_b.second.get()); - ON_CALL(channel_a, GetMedium).WillByDefault([]() { + ON_CALL(*channel_a, GetMedium).WillByDefault([]() { return Medium::BLUETOOTH; }); - ON_CALL(channel_b, GetMedium).WillByDefault([]() { + ON_CALL(*channel_b, GetMedium).WillByDefault([]() { return Medium::BLUETOOTH; }); @@ -385,21 +395,21 @@ TEST_F(BaseEndpointChannelTest, EncryptedReadWriteCanNotBeIntercepted) { MakeDataMonitor("monitor_b", &capture_b, &mutex))); // Run DH key exchange; setup encryption contexts for channels. - auto [context_a, context_b] = DoDhKeyExchange(&channel_a, &channel_b); + auto [context_a, context_b] = DoDhKeyExchange(channel_a, channel_b); ASSERT_NE(context_a, nullptr); ASSERT_NE(context_b, nullptr); - channel_a.EnableEncryption(context_a); - channel_b.EnableEncryption(context_b); + channel_a->EnableEncryption(context_a); + channel_b->EnableEncryption(context_b); - EXPECT_EQ(channel_a.GetType(), "ENCRYPTED_BLUETOOTH"); - EXPECT_EQ(channel_b.GetType(), "ENCRYPTED_BLUETOOTH"); - EXPECT_TRUE(channel_a.IsEncrypted()); - EXPECT_TRUE(channel_b.IsEncrypted()); + EXPECT_EQ(channel_a->GetType(), "ENCRYPTED_BLUETOOTH"); + EXPECT_EQ(channel_b->GetType(), "ENCRYPTED_BLUETOOTH"); + EXPECT_TRUE(channel_a->IsEncrypted()); + EXPECT_TRUE(channel_b->IsEncrypted()); // Start data transfer absl::string_view tx_message = "data message"; - channel_a.Write(tx_message); - ByteArray rx_message = std::move(channel_b.Read().result()); + channel_a->Write(tx_message); + ByteArray rx_message = std::move(channel_b->Read().result()); // Verify expectations. EXPECT_EQ(rx_message.AsStringView(), tx_message); @@ -411,8 +421,8 @@ TEST_F(BaseEndpointChannelTest, EncryptedReadWriteCanNotBeIntercepted) { } // Shutdown test environment. - channel_a.Close(DisconnectionReason::LOCAL_DISCONNECTION); - channel_b.Close(DisconnectionReason::REMOTE_DISCONNECTION); + channel_a->Close(DisconnectionReason::LOCAL_DISCONNECTION); + channel_b->Close(DisconnectionReason::REMOTE_DISCONNECTION); } TEST_F(BaseEndpointChannelTest, CanBesuspendedAndResumed) { @@ -486,43 +496,45 @@ TEST_F(BaseEndpointChannelTest, ReadUnencryptedFrameOnEncryptedChannel) { // Setup test communication environment. auto pipe_a = CreatePipe(); // channel_a writes to pipe_a, reads from pipe_b. auto pipe_b = CreatePipe(); // channel_b writes to pipe_b, reads from pipe_a. - TestEndpointChannel channel_a(pipe_b.first.get(), pipe_a.second.get()); - TestEndpointChannel channel_b(pipe_a.first.get(), pipe_b.second.get()); + auto channel_a = std::make_shared(pipe_b.first.get(), + pipe_a.second.get()); + auto channel_b = std::make_shared(pipe_a.first.get(), + pipe_b.second.get()); - ON_CALL(channel_a, GetMedium).WillByDefault([]() { + ON_CALL(*channel_a, GetMedium).WillByDefault([]() { return Medium::BLUETOOTH; }); - ON_CALL(channel_b, GetMedium).WillByDefault([]() { + ON_CALL(*channel_b, GetMedium).WillByDefault([]() { return Medium::BLUETOOTH; }); // Run DH key exchange; setup encryption contexts for channels. But only // encrypt |channel_b|. - auto [context_a, context_b] = DoDhKeyExchange(&channel_a, &channel_b); + auto [context_a, context_b] = DoDhKeyExchange(channel_a, channel_b); ASSERT_NE(context_a, nullptr); ASSERT_NE(context_b, nullptr); - channel_b.EnableEncryption(context_b); + channel_b->EnableEncryption(context_b); - EXPECT_EQ(channel_a.GetType(), "BLUETOOTH"); - EXPECT_EQ(channel_b.GetType(), "ENCRYPTED_BLUETOOTH"); + EXPECT_EQ(channel_a->GetType(), "BLUETOOTH"); + EXPECT_EQ(channel_b->GetType(), "ENCRYPTED_BLUETOOTH"); // An unencrypted KeepAlive should succeed. std::string keep_alive_message = parser::ForKeepAlive(); - channel_a.Write(keep_alive_message); - ExceptionOr result = channel_b.Read(); + channel_a->Write(keep_alive_message); + ExceptionOr result = channel_b->Read(); EXPECT_TRUE(result.ok()); EXPECT_EQ(result.result().AsStringView(), keep_alive_message); // An unencrypted data frame should fail. absl::string_view tx_message = "data message"; - channel_a.Write(tx_message); - result = channel_b.Read(); + channel_a->Write(tx_message); + result = channel_b->Read(); EXPECT_FALSE(result.ok()); EXPECT_EQ(result.exception(), Exception::kInvalidProtocolBuffer); // Shutdown test environment. - channel_a.Close(DisconnectionReason::LOCAL_DISCONNECTION); - channel_b.Close(DisconnectionReason::REMOTE_DISCONNECTION); + channel_a->Close(DisconnectionReason::LOCAL_DISCONNECTION); + channel_b->Close(DisconnectionReason::REMOTE_DISCONNECTION); } } // namespace diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 1aab772d..0d79ceac 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -212,8 +212,7 @@ std::vector BasePcpHandler::GetConnectionInfoFromResult( } WifiLanConnectionInfo info( std::string(ip_address.begin(), ip_address.end()), - absl::StrCat(absl::Hex(port, absl::kZeroPad16)), "", - {}); + absl::StrCat(absl::Hex(port, absl::kZeroPad16)), "", {}); connection_infos.push_back(info); } } @@ -424,25 +423,25 @@ BooleanMediumSelector BasePcpHandler::ComputeIntersectionOfSupportedMediums( pending_connection_info.connection_options.connection_info .supported_wifi_direct_auth_types; LOG(INFO) << "Remote supported WifiDirect auth types: " - << absl::StrJoin( - remote_supported_wifi_direct_auth_types, ", ", - [](std::string* out, int auth_type) { - absl::StrAppend( - out, - WifiDirectAuthType_Name( - static_cast(auth_type))); - }); + << absl::StrJoin( + remote_supported_wifi_direct_auth_types, ", ", + [](std::string* out, int auth_type) { + absl::StrAppend( + out, + WifiDirectAuthType_Name( + static_cast(auth_type))); + }); auto local_supported_wifi_direct_auth_types = mediums_->GetWifiDirect().GetSupportedWifiDirectAuthTypes(); LOG(INFO) << "Local supported WifiDirect auth types: " - << absl::StrJoin( - local_supported_wifi_direct_auth_types, ", ", - [](std::string* out, int auth_type) { - absl::StrAppend( - out, - WifiDirectAuthType_Name( - static_cast(auth_type))); - }); + << absl::StrJoin( + local_supported_wifi_direct_auth_types, ", ", + [](std::string* out, int auth_type) { + absl::StrAppend( + out, + WifiDirectAuthType_Name( + static_cast(auth_type))); + }); bool found_common_auth_type = false; for (const auto& auth_type : local_supported_wifi_direct_auth_types) { if (auth_type == WifiDirectAuthType::WIFI_DIRECT_TYPE_UNKNOWN) { @@ -587,34 +586,50 @@ void BasePcpHandler::RunOnPcpHandlerThread(const std::string& name, serial_executor_.Execute(name, std::move(runnable)); } -EncryptionRunner::ResultListener BasePcpHandler::GetResultListener() { +EncryptionRunner::ResultListener BasePcpHandler::GetResultListener( + std::shared_ptr endpoint_channel) { + std::weak_ptr weak_channel = endpoint_channel; + return { .on_success_cb = - [this](const std::string& endpoint_id, - std::unique_ptr ukey2, - const std::string& auth_token, - const ByteArray& raw_auth_token) { + [this, weak_channel](const std::string& endpoint_id, + std::unique_ptr ukey2, + const std::string& auth_token, + const ByteArray& raw_auth_token) { + auto channel = weak_channel.lock(); + if (!channel) return; + RunOnPcpHandlerThread( "encryption-success", - [this, endpoint_id, raw_ukey2 = ukey2.release(), auth_token, - raw_auth_token]() RUN_ON_PCP_HANDLER_THREAD() mutable { - OnEncryptionSuccessRunnable( - endpoint_id, std::unique_ptr(raw_ukey2), - auth_token, raw_auth_token); - }); + [this, endpoint_id, weak_channel, raw_ukey2 = ukey2.release(), + auth_token, raw_auth_token]() + RUN_ON_PCP_HANDLER_THREAD() mutable { + std::unique_ptr ukey2(raw_ukey2); + auto channel = weak_channel.lock(); + if (!channel) return; + OnEncryptionSuccessRunnable(endpoint_id, std::move(ukey2), + auth_token, raw_auth_token, + channel); + }); }, .on_failure_cb = - [this](const std::string& endpoint_id, EndpointChannel* channel) { + [this, weak_channel](const std::string& endpoint_id) { + auto channel = weak_channel.lock(); + if (!channel) return; + RunOnPcpHandlerThread( "encryption-failure", - [this, endpoint_id, channel]() RUN_ON_PCP_HANDLER_THREAD() { - LOG(ERROR) - << "Encryption failed for endpoint_id=" << endpoint_id - << " on medium=" - << location::nearby::proto::connections::Medium_Name( - channel->GetMedium()); - OnEncryptionFailureRunnable(endpoint_id, channel); - }); + [this, endpoint_id, weak_channel]() + RUN_ON_PCP_HANDLER_THREAD() { + auto channel = weak_channel.lock(); + if (!channel) return; + LOG(ERROR) + << "Encryption failed for endpoint_id=" << endpoint_id + << " on medium=" + << location::nearby::proto::connections::Medium_Name( + channel->GetMedium()); + OnEncryptionFailureRunnable(endpoint_id, channel); + }); }, }; } @@ -622,36 +637,49 @@ EncryptionRunner::ResultListener BasePcpHandler::GetResultListener() { EncryptionRunner::ResultListener BasePcpHandler::GetResultListenerV3( const NearbyDeviceProvider& device_provider, const NearbyDevice& remote_device, - const EndpointChannel& endpoint_channel) { + std::shared_ptr endpoint_channel) { + std::weak_ptr weak_channel = endpoint_channel; + return { .on_success_cb = - [this, &device_provider, &remote_device, &endpoint_channel]( + [this, &device_provider, &remote_device, weak_channel]( const std::string& endpoint_id, std::unique_ptr ukey2, const std::string& auth_token, const ByteArray& raw_auth_token) { + auto channel = weak_channel.lock(); + if (!channel) return; + RunOnPcpHandlerThread( "encryption-success", - [this, &device_provider, &remote_device, &endpoint_channel, - raw_ukey2 = ukey2.release(), auth_token, - raw_auth_token]() RUN_ON_PCP_HANDLER_THREAD() mutable { - OnEncryptionSuccessRunnableV3( - remote_device, std::unique_ptr(raw_ukey2), - auth_token, raw_auth_token, endpoint_channel, - device_provider); - }); + [this, &device_provider, &remote_device, weak_channel, + raw_ukey2 = ukey2.release(), auth_token, raw_auth_token]() + RUN_ON_PCP_HANDLER_THREAD() mutable { + std::unique_ptr ukey2(raw_ukey2); + auto channel = weak_channel.lock(); + if (!channel) return; + OnEncryptionSuccessRunnableV3( + remote_device, std::move(ukey2), auth_token, + raw_auth_token, channel, device_provider); + }); }, .on_failure_cb = - [this](const std::string& endpoint_id, EndpointChannel* channel) { + [this, weak_channel](const std::string& endpoint_id) { + auto channel = weak_channel.lock(); + if (!channel) return; + RunOnPcpHandlerThread( "encryption-failure", - [this, endpoint_id, channel]() RUN_ON_PCP_HANDLER_THREAD() { - LOG(ERROR) - << "Encryption failed for endpoint_id=" << endpoint_id - << " on medium=" - << location::nearby::proto::connections::Medium_Name( - channel->GetMedium()); - OnEncryptionFailureRunnable(endpoint_id, channel); - }); + [this, endpoint_id, weak_channel]() + RUN_ON_PCP_HANDLER_THREAD() { + auto channel = weak_channel.lock(); + if (!channel) return; + LOG(ERROR) + << "Encryption failed for endpoint_id=" << endpoint_id + << " on medium=" + << location::nearby::proto::connections::Medium_Name( + channel->GetMedium()); + OnEncryptionFailureRunnable(endpoint_id, channel); + }); }, }; } @@ -659,7 +687,7 @@ EncryptionRunner::ResultListener BasePcpHandler::GetResultListenerV3( void BasePcpHandler::OnEncryptionSuccessRunnableV3( const NearbyDevice& remote_device, std::unique_ptr ukey2, absl::string_view auth_token, const ByteArray& raw_auth_token, - const EndpointChannel& endpoint_channel, + std::shared_ptr endpoint_channel, const NearbyDeviceProvider& device_provider) { // Quick fail if we've been removed from pending connections while we were // busy running UKEY2. @@ -674,7 +702,11 @@ void BasePcpHandler::OnEncryptionSuccessRunnableV3( } BasePcpHandler::PendingConnectionInfo& pending_connection_info = it->second; - + // Verify pointer equality to avoid accidental action on superseded + // channels. + if (endpoint_channel != pending_connection_info.channel) { + return; + } // TODO(b/300149127): Add test coverage. if (!ukey2) { // Fail early, if there is no crypto context. @@ -724,7 +756,8 @@ void BasePcpHandler::OnEncryptionSuccessRunnableV3( void BasePcpHandler::OnEncryptionSuccessRunnable( const std::string& endpoint_id, std::unique_ptr ukey2, - const std::string& auth_token, const ByteArray& raw_auth_token) { + const std::string& auth_token, const ByteArray& raw_auth_token, + std::shared_ptr endpoint_channel) { // Quick fail if we've been removed from pending connections while we were // busy running UKEY2. // TODO(b/316421187): Add test coverage @@ -738,6 +771,12 @@ void BasePcpHandler::OnEncryptionSuccessRunnable( BasePcpHandler::PendingConnectionInfo& pending_connection_info = it->second; + // Verify pointer equality to avoid accidental action on superseded + // channels. + if (endpoint_channel != pending_connection_info.channel) { + return; + } + if (!ukey2) { // Fail early, if there is no crypto context. ProcessPreConnectionInitiationFailure( @@ -801,24 +840,21 @@ void BasePcpHandler::RegisterDeviceAfterEncryptionSuccess( } void BasePcpHandler::OnEncryptionFailureRunnable( - const std::string& endpoint_id, EndpointChannel* endpoint_channel) { + const std::string& endpoint_id, + std::shared_ptr endpoint_channel) { auto it = pending_connections_.find(endpoint_id); if (it == pending_connections_.end()) { LOG(INFO) - << "Connection not found on UKEY negotination complete; endpoint_id=" + << "Connection not found on UKEY negotiation complete; endpoint_id=" << endpoint_id; return; } BasePcpHandler::PendingConnectionInfo& pending_connection_info = it->second; - // We had a bug here, caused by a race with EncryptionRunner. We now verify - // the EndpointChannel to avoid it. In a simultaneous connection, we clean - // up one of the two EndpointChannels and then update our pendingConnections - // with the winning channel's state. Closing a channel that was in the - // middle of EncryptionRunner would trigger onEncryptionFailed, and, since - // the map had already updated with the winning EndpointChannel, we closed - // it too by accident. - if (*endpoint_channel != *pending_connection_info.channel) { + + // Verify pointer equality to avoid accidental action on superseded + // channels. + if (endpoint_channel != pending_connection_info.channel) { LOG(INFO) << "Not destroying channel [mismatch]: passed=" << endpoint_channel->GetName() << "; expected=" << pending_connection_info.channel->GetName(); @@ -871,8 +907,8 @@ ConnectionInfo BasePcpHandler::FillConnectionInfo( connection_info.supported_wifi_direct_auth_types = mediums_->GetWifiDirect().GetSupportedWifiDirectAuthTypes(); VLOG(1) << "Set SupportedWifiDirectAuthTypes for WIFI_DIRECT: " - << absl::StrJoin(connection_info.supported_wifi_direct_auth_types, - ","); + << absl::StrJoin(connection_info.supported_wifi_direct_auth_types, + ","); } else { connection_info.supported_wifi_direct_auth_types = {}; } @@ -1005,17 +1041,32 @@ Status BasePcpHandler::RequestConnection( pending_connection_info.medium = channel->GetMedium(); pending_connection_info.channel = std::move(channel); - EndpointChannel* endpoint_channel = - pending_connections_ - .emplace(endpoint_id, std::move(pending_connection_info)) - .first->second.channel.get(); + std::shared_ptr channel_to_close_on_failure = + pending_connection_info.channel; + auto [it, inserted] = pending_connections_.emplace( + endpoint_id, std::move(pending_connection_info)); + if (!inserted) { + LOG(ERROR) << "Failed to add outgoing connection to pending set; " + "endpoint_id=" + << endpoint_id + << ". Likely a collision with an existing pending " + "connection."; + if (channel_to_close_on_failure) { + channel_to_close_on_failure->Close( + location::nearby::proto::connections::DisconnectionReason:: + IO_ERROR); + } + result->Set({Status::kEndpointIoError}); + return; + } + std::shared_ptr endpoint_channel = it->second.channel; LOG(INFO) << "Initiating secure connection: endpoint_id=" << endpoint_id; // Next, we'll set up encryption. When it's done, our future will return // and RequestConnection() will finish. encryption_runner_.StartClient(client, endpoint_id, endpoint_channel, - GetResultListener()); + GetResultListener(endpoint_channel)); }); LOG(INFO) << "Waiting for connection to complete: endpoint_id=" << endpoint_id; @@ -1152,10 +1203,25 @@ Status BasePcpHandler::RequestConnectionV3( pending_connection_info.medium = channel->GetMedium(); pending_connection_info.channel = std::move(channel); - EndpointChannel* endpoint_channel = - pending_connections_ - .emplace(endpoint_id, std::move(pending_connection_info)) - .first->second.channel.get(); + std::shared_ptr channel_to_close_on_failure = + pending_connection_info.channel; + auto [it, inserted] = pending_connections_.emplace( + endpoint_id, std::move(pending_connection_info)); + if (!inserted) { + LOG(ERROR) << "Failed to add outgoing connection to pending set; " + "endpoint_id=" + << endpoint_id + << ". Likely a collision with an existing pending " + "connection."; + if (channel_to_close_on_failure) { + channel_to_close_on_failure->Close( + location::nearby::proto::connections::DisconnectionReason:: + IO_ERROR); + } + result->Set({Status::kEndpointIoError}); + return; + } + std::shared_ptr endpoint_channel = it->second.channel; LOG(INFO) << "Initiating secure connection: endpoint_id=" << endpoint_id; @@ -1165,7 +1231,7 @@ Status BasePcpHandler::RequestConnectionV3( encryption_runner_.StartClient( client, endpoint_id, endpoint_channel, GetResultListenerV3(*(client->GetLocalDeviceProvider()), - remote_device, *endpoint_channel)); + remote_device, endpoint_channel)); }); LOG(INFO) << "Waiting for connection to complete: endpoint_id=" << endpoint_id; @@ -2133,14 +2199,23 @@ Exception BasePcpHandler::OnIncomingConnection( pending_connection_info.medium = channel->GetMedium(); pending_connection_info.channel = std::move(channel); - auto* owned_channel = pending_connections_ - .emplace(connection_request.endpoint_id(), - std::move(pending_connection_info)) - .first->second.channel.get(); + auto [it, inserted] = pending_connections_.emplace( + connection_request.endpoint_id(), std::move(pending_connection_info)); + // This should not happen since BreakTie() above should have checked that + // the endpoint_id is not already in pending_connections_. + if (!inserted) { + LOG(ERROR) << "Failed to add incoming connection to pending set; " + "endpoint_id=" + << connection_request.endpoint_id() + << ". Likely a collision with an existing pending connection."; + return {Exception::kIo}; + } + std::shared_ptr endpoint_channel = it->second.channel; // Next, we'll set up encryption. encryption_runner_.StartServer(client, connection_request.endpoint_id(), - owned_channel, GetResultListener()); + endpoint_channel, + GetResultListener(endpoint_channel)); return {Exception::kSuccess}; } diff --git a/connections/implementation/base_pcp_handler.h b/connections/implementation/base_pcp_handler.h index a1c3db7c..f14665f6 100644 --- a/connections/implementation/base_pcp_handler.h +++ b/connections/implementation/base_pcp_handler.h @@ -476,11 +476,11 @@ class BasePcpHandler : public PcpHandler, // Only (possibly) vector for incoming connections. std::vector supported_mediums; - // Keep track of a channel before we pass it to EndpointChannelManager. This - // is owned until the call to OnEncryptionSuccessRunnableV3 or - // OnEncryptionSuccessRunnable when ownership is transferred to the - // EndpointManager. - std::unique_ptr channel; + // Keep track of a channel before it is registered with the + // EndpointManager. This reference is held during the handshake phase and + // passed to the EndpointManager upon successful encryption + // (OnEncryptionSuccessRunnableV3 or OnEncryptionSuccessRunnable). + std::shared_ptr channel; // Crypto context; initially empty; established first thing after channel // creation by running UKey2 session. While it is in progress, we keep track @@ -509,24 +509,27 @@ class BasePcpHandler : public PcpHandler, void OnEncryptionFailureImpl(const std::string& endpoint_id, EndpointChannel* channel); - EncryptionRunner::ResultListener GetResultListener(); + EncryptionRunner::ResultListener GetResultListener( + std::shared_ptr endpoint_channel); EncryptionRunner::ResultListener GetResultListenerV3( const NearbyDeviceProvider& device_provider, const NearbyDevice& remote_device, - const EndpointChannel& endpoint_channel); + std::shared_ptr endpoint_channel); void OnEncryptionSuccessRunnable( const std::string& endpoint_id, std::unique_ptr ukey2, - const std::string& auth_token, const ByteArray& raw_auth_token); + const std::string& auth_token, const ByteArray& raw_auth_token, + std::shared_ptr endpoint_channel); void OnEncryptionSuccessRunnableV3( const NearbyDevice& remote_device, std::unique_ptr<::securegcm::UKey2Handshake> ukey2, absl::string_view auth_token, const ByteArray& raw_auth_token, - const EndpointChannel& endpoint_channel, + std::shared_ptr endpoint_channel, const NearbyDeviceProvider& device_provider); - void OnEncryptionFailureRunnable(const std::string& endpoint_id, - EndpointChannel* endpoint_channel); + void OnEncryptionFailureRunnable( + const std::string& endpoint_id, + std::shared_ptr endpoint_channel); void RegisterDeviceAfterEncryptionSuccess( std::string_view endpoint_id, std::unique_ptr<::securegcm::UKey2Handshake> ukey2, diff --git a/connections/implementation/base_pcp_handler_test.cc b/connections/implementation/base_pcp_handler_test.cc index 351e3dc3..e1fad699 100644 --- a/connections/implementation/base_pcp_handler_test.cc +++ b/connections/implementation/base_pcp_handler_test.cc @@ -460,9 +460,7 @@ class BasePcpHandlerTest MacAddress::FromString("12:34:56:78:9a:bc", remote_mac_address_); } - void TearDown() override { - env_.Stop(); - } + void TearDown() override { env_.Stop(); } void StartAdvertising(ClientProxy* client, MockPcpHandler* pcp_handler, BooleanMediumSelector allowed = GetParam()) { @@ -645,7 +643,7 @@ class BasePcpHandlerTest void RequestConnection( const std::string& endpoint_id, std::unique_ptr channel_a, - MockEndpointChannel* channel_b, ClientProxy* client, + std::shared_ptr channel_b, ClientProxy* client, MockPcpHandler* pcp_handler, location::nearby::proto::connections::Medium connect_medium, std::atomic_int* flag = nullptr, @@ -715,7 +713,7 @@ class BasePcpHandlerTest void RequestConnectionV3( const NearbyDevice& remote_device, std::unique_ptr channel_a, - MockEndpointChannel* channel_b, ClientProxy* client, + std::shared_ptr channel_b, ClientProxy* client, MockPcpHandler* pcp_handler, location::nearby::proto::connections::Medium connect_medium, FakePresenceDeviceProvider* fake_presence_device_provider, @@ -795,7 +793,7 @@ class BasePcpHandlerTest void RequestConnectionWifiLanFail( const std::string& endpoint_id, std::unique_ptr channel_a, - MockEndpointChannel* channel_b, ClientProxy* client, + std::shared_ptr channel_b, ClientProxy* client, MockPcpHandler* pcp_handler, std::atomic_int* flag = nullptr, Status expected_result = {Status::kSuccess}) { ConnectionRequestInfo info{ @@ -1136,12 +1134,13 @@ TEST_F(BasePcpHandlerTest, WifiMediumFailFallBackToBT) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(1); EXPECT_CALL(*channel_b, CloseImpl).Times(1); EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); - RequestConnectionWifiLanFail(endpoint_id, std::move(channel_a), - channel_b.get(), client_.get(), &pcp_handler); + RequestConnectionWifiLanFail(endpoint_id, std::move(channel_a), channel_b, + client_.get(), &pcp_handler); LOG(INFO) << "RequestConnection complete"; channel_b->Close(); bwu.Shutdown(); @@ -1161,12 +1160,13 @@ TEST_P(BasePcpHandlerTest, RequestConnectionChangesState) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(1); EXPECT_CALL(*channel_b, CloseImpl).Times(1); EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); - RequestConnection("1234", std::move(channel_a), channel_b.get(), - client_.get(), &pcp_handler, connect_medium); + RequestConnection("1234", std::move(channel_a), channel_b, client_.get(), + &pcp_handler, connect_medium); LOG(INFO) << "RequestConnection complete"; EXPECT_TRUE(pcp_handler.HasOutgoingConnections(client_.get())); EXPECT_FALSE(pcp_handler.HasIncomingConnections(client_.get())); @@ -1207,12 +1207,13 @@ TEST_P(BasePcpHandlerTest, CanRequestConnectionPresence) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(1); EXPECT_CALL(*channel_b, CloseImpl).Times(1); EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); - RequestConnection("1234", std::move(channel_a), channel_b.get(), - client_.get(), &pcp_handler, connect_medium); + RequestConnection("1234", std::move(channel_a), channel_b, client_.get(), + &pcp_handler, connect_medium); LOG(INFO) << "RequestConnection complete"; channel_b->Close(); bwu.Shutdown(); @@ -1236,12 +1237,13 @@ TEST_P(BasePcpHandlerTest, CanRequestConnectionLegacy) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(1); EXPECT_CALL(*channel_b, CloseImpl).Times(1); EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); - RequestConnection("1234", std::move(channel_a), channel_b.get(), - client_.get(), &pcp_handler, connect_medium); + RequestConnection("1234", std::move(channel_a), channel_b, client_.get(), + &pcp_handler, connect_medium); LOG(INFO) << "RequestConnection complete"; channel_b->Close(); bwu.Shutdown(); @@ -1266,11 +1268,12 @@ TEST_P(BasePcpHandlerTest, RequestConnectionV3) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - const auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(1); EXPECT_CALL(*channel_b, CloseImpl).Times(1); EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); - RequestConnectionV3(mock_device_, std::move(channel_a), channel_b.get(), + RequestConnectionV3(mock_device_, std::move(channel_a), channel_b, client_.get(), &pcp_handler, connect_medium, &provider); LOG(INFO) << "RequestConnectionV3 complete"; channel_b->Close(); @@ -1297,12 +1300,13 @@ TEST_P(BasePcpHandlerTest, RequestConnectionV3_AuthenticationFailure) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - const auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(1); EXPECT_CALL(*channel_b, CloseImpl).Times(1); EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); RequestConnectionV3( - mock_device_, std::move(channel_a), channel_b.get(), client_.get(), + mock_device_, std::move(channel_a), channel_b, client_.get(), &pcp_handler, connect_medium, &provider, /*flag=*/nullptr, /*expected_result=*/{Status::kSuccess}, /*expected_authentication_status=*/AuthenticationStatus::kFailure); @@ -1328,7 +1332,8 @@ TEST_P(BasePcpHandlerTest, RequestConnectionV3_ConnectImplFailure) { auto mediums = pcp_handler.GetDiscoveryMediums(client_.get()); auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnectionForConnectFailure(connect_medium); - const auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_b, CloseImpl).Times(1); EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); ConnectionRequestInfo info{ @@ -1403,7 +1408,8 @@ TEST_P(BasePcpHandlerTest, RequestConnection_ConnectImplFailure) { auto mediums = pcp_handler.GetDiscoveryMediums(client_.get()); auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnectionForConnectFailure(connect_medium); - const auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_b, CloseImpl).Times(1); EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); ConnectionRequestInfo info{ @@ -1475,12 +1481,13 @@ TEST_P(BasePcpHandlerTest, IoError_RequestConnectionV3Fails) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(AtLeast(1)); EXPECT_CALL(*channel_b, CloseImpl).Times(AtLeast(1)); channel_b->broken_write_ = true; EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); - RequestConnectionV3(mock_device_, std::move(channel_a), channel_b.get(), + RequestConnectionV3(mock_device_, std::move(channel_a), channel_b, client_.get(), &pcp_handler, connect_medium, nullptr, nullptr, {Status::kEndpointIoError}); LOG(INFO) << "RequestConnectionV3 complete"; @@ -1503,13 +1510,14 @@ TEST_P(BasePcpHandlerTest, IoError_RequestConnectionFails) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(AtLeast(1)); EXPECT_CALL(*channel_b, CloseImpl).Times(AtLeast(1)); channel_b->broken_write_ = true; EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); - RequestConnection(endpoint_id, std::move(channel_a), channel_b.get(), - client_.get(), &pcp_handler, connect_medium, nullptr, + RequestConnection(endpoint_id, std::move(channel_a), channel_b, client_.get(), + &pcp_handler, connect_medium, nullptr, {Status::kEndpointIoError}); LOG(INFO) << "RequestConnection complete"; channel_b->Close(); @@ -1531,11 +1539,12 @@ TEST_P(BasePcpHandlerTest, AcceptConnectionChangesState) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(1); EXPECT_CALL(*channel_b, CloseImpl).Times(1); - RequestConnection(endpoint_id, std::move(channel_a), channel_b.get(), - client_.get(), &pcp_handler, connect_medium); + RequestConnection(endpoint_id, std::move(channel_a), channel_b, client_.get(), + &pcp_handler, connect_medium); LOG(INFO) << "Attempting to accept connection: id=" << endpoint_id; EXPECT_EQ(pcp_handler.AcceptConnection(client_.get(), endpoint_id, {}), Status{Status::kSuccess}); @@ -1559,9 +1568,10 @@ TEST_P(BasePcpHandlerTest, RejectConnectionChangesState) { auto mediums = pcp_handler.GetDiscoveryMediums(client_.get()); auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(1); - RequestConnection(endpoint_id, std::move(channel_pair.first), channel_b.get(), + RequestConnection(endpoint_id, std::move(channel_pair.first), channel_b, client_.get(), &pcp_handler, connect_medium); LOG(INFO) << "Attempting to reject connection: id=" << endpoint_id; EXPECT_EQ(pcp_handler.RejectConnection(client_.get(), endpoint_id), @@ -1587,11 +1597,12 @@ TEST_P(BasePcpHandlerTest, OnIncomingFrameChangesState) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(1); EXPECT_CALL(*channel_b, CloseImpl).Times(1); - RequestConnection(endpoint_id, std::move(channel_a), channel_b.get(), - client_.get(), &pcp_handler, connect_medium); + RequestConnection(endpoint_id, std::move(channel_a), channel_b, client_.get(), + &pcp_handler, connect_medium); LOG(INFO) << "Attempting to accept connection: id=" << endpoint_id; EXPECT_CALL(mock_connection_listener_.accepted_cb, Call).Times(1); EXPECT_CALL(mock_connection_listener_.disconnected_cb, Call) @@ -1628,10 +1639,11 @@ TEST_P(BasePcpHandlerTest, DestructorIsCalledOnProtocolEndpoint) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(1); EXPECT_CALL(*channel_b, CloseImpl).Times(1); - RequestConnection(endpoint_id, std::move(channel_a), channel_b.get(), + RequestConnection(endpoint_id, std::move(channel_a), channel_b, client_.get(), &pcp_handler, connect_medium, &destroyed_flag); mediums_count = mediums.size(); @@ -1670,11 +1682,12 @@ TEST_P(BasePcpHandlerTest, MultipleMediumsProduceSingleEndpointLostEvent) { auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(connect_medium); auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; + std::shared_ptr channel_b = + std::move(channel_pair.second); EXPECT_CALL(*channel_a, CloseImpl).Times(1); EXPECT_CALL(*channel_b, CloseImpl).Times(1); EXPECT_CALL(mock_discovery_listener_.endpoint_lost_cb, Call).Times(1); - RequestConnection(endpoint_id, std::move(channel_a), channel_b.get(), + RequestConnection(endpoint_id, std::move(channel_a), channel_b, client_.get(), &pcp_handler, connect_medium, &destroyed_flag); auto allowed_mediums = pcp_handler.GetDiscoveryMediums(client_.get()); @@ -2543,7 +2556,8 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForConnectionsWithPresence) { } TEST_F(BasePcpHandlerTest, IncomingConnectionFailsWithEmptyEndpointId) { - env_.Start(); + env_.Start({.use_simulated_clock = true}); + client_ = std::make_unique(&mock_event_logger_); Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); @@ -2600,7 +2614,6 @@ TEST_F(BasePcpHandlerTest, IncomingConnectionFailsWithEmptyEndpointId) { )pb"; absl::string_view client_session_log = R"pb( event_type: CLIENT_SESSION - client_session { duration_millis: 0 } version: "v1.5.0" )pb"; EXPECT_CALL(mock_event_logger_, @@ -2615,9 +2628,8 @@ TEST_F(BasePcpHandlerTest, IncomingConnectionFailsWithEmptyEndpointId) { Log(Matcher( HasEventType(EventType::START_CLIENT_SESSION)))) .Times(3); - EXPECT_CALL( - mock_event_logger_, - Log(Matcher(EqualsProto(client_session_log)))) + EXPECT_CALL(mock_event_logger_, Log(Matcher(Partially( + EqualsProto(client_session_log))))) .Times(2); EXPECT_CALL(mock_event_logger_, Log(Matcher( Partially(EqualsProto(expected_log))))); diff --git a/connections/implementation/connections_authentication_transport.cc b/connections/implementation/connections_authentication_transport.cc index ec669d9b..f4bb001d 100644 --- a/connections/implementation/connections_authentication_transport.cc +++ b/connections/implementation/connections_authentication_transport.cc @@ -14,7 +14,9 @@ #include "connections/implementation/connections_authentication_transport.h" +#include #include +#include #include "absl/strings/string_view.h" #include "connections/implementation/endpoint_channel.h" @@ -24,19 +26,18 @@ namespace nearby { namespace connections { ConnectionsAuthenticationTransport::ConnectionsAuthenticationTransport( - const EndpointChannel& channel) { - channel_ = const_cast(&channel); -} + std::shared_ptr channel) + : channel_(std::move(channel)) {} void ConnectionsAuthenticationTransport::WriteMessage( absl::string_view message) const { - // channel_ should never be null. + // channel_ is guaranteed valid by shared_ptr ownership CHECK(channel_ != nullptr); channel_->Write(message); } std::string ConnectionsAuthenticationTransport::ReadMessage() const { - // channel_ should never be null. + // channel_ is guaranteed valid by shared_ptr ownership CHECK(channel_ != nullptr); auto response = channel_->Read(); if (response.ok()) { diff --git a/connections/implementation/connections_authentication_transport.h b/connections/implementation/connections_authentication_transport.h index ab7886d4..a4bcafac 100644 --- a/connections/implementation/connections_authentication_transport.h +++ b/connections/implementation/connections_authentication_transport.h @@ -15,6 +15,7 @@ #ifndef THIRD_PARTY_NEARBY_CONNECTIONS_IMPLEMENTATION_CONNECTIONS_AUTHENTICATION_TRANSPORT_H_ #define THIRD_PARTY_NEARBY_CONNECTIONS_IMPLEMENTATION_CONNECTIONS_AUTHENTICATION_TRANSPORT_H_ +#include #include #include "absl/strings/string_view.h" @@ -30,12 +31,13 @@ namespace connections { class ConnectionsAuthenticationTransport : public nearby::AuthenticationTransport { public: - explicit ConnectionsAuthenticationTransport(const EndpointChannel& channel); + explicit ConnectionsAuthenticationTransport( + std::shared_ptr channel); void WriteMessage(absl::string_view message) const override; std::string ReadMessage() const override; private: - EndpointChannel* channel_; + std::shared_ptr channel_; }; } // namespace connections diff --git a/connections/implementation/connections_authentication_transport_test.cc b/connections/implementation/connections_authentication_transport_test.cc index 4198080f..667fbab6 100644 --- a/connections/implementation/connections_authentication_transport_test.cc +++ b/connections/implementation/connections_authentication_transport_test.cc @@ -85,35 +85,38 @@ class MockEndpointChannel : public EndpointChannel { }; TEST(ConnectionsAuthenticationTransportTest, TestWriteMessage) { - MockEndpointChannel channel; + auto channel = std::make_shared(); + auto* channel_ptr = channel.get(); ConnectionsAuthenticationTransport transport(channel); - EXPECT_CALL(channel, Write(_)).WillOnce([&channel](absl::string_view data) { - channel.messages_.push_back(std::string(data)); - return Exception{ - .value = Exception::Value::kSuccess, - }; - }); + EXPECT_CALL(*channel, Write(_)) + .WillOnce([channel_ptr](absl::string_view data) { + channel_ptr->messages_.push_back(std::string(data)); + return Exception{ + .value = Exception::Value::kSuccess, + }; + }); transport.WriteMessage("hello world"); - EXPECT_THAT(channel.messages_, testing::ElementsAre("hello world")); + EXPECT_THAT(channel_ptr->messages_, testing::ElementsAre("hello world")); } TEST(ConnectionsAuthenticationTransportTest, TestReadMessage) { - MockEndpointChannel channel; + auto channel = std::make_shared(); + auto* channel_ptr = channel.get(); ConnectionsAuthenticationTransport transport(channel); - channel.messages_.push_back("hello world"); - EXPECT_CALL(channel, Read()).WillOnce([&channel]() { - std::string ret = channel.messages_[0]; - channel.messages_.erase(channel.messages_.begin()); + channel_ptr->messages_.push_back("hello world"); + EXPECT_CALL(*channel, Read()).WillOnce([channel_ptr]() { + std::string ret = channel_ptr->messages_[0]; + channel_ptr->messages_.erase(channel_ptr->messages_.begin()); return ExceptionOr(ByteArray(ret)); }); EXPECT_EQ(transport.ReadMessage(), "hello world"); } TEST(ConnectionsAuthenticationTransportTest, TestReadMessageFail) { - MockEndpointChannel channel; + auto channel = std::make_shared(); ConnectionsAuthenticationTransport transport(channel); - channel.messages_.push_back("hello world"); - EXPECT_CALL(channel, Read()).WillOnce([]() { + channel->messages_.push_back("hello world"); + EXPECT_CALL(*channel, Read()).WillOnce([]() { return ExceptionOr(Exception::Value::kIo); }); EXPECT_EQ(transport.ReadMessage(), ""); diff --git a/connections/implementation/encryption_runner.cc b/connections/implementation/encryption_runner.cc index 7a2842db..a3ade421 100644 --- a/connections/implementation/encryption_runner.cc +++ b/connections/implementation/encryption_runner.cc @@ -68,9 +68,9 @@ bool HandleEncryptionSuccess(const std::string& endpoint_id, return true; } -void CancelableAlarmRunnable(ClientProxy* client, - const std::string& endpoint_id, - EndpointChannel* endpoint_channel) { +void CancelableAlarmRunnable( + ClientProxy* client, const std::string& endpoint_id, + std::shared_ptr endpoint_channel) { LOG(INFO) << "Timing out encryption for client " << client->GetClientId() << " to endpoint_id=" << endpoint_id << " after " << absl::FormatDuration(kTimeout); @@ -80,18 +80,31 @@ void CancelableAlarmRunnable(ClientProxy* client, class ServerRunnable final { public: ServerRunnable(ClientProxy* client, ScheduledExecutor* alarm_executor, - const std::string& endpoint_id, EndpointChannel* channel, + const std::string& endpoint_id, + std::shared_ptr channel, EncryptionRunner::ResultListener listener) : client_(client), alarm_executor_(alarm_executor), endpoint_id_(endpoint_id), - channel_(channel), + weak_channel_(channel), listener_(std::move(listener)) {} void operator()() { + // Lock the weak pointer. If it fails, the channel was freed. + auto channel = weak_channel_.lock(); + // The IsClosed() check is to provide an early exit if channel has been + // closed. Otherwise the Read() and Write() calls on the channel below will + // return error and exit. + if (!channel || channel->IsClosed()) { + return; + } CancelableAlarm timeout_alarm( "EncryptionRunner.StartServer() timeout", - [this]() { CancelableAlarmRunnable(client_, endpoint_id_, channel_); }, + [this, weak_channel = weak_channel_]() { + if (auto channel = weak_channel.lock()) { + CancelableAlarmRunnable(client_, endpoint_id_, channel); + } + }, kTimeout, alarm_executor_); std::unique_ptr server = @@ -103,7 +116,7 @@ class ServerRunnable final { } // Message 1 (Client Init) - ExceptionOr client_init = channel_->Read(); + ExceptionOr client_init = channel->Read(); if (!client_init.ok()) { LogException(); HandleHandshakeOrIoException(&timeout_alarm); @@ -117,7 +130,7 @@ class ServerRunnable final { if (!parse_result.success) { LogException(); if (parse_result.alert_to_send != nullptr) { - HandleAlertException(parse_result); + HandleAlertException(parse_result, channel); } HandleHandshakeOrIoException(&timeout_alarm); return; @@ -137,7 +150,7 @@ class ServerRunnable final { return; } - Exception write_exception = channel_->Write(*server_init); + Exception write_exception = channel->Write(*server_init); if (!write_exception.Ok()) { LogException(); HandleHandshakeOrIoException(&timeout_alarm); @@ -148,7 +161,7 @@ class ServerRunnable final { << endpoint_id_ << ")."; // Message 3 (Client Finish) - ExceptionOr client_finish = channel_->Read(); + ExceptionOr client_finish = channel->Read(); if (!client_finish.ok()) { LogException(); @@ -163,7 +176,7 @@ class ServerRunnable final { if (!parse_result.success) { LogException(); if (parse_result.alert_to_send != nullptr) { - HandleAlertException(parse_result); + HandleAlertException(parse_result, channel); } HandleHandshakeOrIoException(&timeout_alarm); return; @@ -189,13 +202,13 @@ class ServerRunnable final { void HandleHandshakeOrIoException(CancelableAlarm* timeout_alarm) { timeout_alarm->Cancel(); - listener_.CallFailureCallback(endpoint_id_, channel_); + listener_.CallFailureCallback(endpoint_id_); } void HandleAlertException( - const securegcm::UKey2Handshake::ParseResult& parse_result) const { - Exception write_exception = - channel_->Write(*parse_result.alert_to_send); + const securegcm::UKey2Handshake::ParseResult& parse_result, + std::shared_ptr channel) const { + Exception write_exception = channel->Write(*parse_result.alert_to_send); if (!write_exception.Ok()) { LOG(WARNING) << "In StartServer(), client " << client_->GetClientId() << " failed to pass the alert error message to endpoint(id=" @@ -206,25 +219,39 @@ class ServerRunnable final { ClientProxy* client_; ScheduledExecutor* alarm_executor_; const std::string endpoint_id_; - EndpointChannel* channel_; + std::weak_ptr weak_channel_; EncryptionRunner::ResultListener listener_; }; class ClientRunnable final { public: ClientRunnable(ClientProxy* client, ScheduledExecutor* alarm_executor, - const std::string& endpoint_id, EndpointChannel* channel, + const std::string& endpoint_id, + std::shared_ptr channel, EncryptionRunner::ResultListener listener) : client_(client), alarm_executor_(alarm_executor), endpoint_id_(endpoint_id), - channel_(channel), + weak_channel_(channel), listener_(std::move(listener)) {} void operator()() { + // Lock the weak pointer. If it fails, the channel was freed. + auto channel = weak_channel_.lock(); + // The IsClosed() check is to provide an early exit if channel has been + // closed. Otherwise the Read() and Write() calls on the channel below will + // return error and exit. + if (!channel || channel->IsClosed()) { + return; + } + CancelableAlarm timeout_alarm( "EncryptionRunner.StartClient() timeout", - [this]() { CancelableAlarmRunnable(client_, endpoint_id_, channel_); }, + [this, weak_channel = weak_channel_]() { + if (auto channel = weak_channel.lock()) { + CancelableAlarmRunnable(client_, endpoint_id_, channel); + } + }, kTimeout, alarm_executor_); std::unique_ptr crypto = @@ -248,7 +275,7 @@ class ClientRunnable final { return; } - Exception write_init_exception = channel_->Write(*client_init); + Exception write_init_exception = channel->Write(*client_init); if (!write_init_exception.Ok()) { LogException(); HandleHandshakeOrIoException(&timeout_alarm); @@ -259,7 +286,7 @@ class ClientRunnable final { << endpoint_id_ << ")."; // Message 2 (Server Init) - ExceptionOr server_init = channel_->Read(); + ExceptionOr server_init = channel->Read(); if (!server_init.ok()) { LogException(); @@ -274,7 +301,7 @@ class ClientRunnable final { if (!parse_result.success) { LogException(); if (parse_result.alert_to_send != nullptr) { - HandleAlertException(parse_result); + HandleAlertException(parse_result, channel); } HandleHandshakeOrIoException(&timeout_alarm); return; @@ -294,8 +321,7 @@ class ClientRunnable final { return; } - Exception write_finish_exception = - channel_->Write(*client_finish); + Exception write_finish_exception = channel->Write(*client_finish); if (!write_finish_exception.Ok()) { LogException(); HandleHandshakeOrIoException(&timeout_alarm); @@ -322,12 +348,13 @@ class ClientRunnable final { void HandleHandshakeOrIoException(CancelableAlarm* timeout_alarm) { timeout_alarm->Cancel(); - listener_.CallFailureCallback(endpoint_id_, channel_); + listener_.CallFailureCallback(endpoint_id_); } void HandleAlertException( - const securegcm::UKey2Handshake::ParseResult& parse_result) const { - Exception write_exception = channel_->Write(*parse_result.alert_to_send); + const securegcm::UKey2Handshake::ParseResult& parse_result, + std::shared_ptr channel) const { + Exception write_exception = channel->Write(*parse_result.alert_to_send); if (!write_exception.Ok()) { LOG(WARNING) << "In StartClient(), client " << client_->GetClientId() << " failed to pass the alert error message to endpoint(id=" @@ -338,7 +365,7 @@ class ClientRunnable final { ClientProxy* client_; ScheduledExecutor* alarm_executor_; const std::string endpoint_id_; - EndpointChannel* channel_; + std::weak_ptr weak_channel_; EncryptionRunner::ResultListener listener_; }; @@ -346,19 +373,19 @@ class ClientRunnable final { EncryptionRunner::~EncryptionRunner() { Shutdown(); } -void EncryptionRunner::StartServer(ClientProxy* client, - const std::string& endpoint_id, - EndpointChannel* endpoint_channel, - EncryptionRunner::ResultListener listener) { +void EncryptionRunner::StartServer( + ClientProxy* client, const std::string& endpoint_id, + std::shared_ptr endpoint_channel, + EncryptionRunner::ResultListener listener) { ServerRunnable runnable(client, &alarm_executor_, endpoint_id, endpoint_channel, std::move(listener)); server_executor_.Execute("encryption-server", std::move(runnable)); } -void EncryptionRunner::StartClient(ClientProxy* client, - const std::string& endpoint_id, - EndpointChannel* endpoint_channel, - EncryptionRunner::ResultListener listener) { +void EncryptionRunner::StartClient( + ClientProxy* client, const std::string& endpoint_id, + std::shared_ptr endpoint_channel, + EncryptionRunner::ResultListener listener) { ClientRunnable runnable(client, &alarm_executor_, endpoint_id, endpoint_channel, std::move(listener)); client_executor_.Execute("encryption-client", std::move(runnable)); @@ -387,9 +414,9 @@ void EncryptionRunner::ResultListener::CallSuccessCallback( } void EncryptionRunner::ResultListener::CallFailureCallback( - const std::string& endpoint_id, EndpointChannel* channel) { + const std::string& endpoint_id) { if (on_failure_cb) { - std::move(on_failure_cb)(endpoint_id, channel); + std::move(on_failure_cb)(endpoint_id); } Reset(); } diff --git a/connections/implementation/encryption_runner.h b/connections/implementation/encryption_runner.h index e8e8c186..6e2236d7 100644 --- a/connections/implementation/encryption_runner.h +++ b/connections/implementation/encryption_runner.h @@ -45,8 +45,7 @@ class EncryptionRunner { std::unique_ptr ukey2, const std::string& auth_token, const ByteArray& raw_auth_token); - void CallFailureCallback(const std::string& endpoint_id, - EndpointChannel* channel); + void CallFailureCallback(const std::string& endpoint_id); void Reset(); // @EncryptionRunnerThread @@ -56,27 +55,19 @@ class EncryptionRunner { const ByteArray& raw_auth_token) &&> on_success_cb; - // Encryption has failed. The remote_endpoint_id and channel are given so - // that any pending state can be cleaned up. - // - // We return the EndpointChannel because, at this stage, simultaneous - // connections are a possibility. Use this channel to verify that the state - // you're cleaning up is for this EndpointChannel, and not state for another - // channel to the same endpoint. + // Encryption has failed. // // @EncryptionRunnerThread - absl::AnyInvocable - on_failure_cb; + absl::AnyInvocable on_failure_cb; }; // @AnyThread void StartServer(ClientProxy* client, const std::string& endpoint_id, - EndpointChannel* endpoint_channel, + std::shared_ptr endpoint_channel, ResultListener result_listener); // @AnyThread void StartClient(ClientProxy* client, const std::string& endpoint_id, - EndpointChannel* endpoint_channel, + std::shared_ptr endpoint_channel, ResultListener result_listener); // @AnyThread diff --git a/connections/implementation/encryption_runner_test.cc b/connections/implementation/encryption_runner_test.cc index 5cf31250..f3cd2bd0 100644 --- a/connections/implementation/encryption_runner_test.cc +++ b/connections/implementation/encryption_runner_test.cc @@ -123,21 +123,24 @@ class FakeEndpointChannel : public EndpointChannel { }; struct User { - User(InputStream* reader, OutputStream* writer) : channel(reader, writer) {} + User(InputStream* reader, OutputStream* writer) + : channel(std::make_shared(reader, writer)) {} - FakeEndpointChannel channel; + std::shared_ptr channel; EncryptionRunner crypto; ClientProxy client; }; struct Response { + Response() : latch(2) {} + explicit Response(int count) : latch(count) {} enum class Status { kUnknown = 0, kDone = 1, kFailed = 2, }; - CountDownLatch latch{2}; + CountDownLatch latch; Status server_status = Status::kUnknown; Status client_status = Status::kUnknown; }; @@ -154,7 +157,7 @@ TEST(EncryptionRunnerTest, ReadWrite) { Response response; user_a.crypto.StartServer( - &user_a.client, "endpoint_id", &user_a.channel, + &user_a.client, "endpoint_id", user_a.channel, { .on_success_cb = [&response](const std::string& endpoint_id, @@ -165,15 +168,14 @@ TEST(EncryptionRunnerTest, ReadWrite) { response.latch.CountDown(); }, .on_failure_cb = - [&response](const std::string& endpoint_id, - EndpointChannel* channel) { - channel->Close(); + [&response, &user_a](const std::string& endpoint_id) { + user_a.channel->Close(); response.server_status = Response::Status::kFailed; response.latch.CountDown(); }, }); user_b.crypto.StartClient( - &user_b.client, "endpoint_id", &user_b.channel, + &user_b.client, "endpoint_id", user_b.channel, { .on_success_cb = [&response](const std::string& endpoint_id, @@ -184,9 +186,8 @@ TEST(EncryptionRunnerTest, ReadWrite) { response.latch.CountDown(); }, .on_failure_cb = - [&response](const std::string& endpoint_id, - EndpointChannel* channel) { - channel->Close(); + [&response, &user_b](const std::string& endpoint_id) { + user_b.channel->Close(); response.client_status = Response::Status::kFailed; response.latch.CountDown(); }, @@ -203,14 +204,13 @@ TEST(EncryptionRunnerTest, ClientWriteFails) { /*writer=*/from_a_to_b.second.get()); User user_b(/*reader=*/from_a_to_b.first.get(), /*writer=*/from_b_to_a.second.get()); - Response response; - response.latch = CountDownLatch(1); + Response response(1); // Close server's input stream, so client can't write to it. from_b_to_a.first->Close(); user_b.crypto.StartClient( - &user_b.client, "endpoint_id", &user_b.channel, + &user_b.client, "endpoint_id", user_b.channel, { .on_success_cb = [&response](const std::string& endpoint_id, @@ -221,9 +221,8 @@ TEST(EncryptionRunnerTest, ClientWriteFails) { response.latch.CountDown(); }, .on_failure_cb = - [&response](const std::string& endpoint_id, - EndpointChannel* channel) { - channel->Close(); + [&response, &user_a](const std::string& endpoint_id) { + user_a.channel->Close(); response.client_status = Response::Status::kFailed; response.latch.CountDown(); }, @@ -239,14 +238,13 @@ TEST(EncryptionRunnerTest, ServerWriteFails) { /*writer=*/from_a_to_b.second.get()); User user_b(/*reader=*/from_a_to_b.first.get(), /*writer=*/from_b_to_a.second.get()); - Response response; - response.latch = CountDownLatch(1); + Response response(1); // Close client's input stream, so server can't write to it. from_a_to_b.first->Close(); user_a.crypto.StartServer( - &user_a.client, "endpoint_id", &user_a.channel, + &user_a.client, "endpoint_id", user_a.channel, { .on_success_cb = [&response](const std::string& endpoint_id, @@ -257,24 +255,22 @@ TEST(EncryptionRunnerTest, ServerWriteFails) { response.latch.CountDown(); }, .on_failure_cb = - [&response](const std::string& endpoint_id, - EndpointChannel* channel) { - channel->Close(); + [&response, &user_a](const std::string& endpoint_id) { + user_a.channel->Close(); response.server_status = Response::Status::kFailed; response.latch.CountDown(); }, }); user_b.crypto.StartClient( - &user_b.client, "endpoint_id", &user_b.channel, + &user_b.client, "endpoint_id", user_b.channel, { - .on_success_cb = - [](const std::string& endpoint_id, - std::unique_ptr ukey2, - const std::string& auth_token, - const ByteArray& raw_auth_token) {}, + .on_success_cb = [](const std::string& endpoint_id, + std::unique_ptr ukey2, + const std::string& auth_token, + const ByteArray& raw_auth_token) {}, .on_failure_cb = - [](const std::string& endpoint_id, EndpointChannel* channel) { - channel->Close(); + [&user_b](const std::string& endpoint_id) { + user_b.channel->Close(); }, }); EXPECT_TRUE(response.latch.Await(absl::Milliseconds(5000)).result()); @@ -286,11 +282,10 @@ TEST(EncryptionRunnerTest, ClientSendsGarbageMessage1) { auto from_client_to_server = CreatePipe(); User user_a(/*reader=*/from_client_to_server.first.get(), /*writer=*/from_server_to_client.second.get()); - Response response; - response.latch = CountDownLatch(1); + Response response(1); user_a.crypto.StartServer( - &user_a.client, "endpoint_id", &user_a.channel, + &user_a.client, "endpoint_id", user_a.channel, { .on_success_cb = [&response](const std::string& endpoint_id, @@ -301,9 +296,8 @@ TEST(EncryptionRunnerTest, ClientSendsGarbageMessage1) { response.latch.CountDown(); }, .on_failure_cb = - [&response](const std::string& endpoint_id, - EndpointChannel* channel) { - channel->Close(); + [&response, &user_a](const std::string& endpoint_id) { + user_a.channel->Close(); response.server_status = Response::Status::kFailed; response.latch.CountDown(); }, @@ -327,11 +321,10 @@ TEST(EncryptionRunnerTest, ServerSendsGarbageMessage2) { auto from_client_to_server = CreatePipe(); User user_b(/*reader=*/from_server_to_client.first.get(), /*writer=*/from_client_to_server.second.get()); - Response response; - response.latch = CountDownLatch(1); + Response response(1); user_b.crypto.StartClient( - &user_b.client, "endpoint_id", &user_b.channel, + &user_b.client, "endpoint_id", user_b.channel, { .on_success_cb = [&response](const std::string& endpoint_id, @@ -342,9 +335,8 @@ TEST(EncryptionRunnerTest, ServerSendsGarbageMessage2) { response.latch.CountDown(); }, .on_failure_cb = - [&response](const std::string& endpoint_id, - EndpointChannel* channel) { - channel->Close(); + [&response, &user_b](const std::string& endpoint_id) { + user_b.channel->Close(); response.client_status = Response::Status::kFailed; response.latch.CountDown(); }, @@ -373,11 +365,10 @@ TEST(EncryptionRunnerTest, ClientSendsGarbageMessage3) { /*writer=*/from_server_to_client.second.get()); User user_b(/*reader=*/from_server_to_client.first.get(), /*writer=*/from_client_to_server.second.get()); - Response response; - response.latch = CountDownLatch(1); + Response response(1); user_a.crypto.StartServer( - &user_a.client, "endpoint_id", &user_a.channel, + &user_a.client, "endpoint_id", user_a.channel, { .on_success_cb = [&response](const std::string& endpoint_id, @@ -388,9 +379,8 @@ TEST(EncryptionRunnerTest, ClientSendsGarbageMessage3) { response.latch.CountDown(); }, .on_failure_cb = - [&response](const std::string& endpoint_id, - EndpointChannel* channel) { - channel->Close(); + [&response, &user_a](const std::string& endpoint_id) { + user_a.channel->Close(); response.server_status = Response::Status::kFailed; response.latch.CountDown(); }, @@ -410,7 +400,8 @@ TEST(EncryptionRunnerTest, ClientSendsGarbageMessage3) { EXPECT_TRUE(server_init.ok()); // Client crypto parses message 2. - client_crypto->ParseHandshakeMessage(std::string(server_init.result())); + client_crypto->ParseHandshakeMessage( + std::string(server_init.result().data(), server_init.result().size())); // Client sends garbage instead of message 3 from_client_to_server.second->Write("Garbage"); diff --git a/connections/implementation/endpoint_channel_manager.cc b/connections/implementation/endpoint_channel_manager.cc index b093b6f3..c6af41d4 100644 --- a/connections/implementation/endpoint_channel_manager.cc +++ b/connections/implementation/endpoint_channel_manager.cc @@ -46,7 +46,7 @@ EndpointChannelManager::~EndpointChannelManager() { void EndpointChannelManager::RegisterChannelForEndpoint( ClientProxy* client, const std::string& endpoint_id, - std::unique_ptr channel) { + std::shared_ptr channel) { MutexLock lock(&mutex_); LOG(INFO) << "EndpointChannelManager registered channel of type " @@ -59,7 +59,7 @@ void EndpointChannelManager::RegisterChannelForEndpoint( void EndpointChannelManager::ReplaceChannelForEndpoint( ClientProxy* client, const std::string& endpoint_id, - std::unique_ptr channel, bool enable_encryption) { + std::shared_ptr channel, bool enable_encryption) { MutexLock lock(&mutex_); if (client->IsSafeToDisconnectEnabled(endpoint_id) && channel_state_.IsWaitingForSafeToDisconnectTimeout(endpoint_id)) { @@ -106,7 +106,7 @@ std::shared_ptr EndpointChannelManager::GetChannelForEndpoint( void EndpointChannelManager::SetActiveEndpointChannel( ClientProxy* client, const std::string& endpoint_id, - std::unique_ptr channel, bool enable_encryption) { + std::shared_ptr channel, bool enable_encryption) { // Update the channel first, then encrypt this new channel, if // crypto context is present. channel->SetAnalyticsRecorder(&client->GetAnalyticsRecorder(), endpoint_id); @@ -189,7 +189,7 @@ void EndpointChannelManager::ChannelState::DestroyAll() { } void EndpointChannelManager::ChannelState::UpdateChannelForEndpoint( - const std::string& endpoint_id, std::unique_ptr channel) { + const std::string& endpoint_id, std::shared_ptr channel) { // Create EndpointData instance, if necessary, and populate channel. endpoints_[endpoint_id].channel = std::move(channel); } diff --git a/connections/implementation/endpoint_channel_manager.h b/connections/implementation/endpoint_channel_manager.h index cbc5556a..19183ee0 100644 --- a/connections/implementation/endpoint_channel_manager.h +++ b/connections/implementation/endpoint_channel_manager.h @@ -59,7 +59,7 @@ class EndpointChannelManager final { // be closed before continuing the registration. void RegisterChannelForEndpoint(ClientProxy* client, const std::string& endpoint_id, - std::unique_ptr channel) + std::shared_ptr channel) ABSL_LOCKS_EXCLUDED(mutex_); // Replaces the EndpointChannel to be associated with an endpoint from here on @@ -67,7 +67,7 @@ class EndpointChannelManager final { // to the newly-provided EndpointChannel. void ReplaceChannelForEndpoint(ClientProxy* client, const std::string& endpoint_id, - std::unique_ptr channel, + std::shared_ptr channel, bool enable_encryption) ABSL_LOCKS_EXCLUDED(mutex_); @@ -168,7 +168,7 @@ class EndpointChannelManager final { // Stores a new EndpointChannel for the endpoint. // Prevoius one is destroyed, if it existed. void UpdateChannelForEndpoint(const std::string& endpoint_id, - std::unique_ptr channel); + std::shared_ptr channel); // Stores a new EncryptionContext for the endpoint. // Prevoius one is destroyed, if it existed. @@ -207,7 +207,7 @@ class EndpointChannelManager final { void SetActiveEndpointChannel(ClientProxy* client, const std::string& endpoint_id, - std::unique_ptr channel, + std::shared_ptr channel, bool enable_encryption) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); diff --git a/connections/implementation/endpoint_channel_manager_test.cc b/connections/implementation/endpoint_channel_manager_test.cc index e5ada1ec..d73b746b 100644 --- a/connections/implementation/endpoint_channel_manager_test.cc +++ b/connections/implementation/endpoint_channel_manager_test.cc @@ -110,8 +110,8 @@ std::function MakeDataMonitor(absl::string_view label, std::pair, std::unique_ptr> -DoDhKeyExchange(BaseEndpointChannel* channel_a, - BaseEndpointChannel* channel_b) { +DoDhKeyExchange(std::shared_ptr channel_a, + std::shared_ptr channel_b) { std::unique_ptr context_a; std::unique_ptr context_b; EncryptionRunner crypto_a; @@ -136,8 +136,7 @@ DoDhKeyExchange(BaseEndpointChannel* channel_a, latch.CountDown(); }, .on_failure_cb = - [&latch](const std::string& endpoint_id, - EndpointChannel* channel) { + [&latch](const std::string& endpoint_id) { LOG(INFO) << "client-A side key negotiation failed"; latch.CountDown(); }, @@ -159,8 +158,7 @@ DoDhKeyExchange(BaseEndpointChannel* channel_a, latch.CountDown(); }, .on_failure_cb = - [&latch](const std::string& endpoint_id, - EndpointChannel* channel) { + [&latch](const std::string& endpoint_id) { LOG(INFO) << "client-B side key negotiation failed"; latch.CountDown(); }, @@ -185,9 +183,9 @@ TEST(BaseEndpointChannelManagerTest, RegisterChannelEncryptedReadwrite) { // to server "b". auto server_b = CreatePipe(); // Data pump "b" reads from client "b", writes // to server "a". - auto channel_a = std::make_unique(server_a.first.get(), + auto channel_a = std::make_shared(server_a.first.get(), client_a.second.get()); - auto channel_b = std::make_unique(server_b.first.get(), + auto channel_b = std::make_shared(server_b.first.get(), client_b.second.get()); auto channel_a_raw = channel_a.get(); auto channel_b_raw = channel_b.get(); @@ -208,7 +206,7 @@ TEST(BaseEndpointChannelManagerTest, RegisterChannelEncryptedReadwrite) { MakeDataMonitor(kMonitorB, &capture_b, &mutex))); // Run DH key exchange; setup encryption contexts for channels. - auto context = DoDhKeyExchange(channel_a.get(), channel_b.get()); + auto context = DoDhKeyExchange(channel_a, channel_b); ASSERT_NE(context.first, nullptr); ASSERT_NE(context.second, nullptr); @@ -266,9 +264,9 @@ TEST(BaseEndpointChannelManagerTest, ReplaceChannelNoEncrypted) { // to server "b". auto server_b = CreatePipe(); // Data pump "b" reads from client "b", writes // to server "a". - auto channel_a = std::make_unique(server_a.first.get(), + auto channel_a = std::make_shared(server_a.first.get(), client_a.second.get()); - auto channel_b = std::make_unique(server_b.first.get(), + auto channel_b = std::make_shared(server_b.first.get(), client_b.second.get()); auto channel_a_raw = channel_a.get(); auto channel_b_raw = channel_b.get(); @@ -289,7 +287,7 @@ TEST(BaseEndpointChannelManagerTest, ReplaceChannelNoEncrypted) { MakeDataMonitor(kMonitorB, &capture_b, &mutex))); // Run DH key exchange; setup encryption contexts for channels. - auto context = DoDhKeyExchange(channel_a.get(), channel_b.get()); + auto context = DoDhKeyExchange(channel_a, channel_b); ASSERT_NE(context.first, nullptr); ASSERT_NE(context.second, nullptr); diff --git a/connections/implementation/endpoint_manager.cc b/connections/implementation/endpoint_manager.cc index a93f4688..c0e94b8b 100644 --- a/connections/implementation/endpoint_manager.cc +++ b/connections/implementation/endpoint_manager.cc @@ -539,103 +539,94 @@ void EndpointManager::RegisterEndpoint( ClientProxy* client, const std::string& endpoint_id, const ConnectionResponseInfo& info, const ConnectionOptions& connection_options, - std::unique_ptr channel, + std::shared_ptr channel, const ConnectionListener& listener, const std::string& connection_token) { CountDownLatch latch(1); - // NOTE (unique_ptr<> capture): - // std::unique_ptr<> is not copyable, so we can not pass it to - // lambda capture, because lambda eventually is converted to - // std::function<>. Instead, we release() a pointer, and pass a raw pointer, - // which is copyalbe. We ignore the risk of job not scheduled (and an - // associated risk of memory leak), because this may only happen during - // service shutdown. - RunOnEndpointManagerThread( - "register-endpoint", - [this, client, channel = channel.release(), &endpoint_id, &info, - &connection_options, &listener, &connection_token, &latch]() { - if (endpoints_.contains(endpoint_id)) { - LOG(WARNING) << "Registering duplicate endpoint " << endpoint_id; - // We must remove old endpoint state before registering a new one - // for the same endpoint_id. - RemoveEndpointState(endpoint_id); - } + RunOnEndpointManagerThread("register-endpoint", [this, client, channel, + &endpoint_id, &info, + &connection_options, + &listener, &connection_token, + &latch]() { + if (endpoints_.contains(endpoint_id)) { + LOG(WARNING) << "Registering duplicate endpoint " << endpoint_id; + // We must remove old endpoint state before registering a new one + // for the same endpoint_id. + RemoveEndpointState(endpoint_id); + } - absl::Duration keep_alive_interval = - absl::Milliseconds(connection_options.keep_alive_interval_millis); - absl::Duration keep_alive_timeout = - absl::Milliseconds(connection_options.keep_alive_timeout_millis); - LOG(INFO) << "Registering endpoint " << endpoint_id << " for client " - << client->GetClientId() - << " with keep-alive frame as interval=" - << absl::FormatDuration(keep_alive_interval) - << ", timeout=" << absl::FormatDuration(keep_alive_timeout); + absl::Duration keep_alive_interval = + absl::Milliseconds(connection_options.keep_alive_interval_millis); + absl::Duration keep_alive_timeout = + absl::Milliseconds(connection_options.keep_alive_timeout_millis); + LOG(INFO) << "Registering endpoint " << endpoint_id << " for client " + << client->GetClientId() << " with keep-alive frame as interval=" + << absl::FormatDuration(keep_alive_interval) + << ", timeout=" << absl::FormatDuration(keep_alive_timeout); - // Pass ownership of channel to EndpointChannelManager - LOG(INFO) << "Registering endpoint with channel manager: endpoint " - << endpoint_id; - channel_manager_->RegisterChannelForEndpoint( - client, endpoint_id, std::unique_ptr(channel)); + // Pass ownership of channel to EndpointChannelManager + LOG(INFO) << "Registering endpoint with channel manager: endpoint " + << endpoint_id; + channel_manager_->RegisterChannelForEndpoint(client, endpoint_id, channel); - EndpointState& endpoint_state = - endpoints_ - .emplace(endpoint_id, - EndpointState(endpoint_id, channel_manager_)) - .first->second; + EndpointState& endpoint_state = + endpoints_ + .emplace(endpoint_id, EndpointState(endpoint_id, channel_manager_)) + .first->second; - LOG(INFO) << "Starting workers: endpoint " << endpoint_id; - // For every endpoint, there's normally only one Read handler instance - // running on a dedicated thread. This instance reads data from the - // endpoint and delegates incoming frames to various FrameProcessors. - // Once the frame has been properly handled, it starts reading again - // for the next frame. If the handler fails its read and no other - // EndpointChannels are available for this endpoint, a disconnection - // will be initiated. - endpoint_state.StartEndpointReader([this, client, endpoint_id]() { + LOG(INFO) << "Starting workers: endpoint " << endpoint_id; + // For every endpoint, there's normally only one Read handler instance + // running on a dedicated thread. This instance reads data from the + // endpoint and delegates incoming frames to various FrameProcessors. + // Once the frame has been properly handled, it starts reading again + // for the next frame. If the handler fails its read and no other + // EndpointChannels are available for this endpoint, a disconnection + // will be initiated. + endpoint_state.StartEndpointReader([this, client, endpoint_id]() { + EndpointChannelLoopRunnable( + "Read", client, endpoint_id, + [this, client, endpoint_id](EndpointChannel* channel) { + return HandleData(endpoint_id, client, channel); + }); + }); + + // For every endpoint, there's only one KeepAliveManager instance + // running on a dedicated thread. This instance will periodically send + // out a ping* to the endpoint while listening for an incoming pong**. + // If it fails to send the ping, or if no pong is heard within + // keep_alive_timeout, it initiates a disconnection. + // + // (*) Bluetooth requires a constant outgoing stream of messages. If + // there's silence, Android will break the socket. This is why we + // ping. + // (**) Wifi Hotspots can fail to notice a connection has been lost, + // and they will happily keep writing to /dev/null. This is why we + // listen for the pong. + VLOG(1) << "EndpointManager enabling KeepAlive for endpoint " + << endpoint_id; + endpoint_state.StartEndpointKeepAliveManager( + [this, client, endpoint_id, keep_alive_interval, keep_alive_timeout]( + Mutex* keep_alive_waiter_mutex, + ConditionVariable* keep_alive_waiter) { EndpointChannelLoopRunnable( - "Read", client, endpoint_id, - [this, client, endpoint_id](EndpointChannel* channel) { - return HandleData(endpoint_id, client, channel); + "KeepAliveManager", client, endpoint_id, + [this, keep_alive_interval, keep_alive_timeout, + keep_alive_waiter_mutex, + keep_alive_waiter](EndpointChannel* channel) { + return HandleKeepAlive( + channel, keep_alive_interval, keep_alive_timeout, + keep_alive_waiter_mutex, keep_alive_waiter); }); }); + LOG(INFO) << "Registering endpoint " << endpoint_id + << ", workers started and notifying client."; - // For every endpoint, there's only one KeepAliveManager instance - // running on a dedicated thread. This instance will periodically send - // out a ping* to the endpoint while listening for an incoming pong**. - // If it fails to send the ping, or if no pong is heard within - // keep_alive_timeout, it initiates a disconnection. - // - // (*) Bluetooth requires a constant outgoing stream of messages. If - // there's silence, Android will break the socket. This is why we - // ping. - // (**) Wifi Hotspots can fail to notice a connection has been lost, - // and they will happily keep writing to /dev/null. This is why we - // listen for the pong. - VLOG(1) << "EndpointManager enabling KeepAlive for endpoint " - << endpoint_id; - endpoint_state.StartEndpointKeepAliveManager( - [this, client, endpoint_id, keep_alive_interval, - keep_alive_timeout](Mutex* keep_alive_waiter_mutex, - ConditionVariable* keep_alive_waiter) { - EndpointChannelLoopRunnable( - "KeepAliveManager", client, endpoint_id, - [this, keep_alive_interval, keep_alive_timeout, - keep_alive_waiter_mutex, - keep_alive_waiter](EndpointChannel* channel) { - return HandleKeepAlive( - channel, keep_alive_interval, keep_alive_timeout, - keep_alive_waiter_mutex, keep_alive_waiter); - }); - }); - LOG(INFO) << "Registering endpoint " << endpoint_id - << ", workers started and notifying client."; - - // It's now time to let the client know of this new connection so that - // they can accept or reject it. - client->OnConnectionInitiated(endpoint_id, info, connection_options, - listener, connection_token); - latch.CountDown(); - }); + // It's now time to let the client know of this new connection so that + // they can accept or reject it. + client->OnConnectionInitiated(endpoint_id, info, connection_options, + listener, connection_token); + latch.CountDown(); + }); latch.Await(); } @@ -722,7 +713,7 @@ void EndpointManager::DiscardEndpoint(ClientProxy* client, // of `serial_executor_` and will still have access to a valid // `is_shutdown_`. // - // TODO(b/280653613): Develop a more robost solution to prevent + // TODO(b/280653613): Develop a more robust solution to prevent // accessing an already destroyed `ClientProxy` during destruction. { MutexLock lock(&mutex_); @@ -953,8 +944,7 @@ std::vector EndpointManager::SendTransferFrameBytes( continue; } - Exception write_exception = - channel->Write(bytes, packet_meta_data); + Exception write_exception = channel->Write(bytes, packet_meta_data); if (!write_exception.Ok()) { failed_endpoint_ids.push_back(endpoint_id); LOG(INFO) << "Failed to send packet; endpoint_id=" << endpoint_id; diff --git a/connections/implementation/endpoint_manager.h b/connections/implementation/endpoint_manager.h index 68f7f4f9..4b47f9c5 100644 --- a/connections/implementation/endpoint_manager.h +++ b/connections/implementation/endpoint_manager.h @@ -25,6 +25,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" #include "absl/time/time.h" +#include "connections/connection_options.h" #include "connections/implementation/analytics/packet_meta_data.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" @@ -34,6 +35,8 @@ #include "internal/platform/byte_array.h" #include "internal/platform/condition_variable.h" #include "internal/platform/count_down_latch.h" +#include "internal/platform/exception.h" +#include "internal/platform/mutex.h" #include "internal/platform/runnable.h" #include "internal/platform/single_thread_executor.h" @@ -112,7 +115,7 @@ class EndpointManager { void RegisterEndpoint(ClientProxy* client, const std::string& endpoint_id, const ConnectionResponseInfo& info, const ConnectionOptions& connection_options, - std::unique_ptr channel, + std::shared_ptr channel, const ConnectionListener& listener, const std::string& connection_token); // Called when a client explicitly asks to disconnect from this endpoint. In From ea61e9cefa5795860f88b16d7c43e445d0963d8c Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 29 Apr 2026 22:40:37 -0700 Subject: [PATCH 067/151] Automated Code Change PiperOrigin-RevId: 907961119 --- internal/platform/flags/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/platform/flags/BUILD b/internal/platform/flags/BUILD index e0e875a0..334caa90 100644 --- a/internal/platform/flags/BUILD +++ b/internal/platform/flags/BUILD @@ -22,7 +22,6 @@ cc_library( ], visibility = [ "//connections:__subpackages__", - "//connections:partners", "//internal:__subpackages__", "//location/nearby/cpp:__subpackages__", "//location/nearby/testing:__subpackages__", From 6f52ec53dd26ba0b2436611d20d53d1b20017bab Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 30 Apr 2026 13:54:40 -0700 Subject: [PATCH 068/151] Remove unnecessary code. PiperOrigin-RevId: 908359047 --- connections/implementation/BUILD | 7 +- connections/implementation/analytics/BUILD | 4 - .../analytics/packet_meta_data.h | 101 ----- .../analytics/throughput_recorder.cc | 362 ------------------ .../analytics/throughput_recorder.h | 178 --------- .../analytics/throughput_recorder_test.cc | 241 ------------ .../implementation/base_endpoint_channel.cc | 22 -- .../implementation/base_endpoint_channel.h | 9 +- .../implementation/base_pcp_handler.cc | 3 +- connections/implementation/base_pcp_handler.h | 9 +- .../implementation/base_pcp_handler_test.cc | 4 +- connections/implementation/bwu_manager.cc | 5 +- connections/implementation/bwu_manager.h | 5 +- .../implementation/bwu_manager_test.cc | 23 +- ...nnections_authentication_transport_test.cc | 75 +--- .../implementation/encryption_runner_test.cc | 9 +- connections/implementation/endpoint_channel.h | 9 - .../implementation/endpoint_manager.cc | 31 +- connections/implementation/endpoint_manager.h | 10 +- .../implementation/endpoint_manager_test.cc | 91 +---- .../implementation/fake_endpoint_channel.h | 9 - .../implementation/mock_endpoint_channel.h | 77 ++++ connections/implementation/payload_manager.cc | 41 +- connections/implementation/payload_manager.h | 7 +- .../implementation/payload_manager_test.cc | 6 +- 25 files changed, 153 insertions(+), 1185 deletions(-) delete mode 100644 connections/implementation/analytics/packet_meta_data.h delete mode 100644 connections/implementation/analytics/throughput_recorder.cc delete mode 100644 connections/implementation/analytics/throughput_recorder.h delete mode 100644 connections/implementation/analytics/throughput_recorder_test.cc create mode 100644 connections/implementation/mock_endpoint_channel.h diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index cdb58602..edc8fd47 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -214,6 +214,7 @@ cc_library( "fake_bwu_handler.h", "fake_endpoint_channel.h", "mock_device.h", + "mock_endpoint_channel.h", "mock_service_controller.h", "mock_service_controller_router.h", "offline_simulation_user.h", @@ -440,8 +441,8 @@ cc_test( ], deps = [ ":internal", + ":internal_test", "//connections:core_types", - "//connections/implementation/analytics", "//connections/implementation/flags:connections_flags", "//internal/flags:nearby_flags", "//internal/platform:base", @@ -491,13 +492,11 @@ cc_test( ], deps = [ ":internal", - "//connections/implementation/analytics", + ":internal_test", "//internal/platform:base", "//internal/platform/implementation/g3", # build_cleaner: keep - "//proto:connections_enums_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", - "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], ) diff --git a/connections/implementation/analytics/BUILD b/connections/implementation/analytics/BUILD index 019db88e..f84377b4 100644 --- a/connections/implementation/analytics/BUILD +++ b/connections/implementation/analytics/BUILD @@ -20,15 +20,12 @@ cc_library( name = "analytics", srcs = [ "analytics_recorder.cc", - "throughput_recorder.cc", ], hdrs = [ "advertising_metadata_params.h", "analytics_recorder.h", "connection_attempt_metadata_params.h", "discovery_metadata_params.h", - "packet_meta_data.h", - "throughput_recorder.h", ], copts = ["-DCORE_ADAPTER_DLL"], visibility = ["//connections:__subpackages__"], @@ -58,7 +55,6 @@ cc_test( size = "small", srcs = [ "analytics_recorder_test.cc", - "throughput_recorder_test.cc", ], shard_count = 16, deps = [ diff --git a/connections/implementation/analytics/packet_meta_data.h b/connections/implementation/analytics/packet_meta_data.h deleted file mode 100644 index ea29c856..00000000 --- a/connections/implementation/analytics/packet_meta_data.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2022-2023 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 NEARBY_CONNECTIONS_IMPLEMENTATION_ANALYTICS_PACKET_META_DATA_H_ -#define NEARBY_CONNECTIONS_IMPLEMENTATION_ANALYTICS_PACKET_META_DATA_H_ - -#include - -#include "absl/time/time.h" -#include "internal/platform/implementation/system_clock.h" - -namespace nearby { -namespace analytics { - -struct PacketMetaData { - int packet_size; - absl::Time file_io_start_time; - absl::Time file_io_end_time; - absl::Time encryption_start_time; - absl::Time encryption_end_time; - absl::Time socket_io_start_time; - absl::Time socket_io_end_time; - - void Reset() { - file_io_start_time = SystemClock::ElapsedRealtime(); - encryption_start_time = SystemClock::ElapsedRealtime(); - socket_io_start_time = SystemClock::ElapsedRealtime(); - packet_size = 0; - } - - void SetPacketSize(int packet_size) { - this->packet_size = packet_size; - } - - int GetPacketSize() const { - return packet_size; - } - - void StartFileIo() { - file_io_start_time = SystemClock::ElapsedRealtime(); - } - - void StopFileIo() { - file_io_end_time = SystemClock::ElapsedRealtime(); - } - - void StartEncryption() { - encryption_start_time = SystemClock::ElapsedRealtime(); - } - - void StopEncryption() { - encryption_end_time = SystemClock::ElapsedRealtime(); - } - - void StartSocketIo() { - socket_io_start_time = SystemClock::ElapsedRealtime(); - } - - void StopSocketIo() { - socket_io_end_time = SystemClock::ElapsedRealtime(); - } - - int64_t GetEncryptionTimeInMillis() const { - if (encryption_end_time > encryption_start_time) { - return absl::ToInt64Milliseconds(encryption_end_time - - encryption_start_time); - } - return 0; - } - - int64_t GetFileIoTimeInMillis() const { - if (file_io_end_time > file_io_start_time) { - return absl::ToInt64Milliseconds(file_io_end_time - file_io_start_time); - } - return 0; - } - - int64_t GetSocketIoTimeInMillis() const { - if (socket_io_end_time > socket_io_start_time) { - return absl::ToInt64Milliseconds(socket_io_end_time - - socket_io_start_time); - } - return 0; - } -}; - -} // namespace analytics -} // namespace nearby - -#endif // NEARBY_CONNECTIONS_IMPLEMENTATION_ANALYTICS_PACKET_META_DATA_H_ diff --git a/connections/implementation/analytics/throughput_recorder.cc b/connections/implementation/analytics/throughput_recorder.cc deleted file mode 100644 index ab467d12..00000000 --- a/connections/implementation/analytics/throughput_recorder.cc +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright 2022-2023 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. - -#include "connections/implementation/analytics/throughput_recorder.h" - -#include -#include -#include -#include - -#include "absl/base/no_destructor.h" -#include "absl/container/flat_hash_map.h" -#include "absl/strings/str_format.h" -#include "absl/time/time.h" -#include "connections/implementation/analytics/packet_meta_data.h" -#include "connections/payload_type.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex_lock.h" - -namespace nearby { -namespace analytics { - -using Medium = ::location::nearby::proto::connections::Medium; -using ::nearby::connections::PayloadDirection; -using ::nearby::connections::PayloadType; - -namespace { -constexpr int kDefaultThroughoutKbps = 0; -constexpr int kKbInBytes = 1024; -constexpr int kSecInMs = 1000; - -int64_t CalculateThroughputKBps(int64_t total_byte_size, int64_t total_millis) { - if (total_millis > 0) { - return total_byte_size * kSecInMs / kKbInBytes / total_millis; - } - return kDefaultThroughoutKbps; -} - -int64_t CalculateThroughputMBps(int64_t throughputKBps) { - return throughputKBps / kKbInBytes; -} - -std::string ToString(PayloadType type) { - switch (type) { - case PayloadType::kBytes: - return std::string("Bytes"); - case PayloadType::kStream: - return std::string("Stream"); - case PayloadType::kFile: - return std::string("File"); - case PayloadType::kUnknown: - return std::string("Unknown"); - } -} -} // namespace - -ThroughputRecorderContainer& ThroughputRecorderContainer::GetInstance() { - static absl::NoDestructor instance; - return *instance; -} - -ThroughputRecorderContainer::ThroughputRecorder::ThroughputRecorder( - int64_t payload_id, PayloadDirection payload_direction, - PayloadType payload_type) - : payload_id_(payload_id), - payload_direction_(payload_direction), - payload_type_(payload_type) { - LOG_IF(DFATAL, payload_type_ == PayloadType::kUnknown) - << "Invalid payload type"; -} - -void ThroughputRecorderContainer::ThroughputRecorder::Start() { - if (VLOG_IS_ON(1)) { - std::string direction = - (payload_direction_ == PayloadDirection::INCOMING_PAYLOAD) ? "; Receive" - : "; Send"; - VLOG(1) << "Start TP profiling for payload_id:" << payload_id_ << direction; - } - - start_timestamp_ = SystemClock::ElapsedRealtime(); -} - -bool ThroughputRecorderContainer::ThroughputRecorder::Stop() { - VLOG(1) << "Stop TP profiling for payload_id:" << payload_id_; - { - absl::Time stop_timestamp = SystemClock::ElapsedRealtime(); - int64_t total_byte_size = 0; - int medium_size = throughputs_.size(); - - if (!success_) { - if (!throughputs_.empty()) { - for (auto& tp : throughputs_) { - tp.second.SetLastTimestamp(stop_timestamp); - } - } - } - - for (auto& tp : throughputs_) { - tp.second.dump(payload_direction_, payload_type_); - total_byte_size += tp.second.GetTotalByteSize(); - } - - throughputs_.clear(); - - int64_t total_millis = - absl::ToInt64Milliseconds(stop_timestamp - start_timestamp_); - throughput_kbps_ = CalculateThroughputKBps(total_byte_size, total_millis); - int64_t throughput_mbps = CalculateThroughputMBps(throughput_kbps_); - - if (medium_size > 1) { - if (throughput_kbps_ != kDefaultThroughoutKbps) { - std::string dump_content = absl::StrFormat( - "%s %s data(%lld bytes) %s, overall used %lld milliseconds, " - "throughput " - "is %lld MB/s (%lld KB/s), File IO takes %lld ms, %s takes %lld " - "ms, " - "Socket IO takes %lld ms", - (payload_direction_ == PayloadDirection::INCOMING_PAYLOAD) - ? "Received" - : "Sent", - ToString(payload_type_), total_byte_size, - success_ ? "SUCCEEDED" : "FAILED", total_millis, throughput_mbps, - throughput_kbps_, file_io_time_, - (payload_direction_ == PayloadDirection::INCOMING_PAYLOAD) - ? "Decryption" - : "Encryption", - encryption_time_, socket_io_time_); - LOG(INFO) << dump_content; - } - } - } - return true; -} - -void ThroughputRecorderContainer::ThroughputRecorder::MarkAsSuccess() { - success_ = true; -} - -void ThroughputRecorderContainer::ThroughputRecorder::Throughput::Add( - int frame_size, int64_t file_io_time, int64_t encryption_time, - int64_t socket_io_time) { - total_byte_size_ += frame_size; - last_timestamp_ = SystemClock::ElapsedRealtime(); - file_io_time_ += file_io_time; - encryption_time_ += encryption_time; - socket_io_time_ += socket_io_time; -} - -bool ThroughputRecorderContainer::ThroughputRecorder::Throughput::dump( - PayloadDirection payload_direction, PayloadType payload_type) { - int64_t total_millis = - absl::ToInt64Milliseconds(last_timestamp_ - start_timestamp_); - int64_t throughput_kbps = - CalculateThroughputKBps(total_byte_size_, total_millis); - if (throughput_kbps == kDefaultThroughoutKbps) { - return false; - } - int64_t throughput_mbps = CalculateThroughputMBps(throughput_kbps); - int64_t other = - total_millis - file_io_time_ - encryption_time_ - socket_io_time_; - std::string dump_content = absl::StrFormat( - "%s %s data(%lld bytes) via %s used %lld ms, throughput is %lld " - "MB/s (%lld KB/s), File IO takes %lld ms, %s takes %lld ms, " - "Socket IO takes %lld ms, " - "Other takes %lld ms", - (payload_direction == PayloadDirection::INCOMING_PAYLOAD) ? "Received" - : "Sent", - ToString(payload_type), total_byte_size_, - location::nearby::proto::connections::Medium_Name(medium_), total_millis, - throughput_mbps, throughput_kbps, file_io_time_, - (payload_direction == PayloadDirection::INCOMING_PAYLOAD) ? "Decryption" - : "Encryption", - encryption_time_, socket_io_time_, other); - LOG(INFO) << dump_content; - return true; -} - -ThroughputRecorderContainer::ThroughputRecorder::Throughput& -ThroughputRecorderContainer::ThroughputRecorder::GetThroughput( - Medium medium, int64_t duration_millis) { - auto it = throughputs_.find(medium); - if (it == throughputs_.end()) { - throughputs_.emplace( - medium, Throughput(medium, SystemClock::ElapsedRealtime() - - absl::Milliseconds(duration_millis))); - return throughputs_.find(medium)->second; - } - return it->second; -} - -int ThroughputRecorderContainer::ThroughputRecorder::GetThroughputsSize() - const { - return throughputs_.size(); -} - -int64_t ThroughputRecorderContainer::ThroughputRecorder::GetThroughputKbps() - const { - return throughput_kbps_; -} - -int64_t ThroughputRecorderContainer::ThroughputRecorder::GetDurationMillis() - const { - return duration_millis_; -} - -void ThroughputRecorderContainer::ThroughputRecorder::UpdateFrameData( - Medium medium, PacketMetaData& packetMetaData) { - duration_millis_ = packetMetaData.GetEncryptionTimeInMillis() + - packetMetaData.GetFileIoTimeInMillis() + - packetMetaData.GetSocketIoTimeInMillis(); - GetThroughput(medium, duration_millis_) - .Add(packetMetaData.packet_size, packetMetaData.GetFileIoTimeInMillis(), - packetMetaData.GetEncryptionTimeInMillis(), - packetMetaData.GetSocketIoTimeInMillis()); - CalculateDurationTimes(packetMetaData); -} - -void ThroughputRecorderContainer::ThroughputRecorder::CalculateDurationTimes( - const PacketMetaData& packetMetaData) { - encryption_time_ += packetMetaData.GetEncryptionTimeInMillis(); - socket_io_time_ += packetMetaData.GetSocketIoTimeInMillis(); - file_io_time_ += packetMetaData.GetFileIoTimeInMillis(); -} - -// Implementation for ThroughputRecorderContainer - -void ThroughputRecorderContainer::Start(int64_t payload_id, - PayloadDirection payload_direction, - PayloadType payload_type) { - if (payload_type == PayloadType::kUnknown) { - return; - } - MutexLock lock(&mutex_); - auto it = throughput_recorders_.find( - std::pair(payload_id, payload_direction)); - if (it == throughput_recorders_.end()) { - auto instance = std::make_unique( - payload_id, payload_direction, payload_type); - instance->Start(); - throughput_recorders_.emplace( - std::pair(payload_id, payload_direction), - std::move(instance)); - } else { - it->second->Start(); - } -} - -void ThroughputRecorderContainer::UpdateFrameData( - int64_t payload_id, PayloadDirection payload_direction, Medium medium, - PacketMetaData& packet_meta_data) { - MutexLock lock(&mutex_); - auto it = throughput_recorders_.find( - std::pair(payload_id, payload_direction)); - if (it != throughput_recorders_.end()) { - it->second->UpdateFrameData(medium, packet_meta_data); - } -} - -void ThroughputRecorderContainer::MarkAsSuccess( - int64_t payload_id, PayloadDirection payload_direction) { - MutexLock lock(&mutex_); - auto it = throughput_recorders_.find( - std::pair(payload_id, payload_direction)); - if (it != throughput_recorders_.end()) { - it->second->MarkAsSuccess(); - } -} - -int64_t ThroughputRecorderContainer::StopTPRecorder( - int64_t payload_id, PayloadDirection payload_direction) { - MutexLock lock(&mutex_); - auto it = throughput_recorders_.find( - std::pair(payload_id, payload_direction)); - if (it != throughput_recorders_.end()) { - it->second->Stop(); - int64_t throughput_kbps = it->second->GetThroughputKbps(); - throughput_recorders_.erase(it); - return throughput_kbps; - } - return 0; -} - -int ThroughputRecorderContainer::GetSize() { - MutexLock lock(&mutex_); - return throughput_recorders_.size(); -} - -void ThroughputRecorderContainer::ClearForTest() { - MutexLock lock(&mutex_); - throughput_recorders_.clear(); -} - -int64_t ThroughputRecorderContainer::GetTotalByteSizeForTesting( - int64_t payload_id, PayloadDirection payload_direction, Medium medium) { - MutexLock lock(&mutex_); - auto it = throughput_recorders_.find( - std::pair(payload_id, payload_direction)); - if (it != throughput_recorders_.end()) { - return it->second->GetThroughput(medium, 0).GetTotalByteSize(); - } - return 0; -} - -int ThroughputRecorderContainer::GetThroughputsSizeForTesting( - int64_t payload_id, PayloadDirection payload_direction) { - MutexLock lock(&mutex_); - auto it = throughput_recorders_.find( - std::pair(payload_id, payload_direction)); - if (it != throughput_recorders_.end()) { - return it->second->GetThroughputsSize(); - } - return 0; -} - -int64_t ThroughputRecorderContainer::GetDurationMillisForTesting( - int64_t payload_id, PayloadDirection payload_direction) { - MutexLock lock(&mutex_); - auto it = throughput_recorders_.find( - std::pair(payload_id, payload_direction)); - if (it != throughput_recorders_.end()) { - return it->second->GetDurationMillis(); - } - return 0; -} - -int64_t ThroughputRecorderContainer::GetThroughputKbpsForTesting( - int64_t payload_id, PayloadDirection payload_direction) { - MutexLock lock(&mutex_); - auto it = throughput_recorders_.find( - std::pair(payload_id, payload_direction)); - if (it != throughput_recorders_.end()) { - return it->second->GetThroughputKbps(); - } - return 0; -} - -bool ThroughputRecorderContainer::DumpForTesting( - int64_t payload_id, PayloadDirection payload_direction, Medium medium) { - MutexLock lock(&mutex_); - auto it = throughput_recorders_.find( - std::pair(payload_id, payload_direction)); - if (it != throughput_recorders_.end()) { - return it->second->GetThroughput(medium, 0).dump( - payload_direction, it->second->GetPayloadType()); - } - return false; -} - -} // namespace analytics -} // namespace nearby diff --git a/connections/implementation/analytics/throughput_recorder.h b/connections/implementation/analytics/throughput_recorder.h deleted file mode 100644 index f8dd5d19..00000000 --- a/connections/implementation/analytics/throughput_recorder.h +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2022-2023 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 NEARBY_CONNECTIONS_IMPLEMENTATION_ANALYTICS_THROUGHPUT_RECORDER_H_ -#define NEARBY_CONNECTIONS_IMPLEMENTATION_ANALYTICS_THROUGHPUT_RECORDER_H_ - -#include -#include -#include - -#include "absl/base/no_destructor.h" -#include "absl/base/thread_annotations.h" -#include "absl/container/flat_hash_map.h" -#include "absl/time/time.h" -#include "connections/implementation/analytics/packet_meta_data.h" -#include "connections/payload_type.h" -#include "internal/platform/mutex.h" - -namespace nearby { -namespace analytics { - -// Container class to manage ThroughputRecorder instances. -// This class is a singleton and provides thread-safe proxy methods to record -// throughput for different payloads. -class ThroughputRecorderContainer { - public: - static ThroughputRecorderContainer& GetInstance(); - - // Records the start of a payload transfer. - void Start(int64_t payload_id, - connections::PayloadDirection payload_direction, - connections::PayloadType payload_type) ABSL_LOCKS_EXCLUDED(mutex_); - - // Records when a frame is sent or received. - void UpdateFrameData(int64_t payload_id, - connections::PayloadDirection payload_direction, - location::nearby::proto::connections::Medium medium, - PacketMetaData& packet_meta_data) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Marks a payload transfer as successful. - void MarkAsSuccess(int64_t payload_id, - connections::PayloadDirection payload_direction) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Stops and removes the throughput recorder for a given payload. - // This calculates and logs the final throughput statistics. - // Returns the throughput in KBps. - int64_t StopTPRecorder(int64_t payload_id, - connections::PayloadDirection payload_direction) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns the number of active recorder instances. - int GetSize() ABSL_LOCKS_EXCLUDED(mutex_); - - // Clear all recorders. Used for testing. - void ClearForTest() ABSL_LOCKS_EXCLUDED(mutex_); - - // Testing proxy methods - int64_t GetTotalByteSizeForTesting( - int64_t payload_id, connections::PayloadDirection payload_direction, - location::nearby::proto::connections::Medium medium) - ABSL_LOCKS_EXCLUDED(mutex_); - int GetThroughputsSizeForTesting( - int64_t payload_id, connections::PayloadDirection payload_direction) - ABSL_LOCKS_EXCLUDED(mutex_); - int64_t GetDurationMillisForTesting( - int64_t payload_id, connections::PayloadDirection payload_direction) - ABSL_LOCKS_EXCLUDED(mutex_); - int64_t GetThroughputKbpsForTesting( - int64_t payload_id, connections::PayloadDirection payload_direction) - ABSL_LOCKS_EXCLUDED(mutex_); - bool DumpForTesting(int64_t payload_id, - connections::PayloadDirection payload_direction, - location::nearby::proto::connections::Medium medium) - ABSL_LOCKS_EXCLUDED(mutex_); - - private: - friend class absl::NoDestructor; - - class ThroughputRecorder { - public: - ThroughputRecorder(int64_t payload_id, - connections::PayloadDirection payload_direction, - connections::PayloadType payload_type); - ~ThroughputRecorder() = default; - - void Start(); - bool Stop() ABSL_LOCKS_EXCLUDED(mutex_); - - class Throughput { - public: - Throughput() = default; - ~Throughput() = default; - Throughput(location::nearby::proto::connections::Medium medium, - absl::Time start_timestamp) - : medium_(medium), start_timestamp_(start_timestamp) {} - - void Add(int frame_size, int64_t file_io_time, int64_t encryption_time, - int64_t socket_io_time); - - void SetLastTimestamp(absl::Time time_stamp) { - last_timestamp_ = time_stamp; - } - - int64_t GetTotalByteSize() const { return total_byte_size_; } - - bool dump(connections::PayloadDirection payload_direction, - connections::PayloadType payload_type); - - private: - const ::location::nearby::proto::connections::Medium medium_; - const absl::Time start_timestamp_; - int64_t total_byte_size_ = 0; - absl::Time last_timestamp_; - int64_t file_io_time_ = 0; - int64_t encryption_time_ = 0; - int64_t socket_io_time_ = 0; - }; - - Throughput& GetThroughput( - location::nearby::proto::connections::Medium medium, - int64_t duration_millis); - int GetThroughputsSize() const; - int64_t GetThroughputKbps() const; - int64_t GetDurationMillis() const; - void UpdateFrameData(location::nearby::proto::connections::Medium medium, - PacketMetaData& packetMetaData); - void MarkAsSuccess(); - connections::PayloadType GetPayloadType() const { return payload_type_; } - - private: - void CalculateDurationTimes(const PacketMetaData& packetMetaData); - - const int64_t payload_id_; - const connections::PayloadDirection payload_direction_; - const connections::PayloadType payload_type_; - absl::Time start_timestamp_; - absl::flat_hash_map - throughputs_; - bool success_ = false; - - int64_t file_io_time_ = 0; - int64_t encryption_time_ = 0; - int64_t socket_io_time_ = 0; - int64_t duration_millis_ = 0; - int64_t throughput_kbps_ = 0; - }; - - ThroughputRecorderContainer() = default; - ThroughputRecorderContainer(const ThroughputRecorderContainer&) = delete; - ThroughputRecorderContainer& operator=(const ThroughputRecorderContainer&) = - delete; - ~ThroughputRecorderContainer() = default; - - Mutex mutex_; - // std::pair for - absl::flat_hash_map, - std::unique_ptr> - throughput_recorders_ ABSL_GUARDED_BY(mutex_); -}; - -} // namespace analytics -} // namespace nearby - -#endif // NEARBY_CONNECTIONS_IMPLEMENTATION_ANALYTICS_THROUGHPUT_RECORDER_H_ diff --git a/connections/implementation/analytics/throughput_recorder_test.cc b/connections/implementation/analytics/throughput_recorder_test.cc deleted file mode 100644 index c28d8c8d..00000000 --- a/connections/implementation/analytics/throughput_recorder_test.cc +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2022-2023 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. - -#include "connections/implementation/analytics/throughput_recorder.h" - -#include - -#include - -#include "gtest/gtest.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "connections/implementation/analytics/packet_meta_data.h" -#include "connections/payload_type.h" -#include "internal/platform/logging.h" -#include "proto/connections_enums.pb.h" - -namespace nearby { -namespace analytics { -namespace { - -constexpr int64_t kPayloadIdA = 123456789; -constexpr int64_t kPayloadIdB = 987654321; -constexpr int kFrameSize = 10 * 64 * 1024; - -class ThroughputRecorderTest : public testing::TestWithParam { - protected: - ThroughputRecorderTest() = default; - ~ThroughputRecorderTest() override { - ThroughputRecorderContainer::GetInstance().ClearForTest(); - } - - ThroughputRecorderContainer& tp_recorder_container_ = - ThroughputRecorderContainer::GetInstance(); -}; - -INSTANTIATE_TEST_SUITE_P(ParametrisedTestThroughputRecorderTest, - ThroughputRecorderTest, testing::Values(true, false)); - -TEST(ThroughputRecorderContainer, InstanceCreate_ContainerSize) { - ThroughputRecorderContainer& TPRecorderContainer = - ThroughputRecorderContainer::GetInstance(); - TPRecorderContainer.Start(kPayloadIdA, - connections::PayloadDirection::OUTGOING_PAYLOAD, - connections::PayloadType::kFile); - TPRecorderContainer.Start(kPayloadIdB, - connections::PayloadDirection::INCOMING_PAYLOAD, - connections::PayloadType::kFile); - EXPECT_EQ(ThroughputRecorderContainer::GetInstance().GetSize(), 2); - ThroughputRecorderContainer::GetInstance().ClearForTest(); - EXPECT_EQ(ThroughputRecorderContainer::GetInstance().GetSize(), 0); -} - -TEST_F(ThroughputRecorderTest, OnFrameSentSaveTransferredSize) { - tp_recorder_container_.Start(kPayloadIdA, - connections::PayloadDirection::OUTGOING_PAYLOAD, - connections::PayloadType::kFile); - - PacketMetaData packet_meta_data; - packet_meta_data.SetPacketSize(kFrameSize); - tp_recorder_container_.UpdateFrameData( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, - location::nearby::proto::connections::BLE, packet_meta_data); - tp_recorder_container_.UpdateFrameData( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, - location::nearby::proto::connections::BLE, packet_meta_data); - tp_recorder_container_.UpdateFrameData( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, - location::nearby::proto::connections::BLE, packet_meta_data); - - EXPECT_EQ(tp_recorder_container_.GetTotalByteSizeForTesting( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, - location::nearby::proto::connections::BLE), - kFrameSize * 3); -} - -TEST_F(ThroughputRecorderTest, OnIgnoreUnkownPaylaodType) { - tp_recorder_container_.Start(kPayloadIdA, - connections::PayloadDirection::OUTGOING_PAYLOAD, - connections::PayloadType::kUnknown); - - PacketMetaData packet_meta_data; - tp_recorder_container_.UpdateFrameData( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, - location::nearby::proto::connections::BLE, packet_meta_data); - EXPECT_EQ(tp_recorder_container_.GetThroughputsSizeForTesting( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD), - 0); - - tp_recorder_container_.Start(kPayloadIdA, - connections::PayloadDirection::INCOMING_PAYLOAD, - connections::PayloadType::kUnknown); - tp_recorder_container_.UpdateFrameData( - kPayloadIdA, connections::PayloadDirection::INCOMING_PAYLOAD, - location::nearby::proto::connections::BLE, packet_meta_data); - EXPECT_EQ(tp_recorder_container_.GetThroughputsSizeForTesting( - kPayloadIdA, connections::PayloadDirection::INCOMING_PAYLOAD), - 0); -} - -TEST_P(ThroughputRecorderTest, OnFrameSentStopAndDump) { - tp_recorder_container_.Start(kPayloadIdA, - connections::PayloadDirection::OUTGOING_PAYLOAD, - connections::PayloadType::kFile); - - PacketMetaData packet_meta_data; - packet_meta_data.SetPacketSize(kFrameSize); - packet_meta_data.StartFileIo(); - absl::SleepFor(absl::Milliseconds(5)); - packet_meta_data.StopFileIo(); - packet_meta_data.StartEncryption(); - absl::SleepFor(absl::Milliseconds(6)); - packet_meta_data.StopEncryption(); - packet_meta_data.StartSocketIo(); - absl::SleepFor(absl::Milliseconds(7)); - packet_meta_data.StopSocketIo(); - tp_recorder_container_.UpdateFrameData( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, - location::nearby::proto::connections::BLE, packet_meta_data); - EXPECT_EQ(tp_recorder_container_.GetDurationMillisForTesting( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD), - packet_meta_data.GetEncryptionTimeInMillis() + - packet_meta_data.GetFileIoTimeInMillis() + - packet_meta_data.GetSocketIoTimeInMillis()); - - packet_meta_data.SetPacketSize(kFrameSize); - packet_meta_data.StartFileIo(); - absl::SleepFor(absl::Milliseconds(15)); - packet_meta_data.StopFileIo(); - packet_meta_data.StartEncryption(); - absl::SleepFor(absl::Milliseconds(16)); - packet_meta_data.StopEncryption(); - packet_meta_data.StartSocketIo(); - absl::SleepFor(absl::Milliseconds(17)); - packet_meta_data.StopSocketIo(); - tp_recorder_container_.UpdateFrameData( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, - location::nearby::proto::connections::BLE, packet_meta_data); - - if (GetParam() == true) { - LOG(INFO) << "MarkAsSuccess"; - tp_recorder_container_.MarkAsSuccess( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD); - } - int throughput_kbps = tp_recorder_container_.StopTPRecorder( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD); - EXPECT_NE(throughput_kbps, 0); - EXPECT_EQ(tp_recorder_container_.GetSize(), 0); -} - -TEST_F(ThroughputRecorderTest, OnFrameSentStopAndDumpForMultiMeadium) { - tp_recorder_container_.Start(kPayloadIdA, - connections::PayloadDirection::OUTGOING_PAYLOAD, - connections::PayloadType::kFile); - - PacketMetaData packet_meta_data1; - packet_meta_data1.SetPacketSize(kFrameSize); - packet_meta_data1.StartFileIo(); - absl::SleepFor(absl::Milliseconds(5)); - packet_meta_data1.StopFileIo(); - packet_meta_data1.StartEncryption(); - absl::SleepFor(absl::Milliseconds(6)); - packet_meta_data1.StopEncryption(); - packet_meta_data1.StartSocketIo(); - absl::SleepFor(absl::Milliseconds(7)); - packet_meta_data1.StopSocketIo(); - tp_recorder_container_.UpdateFrameData( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, - location::nearby::proto::connections::BLE, packet_meta_data1); - - PacketMetaData packet_meta_data2; - packet_meta_data2.SetPacketSize(kFrameSize); - packet_meta_data2.StartFileIo(); - absl::SleepFor(absl::Milliseconds(15)); - packet_meta_data2.StopFileIo(); - packet_meta_data2.StartEncryption(); - absl::SleepFor(absl::Milliseconds(16)); - packet_meta_data2.StopEncryption(); - packet_meta_data2.StartSocketIo(); - absl::SleepFor(absl::Milliseconds(17)); - packet_meta_data2.StopSocketIo(); - tp_recorder_container_.UpdateFrameData( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, - location::nearby::proto::connections::WIFI_LAN, packet_meta_data2); - - tp_recorder_container_.MarkAsSuccess( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD); - int throughput_kbps = tp_recorder_container_.StopTPRecorder( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD); - EXPECT_NE(throughput_kbps, 0); -} - -TEST_F(ThroughputRecorderTest, OnFrameReceivedCheckDurationMillis) { - tp_recorder_container_.Start(kPayloadIdA, - connections::PayloadDirection::INCOMING_PAYLOAD, - connections::PayloadType::kFile); - - PacketMetaData packet_meta_data; - packet_meta_data.SetPacketSize(kFrameSize); - packet_meta_data.StartFileIo(); - absl::SleepFor(absl::Milliseconds(5)); - packet_meta_data.StopFileIo(); - packet_meta_data.StartEncryption(); - absl::SleepFor(absl::Milliseconds(6)); - packet_meta_data.StopEncryption(); - packet_meta_data.StartSocketIo(); - absl::SleepFor(absl::Milliseconds(7)); - packet_meta_data.StopSocketIo(); - tp_recorder_container_.UpdateFrameData( - kPayloadIdA, connections::PayloadDirection::INCOMING_PAYLOAD, - location::nearby::proto::connections::BLE, packet_meta_data); - EXPECT_EQ(tp_recorder_container_.GetDurationMillisForTesting( - kPayloadIdA, connections::PayloadDirection::INCOMING_PAYLOAD), - packet_meta_data.GetEncryptionTimeInMillis() + - packet_meta_data.GetFileIoTimeInMillis() + - packet_meta_data.GetSocketIoTimeInMillis()); -} - -TEST_F(ThroughputRecorderTest, OnTPRecorderNotStarted) { - tp_recorder_container_.Start(kPayloadIdA, - connections::PayloadDirection::OUTGOING_PAYLOAD, - connections::PayloadType::kUnknown); - EXPECT_FALSE(tp_recorder_container_.DumpForTesting( - kPayloadIdA, connections::PayloadDirection::OUTGOING_PAYLOAD, - location::nearby::proto::connections::BLE)); -} - -} // namespace -} // namespace analytics -} // namespace nearby diff --git a/connections/implementation/base_endpoint_channel.cc b/connections/implementation/base_endpoint_channel.cc index ec45785c..16baec65 100644 --- a/connections/implementation/base_endpoint_channel.cc +++ b/connections/implementation/base_endpoint_channel.cc @@ -92,17 +92,10 @@ BaseEndpointChannel::BaseEndpointChannel( try_count_(try_count) {} ExceptionOr BaseEndpointChannel::Read() { - PacketMetaData packet_meta_data; - return Read(packet_meta_data); -} - -ExceptionOr BaseEndpointChannel::Read( - PacketMetaData& packet_meta_data) { ByteArray result; { MutexLock lock(&reader_mutex_); - packet_meta_data.StartSocketIo(); ExceptionOr read_int; if (NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature:: @@ -133,8 +126,6 @@ ExceptionOr BaseEndpointChannel::Read( if (!read_bytes.ok()) { return read_bytes; } - packet_meta_data.StopSocketIo(); - packet_meta_data.SetPacketSize(read_int.result() + sizeof(std::int32_t)); result = std::move(read_bytes.result()); } @@ -144,7 +135,6 @@ ExceptionOr BaseEndpointChannel::Read( if (IsEncryptionEnabledLocked()) { // If encryption is enabled, decode the message. std::string input(std::move(result)); - packet_meta_data.StartEncryption(); std::unique_ptr decrypted_data = crypto_context_->DecodeMessageFromPeer(input); if (decrypted_data) { @@ -175,7 +165,6 @@ ExceptionOr BaseEndpointChannel::Read( << ": Unable to parse data as unencrypted message."; } } - packet_meta_data.StopEncryption(); if (result.Empty()) { LOG(WARNING) << __func__ << ": Unable to parse read result."; return ExceptionOr(message_exception); @@ -191,12 +180,6 @@ ExceptionOr BaseEndpointChannel::Read( } Exception BaseEndpointChannel::Write(absl::string_view data) { - PacketMetaData packet_meta_data; - return Write(data, packet_meta_data); -} - -Exception BaseEndpointChannel::Write(absl::string_view data, - PacketMetaData& packet_meta_data) { { MutexLock pause_lock(&is_paused_mutex_); if (is_paused_) { @@ -217,9 +200,7 @@ Exception BaseEndpointChannel::Write(absl::string_view data, MutexLock crypto_lock(&crypto_mutex_); if (IsEncryptionEnabledLocked()) { // If encryption is enabled, encode the message. - packet_meta_data.StartEncryption(); encrypted = crypto_context_->EncodeMessageToPeer(data); - packet_meta_data.StopEncryption(); if (!encrypted) { LOG(WARNING) << __func__ << ": Failed to encrypt data."; return {Exception::kIo}; @@ -235,7 +216,6 @@ Exception BaseEndpointChannel::Write(absl::string_view data, return {Exception::kIo}; } - packet_meta_data.StartSocketIo(); Exception write_exception; if (NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature:: @@ -262,8 +242,6 @@ Exception BaseEndpointChannel::Write(absl::string_view data, << ": Failed to flush writer: " << flush_exception.value; return flush_exception; } - packet_meta_data.StopSocketIo(); - packet_meta_data.SetPacketSize(data_size + sizeof(std::uint32_t)); } { diff --git a/connections/implementation/base_endpoint_channel.h b/connections/implementation/base_endpoint_channel.h index 3aa770a4..c426c118 100644 --- a/connections/implementation/base_endpoint_channel.h +++ b/connections/implementation/base_endpoint_channel.h @@ -23,7 +23,6 @@ #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "connections/implementation/analytics/analytics_recorder.h" -#include "connections/implementation/analytics/packet_meta_data.h" #include "connections/implementation/endpoint_channel.h" #include "internal/platform/byte_array.h" #include "internal/platform/condition_variable.h" @@ -35,8 +34,6 @@ namespace nearby { namespace connections { -using analytics::PacketMetaData; - class BaseEndpointChannel : public EndpointChannel { public: BaseEndpointChannel(const std::string& service_id, @@ -51,12 +48,10 @@ class BaseEndpointChannel : public EndpointChannel { ~BaseEndpointChannel() override = default; // EndpointChannel: - ExceptionOr Read() override; - ExceptionOr Read(PacketMetaData& packet_meta_data) + ExceptionOr Read() ABSL_LOCKS_EXCLUDED(reader_mutex_, crypto_mutex_, last_read_mutex_) override; - Exception Write(absl::string_view data) override; - Exception Write(absl::string_view data, PacketMetaData& packet_meta_data) + Exception Write(absl::string_view data) ABSL_LOCKS_EXCLUDED(writer_mutex_, crypto_mutex_) override; void Close() ABSL_LOCKS_EXCLUDED(is_paused_mutex_) override; void Close(location::nearby::proto::connections::DisconnectionReason reason) diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 0d79ceac..59418df5 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -1666,8 +1666,7 @@ Status BasePcpHandler::RejectConnection(ClientProxy* client, void BasePcpHandler::OnIncomingFrame( OfflineFrame& frame, const std::string& endpoint_id, ClientProxy* client, - location::nearby::proto::connections::Medium medium, - PacketMetaData& packet_meta_data) { + location::nearby::proto::connections::Medium medium) { CountDownLatch latch(1); RunOnPcpHandlerThread( "incoming-frame", diff --git a/connections/implementation/base_pcp_handler.h b/connections/implementation/base_pcp_handler.h index f14665f6..4dda6590 100644 --- a/connections/implementation/base_pcp_handler.h +++ b/connections/implementation/base_pcp_handler.h @@ -31,7 +31,6 @@ #include "connections/advertising_options.h" #include "connections/connection_options.h" #include "connections/discovery_options.h" -#include "connections/implementation/analytics/packet_meta_data.h" #include "connections/implementation/bwu_manager.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/encryption_runner.h" @@ -158,10 +157,10 @@ class BasePcpHandler : public PcpHandler, const std::string& endpoint_id) override; // @EndpointManagerReaderThread - void OnIncomingFrame(location::nearby::connections::OfflineFrame& frame, - const std::string& endpoint_id, ClientProxy* client, - location::nearby::proto::connections::Medium medium, - analytics::PacketMetaData& packet_meta_data) override; + void OnIncomingFrame( + location::nearby::connections::OfflineFrame& frame, + const std::string& endpoint_id, ClientProxy* client, + location::nearby::proto::connections::Medium medium) override; // Called when an endpoint disconnects while we're waiting for both sides to // approve/reject the connection. diff --git a/connections/implementation/base_pcp_handler_test.cc b/connections/implementation/base_pcp_handler_test.cc index e1fad699..4313a5e3 100644 --- a/connections/implementation/base_pcp_handler_test.cc +++ b/connections/implementation/base_pcp_handler_test.cc @@ -32,7 +32,6 @@ #include "connections/advertising_options.h" #include "connections/connection_options.h" #include "connections/discovery_options.h" -#include "connections/implementation/analytics/packet_meta_data.h" #include "connections/implementation/base_endpoint_channel.h" #include "connections/implementation/bwu_manager.h" #include "connections/implementation/client_proxy.h" @@ -1591,7 +1590,6 @@ TEST_P(BasePcpHandlerTest, OnIncomingFrameChangesState) { EndpointManager em(&ecm); BwuManager bwu(m, em, ecm, {}, {}); MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); - analytics::PacketMetaData packet_meta_data; StartDiscovery(client_.get(), &pcp_handler); auto mediums = pcp_handler.GetDiscoveryMediums(client_.get()); auto connect_medium = mediums[mediums.size() - 1]; @@ -1615,7 +1613,7 @@ TEST_P(BasePcpHandlerTest, OnIncomingFrameChangesState) { Status::kSuccess, os_info, /*multiplex_socket_bitmask=*/0)); EXPECT_CALL(mock_connection_listener_.bandwidth_changed_cb, Call).Times(1); pcp_handler.OnIncomingFrame(frame.result(), endpoint_id, client_.get(), - connect_medium, packet_meta_data); + connect_medium); LOG(INFO) << "Closing connection: id=" << endpoint_id; channel_b->Close(); bwu.Shutdown(); diff --git a/connections/implementation/bwu_manager.cc b/connections/implementation/bwu_manager.cc index 53084af8..d43a2329 100644 --- a/connections/implementation/bwu_manager.cc +++ b/connections/implementation/bwu_manager.cc @@ -400,8 +400,7 @@ void BwuManager::InitiateBwuForEndpoint(ClientProxy* client, void BwuManager::OnIncomingFrame(OfflineFrame& frame, const std::string& endpoint_id, - ClientProxy* client, Medium medium, - PacketMetaData& packet_meta_data) { + ClientProxy* client, Medium medium) { V1Frame::FrameType frame_type = parser::GetFrameType(frame); if (frame_type != V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION) return; @@ -548,7 +547,7 @@ BwuHandler* BwuManager::GetHandlerForMedium(Medium medium) const { } void BwuManager::OnBwuNegotiationFrame( - ClientProxy* client, const BandwidthUpgradeNegotiationFrame frame, + ClientProxy* client, const BandwidthUpgradeNegotiationFrame& frame, const std::string& endpoint_id) { LOG(INFO) << "OnBwuNegotiationFrame: processing incoming " << BandwidthUpgradeNegotiationFrame::EventType_Name( diff --git a/connections/implementation/bwu_manager.h b/connections/implementation/bwu_manager.h index 2c5c766c..d2f53913 100644 --- a/connections/implementation/bwu_manager.h +++ b/connections/implementation/bwu_manager.h @@ -92,8 +92,7 @@ class BwuManager : public EndpointManager::FrameProcessor { // @EndpointManagerReaderThread void OnIncomingFrame(location::nearby::connections::OfflineFrame& frame, const std::string& endpoint_id, ClientProxy* client, - Medium medium, - PacketMetaData& packet_meta_data) override; + Medium medium) override; // Cleans up in-progress upgrades after endpoint disconnection. // @EndpointManagerReaderThread @@ -144,7 +143,7 @@ class BwuManager : public EndpointManager::FrameProcessor { // upgrade. void OnBwuNegotiationFrame( ClientProxy* client, - const location::nearby::connections::BandwidthUpgradeNegotiationFrame + const location::nearby::connections::BandwidthUpgradeNegotiationFrame& frame, const string& endpoint_id); diff --git a/connections/implementation/bwu_manager_test.cc b/connections/implementation/bwu_manager_test.cc index 4862c2e1..6a6495c5 100644 --- a/connections/implementation/bwu_manager_test.cc +++ b/connections/implementation/bwu_manager_test.cc @@ -188,12 +188,12 @@ class BwuManagerTest : public ::testing::Test { parser::FromBytes(parser::ForBwuLastWrite()); bwu_manager_->OnIncomingFrame(last_write_frame.result(), std::string(endpoint_id), &client_, - initial_medium, packet_meta_data_); + initial_medium); ExceptionOr safe_to_close_frame = parser::FromBytes(parser::ForBwuSafeToClose()); bwu_manager_->OnIncomingFrame(safe_to_close_frame.result(), std::string(endpoint_id), &client_, - initial_medium, packet_meta_data_); + initial_medium); return upgraded_channel; } @@ -209,7 +209,6 @@ class BwuManagerTest : public ::testing::Test { FakeBwuHandler* fake_wifi_direct_bwu_handler_ = nullptr; FakeBwuHandler* fake_wifi_hotspot_bwu_handler_ = nullptr; std::unique_ptr bwu_manager_; - PacketMetaData packet_meta_data_; }; TEST(BwuManagerBaseTest, AllowToUpgradeMedium) { @@ -370,12 +369,12 @@ TEST_P(BwuManagerTestParam, InitiateBwu_Success) { parser::FromBytes(parser::ForBwuLastWrite()); bwu_manager_->OnIncomingFrame(last_write_frame.result(), std::string(kEndpointId1), &client_, - Medium::BLUETOOTH, packet_meta_data_); + Medium::BLUETOOTH); ExceptionOr safe_to_close_frame = parser::FromBytes(parser::ForBwuSafeToClose()); bwu_manager_->OnIncomingFrame(safe_to_close_frame.result(), std::string(kEndpointId1), &client_, - Medium::BLUETOOTH, packet_meta_data_); + Medium::BLUETOOTH); // Confirm that upgrade channel is resumed after initial channel is shut down. // Note: If we didn't grab the shared initial channel pointer above, this @@ -871,7 +870,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnUpgradeFailure_FlagEnabled) { parser::FromBytes(parser::ForBwuFailure(info)); bwu_manager_->OnIncomingFrame(upgrade_failure.result(), std::string(kEndpointId3), &client_, - Medium::WEB_RTC, packet_meta_data_); + Medium::WEB_RTC); // With the flag enabled, we can safely revert WebRTC just for service B // because service B has no active WebRTC endpoints. @@ -908,7 +907,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnUpgradeFailure_FlagDisabled) { parser::FromBytes(parser::ForBwuFailure(info)); bwu_manager_->OnIncomingFrame(upgrade_failure.result(), std::string(kEndpointId3), &client_, - Medium::WEB_RTC, packet_meta_data_); + Medium::WEB_RTC); // With the flag disabled, we don't revert if there are still connected // endpoints for _any_ service. We don't have service-level bookkeeping; we @@ -938,7 +937,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_WifiDirect) { upgrade_path_info = sub_frame->mutable_upgrade_path_info(); upgrade_path_info->set_supports_client_introduction_ack(false); bwu_manager_->OnIncomingFrame(frame, std::string(kEndpointId1), &client_, - Medium::BLUETOOTH, packet_meta_data_); + Medium::BLUETOOTH); CountDownLatch latch(1); bwu_manager_->OnEndpointDisconnect(&client_, (std::string)kServiceIdA, std::string(kEndpointId1), latch, @@ -973,7 +972,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_Hotspot) { upgrade_path_info->set_supports_client_introduction_ack(false); upgrade_path_info->set_supports_disabling_encryption(true); bwu_manager_->OnIncomingFrame(frame, std::string(kEndpointId1), &client_, - Medium::BLUETOOTH, packet_meta_data_); + Medium::BLUETOOTH); CountDownLatch latch(1); bwu_manager_->OnEndpointDisconnect(&client_, (std::string)kServiceIdA, std::string(kEndpointId1), latch, @@ -1001,7 +1000,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_Wlan) { upgrade_path_info->set_supports_client_introduction_ack(false); bwu_manager_->OnIncomingFrame(frame, std::string(kEndpointId1), &client_, - Medium::BLUETOOTH, packet_meta_data_); + Medium::BLUETOOTH); CountDownLatch latch(1); bwu_manager_->OnEndpointDisconnect(&client_, (std::string)kServiceIdA, std::string(kEndpointId1), latch, @@ -1040,7 +1039,7 @@ TEST_F(BwuManagerTest, BlockBwuFrameBeforeAccept) { upgrade_path_info2->set_supports_client_introduction_ack(false); upgrade_path_info2->set_supports_disabling_encryption(true); bwu_manager_->OnIncomingFrame(frame2, std::string(kEndpointId2), &client_, - Medium::BLUETOOTH, packet_meta_data_); + Medium::BLUETOOTH); CountDownLatch latch2(1); // The BWU frame should be drop, so the inProgressUpgrades should be empty. ASSERT_EQ(bwu_manager_->IsUpgradeOngoing(std::string(kEndpointId2)), false); @@ -1084,7 +1083,7 @@ TEST_F(BwuManagerTest, BlockBwuFrameFromAdvertiser) { EXPECT_TRUE(client_.IsConnectedToEndpoint(std::string(kEndpointId2))); bwu_manager_->OnIncomingFrame(frame, std::string(kEndpointId2), &client_, - Medium::BLUETOOTH, packet_meta_data_); + Medium::BLUETOOTH); CountDownLatch latch2(1); // The BWU frame should be drop, so the IsUpgradeOngoing should be empty. ASSERT_EQ(bwu_manager_->IsUpgradeOngoing(std::string(kEndpointId2)), false); diff --git a/connections/implementation/connections_authentication_transport_test.cc b/connections/implementation/connections_authentication_transport_test.cc index 667fbab6..333a4da2 100644 --- a/connections/implementation/connections_authentication_transport_test.cc +++ b/connections/implementation/connections_authentication_transport_test.cc @@ -14,7 +14,6 @@ #include "connections/implementation/connections_authentication_transport.h" -#include #include #include #include @@ -23,12 +22,9 @@ #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "connections/implementation/analytics/analytics_recorder.h" -#include "connections/implementation/endpoint_channel.h" +#include "connections/implementation/mock_endpoint_channel.h" #include "internal/platform/byte_array.h" #include "internal/platform/exception.h" -#include "proto/connections_enums.pb.h" namespace nearby { namespace connections { @@ -36,86 +32,39 @@ namespace { using ::testing::_; -class MockEndpointChannel : public EndpointChannel { - public: - MOCK_METHOD(ExceptionOr, Read, (), (override)); - MOCK_METHOD(ExceptionOr, Read, (PacketMetaData&), (override)); - MOCK_METHOD(Exception, Write, (absl::string_view data), (override)); - MOCK_METHOD(Exception, Write, (absl::string_view data, PacketMetaData&), - (override)); - MOCK_METHOD(void, Close, (), (override)); - MOCK_METHOD( - void, Close, - (location::nearby::proto::connections::DisconnectionReason reason), - (override)); - MOCK_METHOD(void, Close, - (location::nearby::proto::connections::DisconnectionReason reason, - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection::SafeDisconnectionResult result), - (override)); - MOCK_METHOD(bool, IsClosed, (), (const, override)); - MOCK_METHOD(std::string, GetType, (), (const, override)); - MOCK_METHOD(std::string, GetServiceId, (), (const, override)); - MOCK_METHOD(std::string, GetName, (), (const, override)); - MOCK_METHOD(location::nearby::proto::connections::Medium, GetMedium, (), - (const, override)); - MOCK_METHOD(location::nearby::proto::connections::ConnectionTechnology, - GetTechnology, (), (const, override)); - MOCK_METHOD(location::nearby::proto::connections::ConnectionBand, GetBand, (), - (const, override)); - MOCK_METHOD(int, GetFrequency, (), (const, override)); - MOCK_METHOD(int, GetTryCount, (), (const, override)); - MOCK_METHOD(int, GetMaxTransmitPacketSize, (), (const, override)); - MOCK_METHOD(void, EnableEncryption, (std::shared_ptr), - (override)); - MOCK_METHOD(void, DisableEncryption, (), (override)); - MOCK_METHOD(bool, IsEncrypted, (), (override)); - MOCK_METHOD(ExceptionOr, TryDecrypt, (const ByteArray& data), - (override)); - MOCK_METHOD(bool, IsPaused, (), (const, override)); - MOCK_METHOD(void, Pause, (), (override)); - MOCK_METHOD(void, Resume, (), (override)); - MOCK_METHOD(absl::Time, GetLastReadTimestamp, (), (const, override)); - MOCK_METHOD(absl::Time, GetLastWriteTimestamp, (), (const, override)); - MOCK_METHOD(uint32_t, GetNextKeepAliveSeqNo, (), (const, override)); - MOCK_METHOD(void, SetAnalyticsRecorder, - (analytics::AnalyticsRecorder*, const std::string&), (override)); - - std::vector messages_; -}; - TEST(ConnectionsAuthenticationTransportTest, TestWriteMessage) { + std::vector messages; auto channel = std::make_shared(); - auto* channel_ptr = channel.get(); ConnectionsAuthenticationTransport transport(channel); EXPECT_CALL(*channel, Write(_)) - .WillOnce([channel_ptr](absl::string_view data) { - channel_ptr->messages_.push_back(std::string(data)); + .WillOnce([&messages](absl::string_view data) { + messages.push_back(std::string(data)); return Exception{ .value = Exception::Value::kSuccess, }; }); transport.WriteMessage("hello world"); - EXPECT_THAT(channel_ptr->messages_, testing::ElementsAre("hello world")); + EXPECT_THAT(messages, testing::ElementsAre("hello world")); } TEST(ConnectionsAuthenticationTransportTest, TestReadMessage) { + std::vector messages; auto channel = std::make_shared(); - auto* channel_ptr = channel.get(); ConnectionsAuthenticationTransport transport(channel); - channel_ptr->messages_.push_back("hello world"); - EXPECT_CALL(*channel, Read()).WillOnce([channel_ptr]() { - std::string ret = channel_ptr->messages_[0]; - channel_ptr->messages_.erase(channel_ptr->messages_.begin()); + messages.push_back("hello world"); + EXPECT_CALL(*channel, Read()).WillOnce([&messages]() { + std::string ret = messages[0]; + messages.erase(messages.begin()); return ExceptionOr(ByteArray(ret)); }); EXPECT_EQ(transport.ReadMessage(), "hello world"); } TEST(ConnectionsAuthenticationTransportTest, TestReadMessageFail) { + std::vector messages; auto channel = std::make_shared(); ConnectionsAuthenticationTransport transport(channel); - channel->messages_.push_back("hello world"); + messages.push_back("hello world"); EXPECT_CALL(*channel, Read()).WillOnce([]() { return ExceptionOr(Exception::Value::kIo); }); diff --git a/connections/implementation/encryption_runner_test.cc b/connections/implementation/encryption_runner_test.cc index f3cd2bd0..ee9bbc1d 100644 --- a/connections/implementation/encryption_runner_test.cc +++ b/connections/implementation/encryption_runner_test.cc @@ -52,18 +52,11 @@ class FakeEndpointChannel : public EndpointChannel { read_timestamp_ = SystemClock::ElapsedRealtime(); return in_ ? in_->Read(kChunkSize) : ExceptionOr{Exception::kIo}; } - ExceptionOr Read(PacketMetaData& packet_meta_data) override { - read_timestamp_ = SystemClock::ElapsedRealtime(); - return in_ ? in_->Read(kChunkSize) : ExceptionOr{Exception::kIo}; - } + Exception Write(absl::string_view data) override { write_timestamp_ = SystemClock::ElapsedRealtime(); return out_ ? out_->Write(data) : Exception{Exception::kIo}; } - Exception Write(absl::string_view data, - PacketMetaData& packet_meta_data) override { - return Write(data); - } void Close() override { if (in_) in_->Close(); if (out_) out_->Close(); diff --git a/connections/implementation/endpoint_channel.h b/connections/implementation/endpoint_channel.h index abd20ef3..fc0d87cf 100644 --- a/connections/implementation/endpoint_channel.h +++ b/connections/implementation/endpoint_channel.h @@ -23,15 +23,12 @@ #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "connections/implementation/analytics/analytics_recorder.h" -#include "connections/implementation/analytics/packet_meta_data.h" #include "internal/platform/byte_array.h" #include "internal/platform/exception.h" namespace nearby { namespace connections { -using analytics::PacketMetaData; - class EndpointChannel { public: virtual ~EndpointChannel() = default; @@ -41,15 +38,9 @@ class EndpointChannel { virtual ExceptionOr Read() = 0; // throws Exception::IO, Exception::INTERRUPTED - virtual ExceptionOr Read(PacketMetaData& packet_meta_data) = 0; - virtual Exception Write(absl::string_view data) = 0; // throws Exception::IO - virtual Exception Write( - absl::string_view data, - PacketMetaData& packet_meta_data) = 0; // throws Exception::IO // Closes this EndpointChannel, without tracking the closure in analytics. - virtual void Close() = 0; // Closes this EndpointChannel and records the closure with the given reason. diff --git a/connections/implementation/endpoint_manager.cc b/connections/implementation/endpoint_manager.cc index c0e94b8b..5070d390 100644 --- a/connections/implementation/endpoint_manager.cc +++ b/connections/implementation/endpoint_manager.cc @@ -24,8 +24,6 @@ #include "absl/functional/any_invocable.h" #include "absl/time/time.h" #include "connections/connection_options.h" -#include "connections/implementation/analytics/packet_meta_data.h" -#include "connections/implementation/analytics/throughput_recorder.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/endpoint_channel_manager.h" @@ -34,7 +32,6 @@ #include "connections/implementation/service_id_constants.h" #include "connections/listeners.h" #include "connections/medium_selector.h" -#include "connections/payload_type.h" #include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" @@ -58,7 +55,6 @@ using ::location::nearby::connections::OfflineFrame; using ::location::nearby::connections::PayloadTransferFrame; using ::location::nearby::connections::V1Frame; using ::location::nearby::proto::connections::DisconnectionReason; -using ::nearby::analytics::PacketMetaData; // We set this to 11s to provide sufficient time for an in-progress WebRTC // bandwidth upgrade to resolve. This is chosen to be slightly longer than the @@ -235,8 +231,7 @@ ExceptionOr EndpointManager::HandleData( // a replacement for this endpoint since we last checked with the // EndpointChannelManager. while (true) { - PacketMetaData packet_meta_data; - ExceptionOr bytes = endpoint_channel->Read(packet_meta_data); + ExceptionOr bytes = endpoint_channel->Read(); if (!bytes.ok()) { LOG(INFO) << "Stop reading on read-time exception: " << bytes.exception(); // Treat kNoData as kIo. @@ -317,8 +312,7 @@ ExceptionOr EndpointManager::HandleData( } frame_processor->OnIncomingFrame(frame, endpoint_id, client, - endpoint_channel->GetMedium(), - packet_meta_data); + endpoint_channel->GetMedium()); } } @@ -657,8 +651,7 @@ int EndpointManager::GetMaxTransmitPacketSize(const std::string& endpoint_id) { std::vector EndpointManager::SendPayloadChunk( const PayloadTransferFrame::PayloadHeader& payload_header, const PayloadTransferFrame::PayloadChunk& payload_chunk, - const std::vector& endpoint_ids, - PacketMetaData& packet_meta_data) { + const std::vector& endpoint_ids) { std::string bytes = parser::ForDataPayloadTransfer(payload_header, payload_chunk); @@ -666,8 +659,7 @@ std::vector EndpointManager::SendPayloadChunk( endpoint_ids, bytes, payload_header.id(), /*offset=*/payload_chunk.offset(), /*packet_type=*/ - PayloadTransferFrame::PacketType_Name(PayloadTransferFrame::DATA), - packet_meta_data); + PayloadTransferFrame::PacketType_Name(PayloadTransferFrame::DATA)); } // Designed to run asynchronously. It is called from IO thread pools, and @@ -735,14 +727,12 @@ std::vector EndpointManager::SendControlMessage( const PayloadTransferFrame::ControlMessage& control, const std::vector& endpoint_ids) { std::string bytes = parser::ForControlPayloadTransfer(header, control); - PacketMetaData packet_meta_data; return SendTransferFrameBytes( endpoint_ids, bytes, header.id(), /*offset=*/control.offset(), /*packet_type=*/ - PayloadTransferFrame::PacketType_Name(PayloadTransferFrame::CONTROL), - packet_meta_data); + PayloadTransferFrame::PacketType_Name(PayloadTransferFrame::CONTROL)); } // @EndpointManagerThread @@ -912,20 +902,18 @@ CountDownLatch EndpointManager::NotifyFrameProcessorsOnEndpointDisconnect( std::vector EndpointManager::SendPayloadAck( std::int64_t payload_id, const std::vector& endpoint_ids) { std::string bytes = parser::ForPayloadAckPayloadTransfer(payload_id); - PacketMetaData packet_meta_data; return SendTransferFrameBytes( endpoint_ids, bytes, payload_id, /* offset= */ -1, /*packet_type=*/ - PayloadTransferFrame::PacketType_Name(PayloadTransferFrame::PAYLOAD_ACK), - packet_meta_data); + PayloadTransferFrame::PacketType_Name(PayloadTransferFrame::PAYLOAD_ACK)); } std::vector EndpointManager::SendTransferFrameBytes( const std::vector& endpoint_ids, const std::string& bytes, std::int64_t payload_id, std::int64_t offset, - const std::string& packet_type, PacketMetaData& packet_meta_data) { + const std::string& packet_type) { std::vector failed_endpoint_ids; for (const std::string& endpoint_id : endpoint_ids) { std::shared_ptr channel = @@ -944,15 +932,12 @@ std::vector EndpointManager::SendTransferFrameBytes( continue; } - Exception write_exception = channel->Write(bytes, packet_meta_data); + Exception write_exception = channel->Write(bytes); if (!write_exception.Ok()) { failed_endpoint_ids.push_back(endpoint_id); LOG(INFO) << "Failed to send packet; endpoint_id=" << endpoint_id; continue; } - analytics::ThroughputRecorderContainer::GetInstance().UpdateFrameData( - payload_id, PayloadDirection::OUTGOING_PAYLOAD, channel->GetMedium(), - packet_meta_data); } return failed_endpoint_ids; diff --git a/connections/implementation/endpoint_manager.h b/connections/implementation/endpoint_manager.h index 4b47f9c5..2250a958 100644 --- a/connections/implementation/endpoint_manager.h +++ b/connections/implementation/endpoint_manager.h @@ -26,7 +26,6 @@ #include "absl/functional/any_invocable.h" #include "absl/time/time.h" #include "connections/connection_options.h" -#include "connections/implementation/analytics/packet_meta_data.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/endpoint_channel_manager.h" @@ -80,8 +79,7 @@ class EndpointManager { virtual void OnIncomingFrame( location::nearby::connections::OfflineFrame& offline_frame, const std::string& from_endpoint_id, ClientProxy* to_client, - location::nearby::proto::connections::Medium current_medium, - analytics::PacketMetaData& packet_meta_data) = 0; + location::nearby::proto::connections::Medium current_medium) = 0; // Implementations must call barrier.CountDown() once // they're done. This parallelizes the disconnection event across all frame @@ -134,8 +132,7 @@ class EndpointManager { payload_header, const location::nearby::connections::PayloadTransferFrame::PayloadChunk& payload_chunk, - const std::vector& endpoint_ids, - analytics::PacketMetaData& packet_meta_data); + const std::vector& endpoint_ids); std::vector SendControlMessage( const location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, @@ -285,8 +282,7 @@ class EndpointManager { std::vector SendTransferFrameBytes( const std::vector& endpoint_ids, const std::string& payload_transfer_frame_bytes, std::int64_t payload_id, - std::int64_t offset, const std::string& packet_type, - analytics::PacketMetaData& packet_meta_data); + std::int64_t offset, const std::string& packet_type); // Executes all jobs sequentially, on a serial_executor_. void RunOnEndpointManagerThread(const std::string& name, Runnable runnable); diff --git a/connections/implementation/endpoint_manager_test.cc b/connections/implementation/endpoint_manager_test.cc index aecd71ab..70a85949 100644 --- a/connections/implementation/endpoint_manager_test.cc +++ b/connections/implementation/endpoint_manager_test.cc @@ -29,11 +29,10 @@ #include "absl/time/clock.h" #include "absl/time/time.h" #include "connections/connection_options.h" -#include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/client_proxy.h" -#include "connections/implementation/endpoint_channel.h" #include "connections/implementation/endpoint_channel_manager.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "connections/implementation/mock_endpoint_channel.h" #include "connections/implementation/offline_frames.h" #include "connections/listeners.h" #include "connections/status.h" @@ -63,68 +62,12 @@ using ::testing::MockFunction; using ::testing::Return; using ::testing::StrictMock; -class MockEndpointChannel : public EndpointChannel { - public: - MOCK_METHOD(ExceptionOr, Read, (), (override)); - MOCK_METHOD(ExceptionOr, Read, (PacketMetaData & packet_meta_data), - (override)); - MOCK_METHOD(Exception, Write, (absl::string_view data), (override)); - MOCK_METHOD(Exception, Write, - (absl::string_view data, PacketMetaData& packet_meta_data), - (override)); - MOCK_METHOD(void, Close, (), (override)); - MOCK_METHOD(void, Close, (DisconnectionReason reason), (override)); - MOCK_METHOD(void, Close, - (DisconnectionReason reason, - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection::SafeDisconnectionResult result), - (override)); - MOCK_METHOD(location::nearby::proto::connections::ConnectionTechnology, - GetTechnology, (), (const, override)); - MOCK_METHOD(location::nearby::proto::connections::ConnectionBand, GetBand, (), - (const, override)); - MOCK_METHOD(int, GetFrequency, (), (const, override)); - MOCK_METHOD(int, GetTryCount, (), (const, override)); - MOCK_METHOD(std::string, GetType, (), (const, override)); - MOCK_METHOD(std::string, GetServiceId, (), (const, override)); - MOCK_METHOD(std::string, GetName, (), (const, override)); - MOCK_METHOD(Medium, GetMedium, (), (const, override)); - MOCK_METHOD(int, GetMaxTransmitPacketSize, (), (const, override)); - MOCK_METHOD(void, EnableEncryption, - (std::shared_ptr context), (override)); - MOCK_METHOD(void, DisableEncryption, (), (override)); - MOCK_METHOD(bool, IsPaused, (), (const, override)); - MOCK_METHOD(bool, IsEncrypted, (), (override)); - MOCK_METHOD(ExceptionOr, TryDecrypt, (const ByteArray& data), - (override)); - MOCK_METHOD(void, Pause, (), (override)); - MOCK_METHOD(void, Resume, (), (override)); - MOCK_METHOD(absl::Time, GetLastReadTimestamp, (), (const, override)); - MOCK_METHOD(absl::Time, GetLastWriteTimestamp, (), (const, override)); - MOCK_METHOD(uint32_t, GetNextKeepAliveSeqNo, (), (const, override)); - MOCK_METHOD(void, SetAnalyticsRecorder, - (analytics::AnalyticsRecorder*, const std::string&), (override)); - - bool IsClosed() const override { - absl::MutexLock lock(mutex_); - return closed_; - } - void DoClose() { - absl::MutexLock lock(mutex_); - closed_ = true; - } - - private: - mutable absl::Mutex mutex_; - bool closed_ = false; -}; - class MockFrameProcessor : public EndpointManager::FrameProcessor { public: MOCK_METHOD(void, OnIncomingFrame, (OfflineFrame & offline_frame, const std::string& from_endpoint_id, ClientProxy* to_client, - Medium current_medium, PacketMetaData& packet_meta_data), + Medium current_medium), (override)); MOCK_METHOD(void, OnEndpointDisconnect, @@ -281,7 +224,7 @@ TEST_F(EndpointManagerTest, RegisterFrameProcessorWorks) { parser::ForConnectionRequestConnections({}, connection_info); EXPECT_CALL(*connect_request, OnIncomingFrame); EXPECT_CALL(*connect_request, OnEndpointDisconnect); - EXPECT_CALL(*endpoint_channel, Read(_)) + EXPECT_CALL(*endpoint_channel, Read()) .WillOnce(Return(ExceptionOr(ByteArray(read_data)))) .WillRepeatedly(Return(ExceptionOr(Exception::kIo))); EXPECT_CALL(*endpoint_channel, Write(_)) @@ -319,6 +262,8 @@ TEST_F(EndpointManagerTest, UnregisterFrameProcessorWorks) { TEST_F(EndpointManagerTest, SendControlMessageAndPayloadAckWorks) { auto endpoint_channel = std::make_unique(); + absl::Mutex close_mutex; + bool closed = false; PayloadTransferFrame::PayloadHeader header; PayloadTransferFrame::ControlMessage control; header.set_id(12345); @@ -327,22 +272,24 @@ TEST_F(EndpointManagerTest, SendControlMessageAndPayloadAckWorks) { control.set_offset(150); control.set_event(PayloadTransferFrame::ControlMessage::PAYLOAD_CANCELED); - ON_CALL(*endpoint_channel, Read(_)) - .WillByDefault([channel = endpoint_channel.get()]() { - if (channel->IsClosed()) return ExceptionOr(Exception::kIo); + ON_CALL(*endpoint_channel, Read()) + .WillByDefault([&, channel = endpoint_channel.get()]() { + absl::MutexLock lock(close_mutex); + if (closed) return ExceptionOr(Exception::kIo); LOG(INFO) << "Simulate read delay: wait"; absl::SleepFor(absl::Milliseconds(100)); LOG(INFO) << "Simulate read delay: done"; - if (channel->IsClosed()) return ExceptionOr(Exception::kIo); + if (closed) return ExceptionOr(Exception::kIo); return ExceptionOr(ByteArray{}); }); ON_CALL(*endpoint_channel, Close(_)) .WillByDefault( - [channel = endpoint_channel.get()](DisconnectionReason reason) { - channel->DoClose(); + [&, channel = endpoint_channel.get()](DisconnectionReason reason) { + absl::MutexLock lock(close_mutex); + closed = true; LOG(INFO) << "Channel closed"; }); - EXPECT_CALL(*endpoint_channel, Write(_, _)) + EXPECT_CALL(*endpoint_channel, Write(_)) .WillRepeatedly(Return(Exception{Exception::kSuccess})); RegisterEndpoint(std::move(endpoint_channel), false); @@ -359,7 +306,7 @@ TEST_F(EndpointManagerTest, SendControlMessageAndPayloadAckWorks) { TEST_F(EndpointManagerTest, SingleReadOnReadError) { auto endpoint_channel = std::make_unique(); - EXPECT_CALL(*endpoint_channel, Read(_)) + EXPECT_CALL(*endpoint_channel, Read()) .WillOnce( Return(ExceptionOr(Exception::kInvalidProtocolBuffer))); EXPECT_CALL(*endpoint_channel, Write(_)) @@ -377,7 +324,7 @@ TEST_F(EndpointManagerTest, ReadInvalidUnencryptedPayloadIgnoresFrame) { CountDownLatch latch(1); const ByteArray payload("not a valid frame"); auto endpoint_channel = std::make_unique(); - EXPECT_CALL(*endpoint_channel, Read(_)) + EXPECT_CALL(*endpoint_channel, Read()) .WillOnce(Return(ExceptionOr(payload))) .WillRepeatedly(Return(ExceptionOr(Exception::kIo))); EXPECT_CALL(*endpoint_channel, TryDecrypt(Eq(payload))) @@ -401,7 +348,7 @@ class EndpointManagerFuzzTest // too. // 4. Invalid frame is ignored. No bad side effects. auto endpoint_channel = std::make_unique(); - EXPECT_CALL(*endpoint_channel, Read(_)) + EXPECT_CALL(*endpoint_channel, Read()) .WillOnce(Return(ExceptionOr(payload))) .WillRepeatedly(Return(ExceptionOr(Exception::kIo))); EXPECT_CALL(*endpoint_channel, TryDecrypt(Eq(payload))) @@ -417,7 +364,7 @@ class EndpointManagerFuzzTest // 2. EndpointManager receives an invalid encrypted frame. // 3. No calls to TryDecrypt. auto endpoint_channel = std::make_unique(); - EXPECT_CALL(*endpoint_channel, Read(_)) + EXPECT_CALL(*endpoint_channel, Read()) .WillOnce(Return(ExceptionOr(payload))) .WillRepeatedly(Return(ExceptionOr(Exception::kIo))); EXPECT_CALL(*endpoint_channel, IsEncrypted()).WillRepeatedly(Return(true)); @@ -468,7 +415,7 @@ TEST_F(EndpointManagerTest, TryDecrypt) { parser::ForConnectionRequestConnections({}, connection_info); EXPECT_CALL(*connect_request, OnIncomingFrame); EXPECT_CALL(*connect_request, OnEndpointDisconnect); - EXPECT_CALL(*endpoint_channel, Read(_)) + EXPECT_CALL(*endpoint_channel, Read()) .WillOnce(Return(ExceptionOr(payload))) .WillRepeatedly(Return(ExceptionOr(Exception::kIo))); EXPECT_CALL(*endpoint_channel, TryDecrypt(Eq(payload))) diff --git a/connections/implementation/fake_endpoint_channel.h b/connections/implementation/fake_endpoint_channel.h index 9221147d..cb03659f 100644 --- a/connections/implementation/fake_endpoint_channel.h +++ b/connections/implementation/fake_endpoint_channel.h @@ -46,19 +46,10 @@ class FakeEndpointChannel : public EndpointChannel { read_timestamp_ = SystemClock::ElapsedRealtime(); return read_output_; } - ExceptionOr Read(PacketMetaData& packet_meta_data) override { - read_timestamp_ = SystemClock::ElapsedRealtime(); - return read_output_; - } Exception Write(absl::string_view data) override { write_timestamp_ = SystemClock::ElapsedRealtime(); return write_output_; } - Exception Write(absl::string_view data, - PacketMetaData& packet_meta_data) override { - write_timestamp_ = SystemClock::ElapsedRealtime(); - return write_output_; - } void Close() override { is_closed_ = true; } void Close(location::nearby::proto::connections::DisconnectionReason reason) override { diff --git a/connections/implementation/mock_endpoint_channel.h b/connections/implementation/mock_endpoint_channel.h new file mode 100644 index 00000000..87f51995 --- /dev/null +++ b/connections/implementation/mock_endpoint_channel.h @@ -0,0 +1,77 @@ +// Copyright 2026 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_CONNECTIONS_IMPLEMENTATION_MOCK_ENDPOINT_CHANNEL_H_ +#define THIRD_PARTY_NEARBY_CONNECTIONS_IMPLEMENTATION_MOCK_ENDPOINT_CHANNEL_H_ + +#include +#include +#include +#include "gmock/gmock.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "connections/implementation/analytics/analytics_recorder.h" +#include "connections/implementation/endpoint_channel.h" +#include "internal/platform/byte_array.h" +#include "internal/platform/exception.h" + +namespace nearby::connections { + +class MockEndpointChannel : public EndpointChannel { + public: + MOCK_METHOD(ExceptionOr, Read, (), (override)); + MOCK_METHOD(Exception, Write, (absl::string_view data), + (override)); + MOCK_METHOD(void, Close, (), (override)); + MOCK_METHOD( + void, Close, + (location::nearby::proto::connections::DisconnectionReason reason), + (override)); + MOCK_METHOD(void, Close, + (location::nearby::proto::connections::DisconnectionReason reason, + location::nearby::analytics::proto::ConnectionsLog:: + EstablishedConnection::SafeDisconnectionResult result), + (override)); + MOCK_METHOD(bool, IsClosed, (), (const, override)); + MOCK_METHOD(std::string, GetType, (), (const, override)); + MOCK_METHOD(std::string, GetServiceId, (), (const, override)); + MOCK_METHOD(std::string, GetName, (), (const, override)); + MOCK_METHOD(location::nearby::proto::connections::Medium, GetMedium, (), + (const, override)); + MOCK_METHOD(location::nearby::proto::connections::ConnectionTechnology, + GetTechnology, (), (const, override)); + MOCK_METHOD(location::nearby::proto::connections::ConnectionBand, GetBand, (), + (const, override)); + MOCK_METHOD(int, GetFrequency, (), (const, override)); + MOCK_METHOD(int, GetTryCount, (), (const, override)); + MOCK_METHOD(int, GetMaxTransmitPacketSize, (), (const, override)); + MOCK_METHOD(void, EnableEncryption, (std::shared_ptr), + (override)); + MOCK_METHOD(void, DisableEncryption, (), (override)); + MOCK_METHOD(bool, IsEncrypted, (), (override)); + MOCK_METHOD(ExceptionOr, TryDecrypt, (const ByteArray& data), + (override)); + MOCK_METHOD(bool, IsPaused, (), (const, override)); + MOCK_METHOD(void, Pause, (), (override)); + MOCK_METHOD(void, Resume, (), (override)); + MOCK_METHOD(absl::Time, GetLastReadTimestamp, (), (const, override)); + MOCK_METHOD(absl::Time, GetLastWriteTimestamp, (), (const, override)); + MOCK_METHOD(uint32_t, GetNextKeepAliveSeqNo, (), (const, override)); + MOCK_METHOD(void, SetAnalyticsRecorder, + (analytics::AnalyticsRecorder*, const std::string&), (override)); +}; + +} // namespace nearby::connections + +#endif // THIRD_PARTY_NEARBY_CONNECTIONS_IMPLEMENTATION_MOCK_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/payload_manager.cc b/connections/implementation/payload_manager.cc index 5cd26943..e9f8b57b 100644 --- a/connections/implementation/payload_manager.cc +++ b/connections/implementation/payload_manager.cc @@ -29,8 +29,6 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/time/time.h" -#include "connections/implementation/analytics/packet_meta_data.h" -#include "connections/implementation/analytics/throughput_recorder.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel_manager.h" #include "connections/implementation/endpoint_manager.h" @@ -65,8 +63,6 @@ using ::location::nearby::connections::V1Frame; using ::location::nearby::proto::connections::Medium; using ::location::nearby::proto::connections::OperationResultCode; using ::location::nearby::proto::connections::PayloadStatus; -using PacketMetaData = ::nearby::analytics::PacketMetaData; -using ::nearby::analytics::ThroughputRecorderContainer; using PayloadDirection = ::nearby::connections::PayloadDirection; constexpr absl::Duration kMinTransferUpdateInterval = absl::Milliseconds(50); @@ -81,7 +77,6 @@ bool PayloadManager::SendPayloadLoop( const EndpointIds& available_endpoint_ids = EndpointsToEndpointIds(pair.first); const Endpoints& unavailable_endpoints = pair.second; - PacketMetaData packet_meta_data; // First, handle any non-available endpoints. for (const auto& endpoint : unavailable_endpoints) { @@ -143,10 +138,8 @@ bool PayloadManager::SendPayloadLoop( // This will block if there is no data to transfer. // It will resume when new data arrives, or if Close() is called. int chunk_size = GetOptimalChunkSize(available_endpoint_ids); - packet_meta_data.StartFileIo(); ByteArray next_chunk = pending_payload.GetInternalPayload()->DetachNextChunk(chunk_size); - packet_meta_data.StopFileIo(); if (shutdown_.Get()) return false; // Save chunk size. We'll need it after we move next_chunk. auto next_chunk_size = next_chunk.size(); @@ -169,7 +162,7 @@ bool PayloadManager::SendPayloadLoop( PayloadTransferFrame::PayloadChunk payload_chunk(CreatePayloadChunk( next_chunk_offset - resume_offset, std::move(next_chunk), index)); const EndpointIds& failed_endpoint_ids = endpoint_manager_->SendPayloadChunk( - payload_header, payload_chunk, available_endpoint_ids, packet_meta_data); + payload_header, payload_chunk, available_endpoint_ids); // Check whether at least one endpoint failed. if (!failed_endpoint_ids.empty()) { VLOG(1) << "Payload xfer: endpoints failed: payload_id=" @@ -209,9 +202,6 @@ bool PayloadManager::SendPayloadLoop( VLOG(1) << "Payload xfer done: payload_id=" << pending_payload.GetInternalPayload()->GetId() << "; size=" << next_chunk_offset; - ThroughputRecorderContainer::GetInstance().MarkAsSuccess( - pending_payload.GetInternalPayload()->GetId(), - PayloadDirection::OUTGOING_PAYLOAD); return false; } } @@ -479,8 +469,6 @@ void PayloadManager::SendPayload(ClientProxy* client, std::int64_t next_chunk_offset = 0; int index = 0; - ThroughputRecorderContainer::GetInstance().Start( - payload_id, PayloadDirection::OUTGOING_PAYLOAD, payload_type); while (should_continue && !shutdown_.Get()) { should_continue = SendPayloadLoop(client, *pending_payload, payload_header, @@ -528,8 +516,7 @@ Status PayloadManager::CancelPayload(ClientProxy* client, void PayloadManager::OnIncomingFrame(OfflineFrame& offline_frame, const std::string& from_endpoint_id, ClientProxy* to_client, - Medium current_medium, - PacketMetaData& packet_meta_data) { + Medium current_medium) { PayloadTransferFrame& frame = *offline_frame.mutable_v1()->mutable_payload_transfer(); @@ -560,8 +547,7 @@ void PayloadManager::OnIncomingFrame(OfflineFrame& offline_frame, ProcessControlPacket(to_client, from_endpoint_id, frame); break; case PayloadTransferFrame::DATA: - ProcessDataPacket(to_client, from_endpoint_id, frame, current_medium, - packet_meta_data); + ProcessDataPacket(to_client, from_endpoint_id, frame, current_medium); break; case PayloadTransferFrame::PAYLOAD_ACK: VLOG(1) << "[safe-to-disconnect][PAYLOAD_RECEIVED_ACK] sender " @@ -812,10 +798,6 @@ PayloadManager::CreateIncomingPayload(const PayloadTransferFrame& frame, void PayloadManager::OnPendingPayloadDestroy(const PendingPayload* payload) { VLOG(1) << "PayloadManager: destroying " << payload->ToString() << " self=" << this; - ThroughputRecorderContainer::GetInstance().StopTPRecorder( - payload->GetId(), payload->IsIncoming() - ? PayloadDirection::INCOMING_PAYLOAD - : PayloadDirection::OUTGOING_PAYLOAD); if (payload->IsIncoming()) return; RunOnStatusUpdateThread( "~PendingPayload", @@ -1301,8 +1283,7 @@ void PayloadManager::HandleSuccessfulIncomingChunk( // @EndpointManagerDataPool void PayloadManager::ProcessDataPacket( ClientProxy* to_client, const std::string& from_endpoint_id, - PayloadTransferFrame& payload_transfer_frame, Medium medium, - PacketMetaData& packet_meta_data) { + PayloadTransferFrame& payload_transfer_frame, Medium medium) { PayloadTransferFrame::PayloadHeader& payload_header = *payload_transfer_frame.mutable_payload_header(); PayloadTransferFrame::PayloadChunk& payload_chunk = @@ -1323,10 +1304,6 @@ void PayloadManager::ProcessDataPacket( Payload::Id payload_id = payload_header.id(); PendingPayloadHandle pending_payload; if (payload_chunk.offset() == 0) { - ThroughputRecorderContainer::GetInstance().Start( - payload_id, PayloadDirection::INCOMING_PAYLOAD, - (PayloadType)payload_header.type()); - packet_meta_data.Reset(); RunOnStatusUpdateThread( "process-data-packet", [to_client, from_endpoint_id, payload_header, this]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() { @@ -1413,7 +1390,6 @@ void PayloadManager::ProcessDataPacket( // Save size of packet before we move it. std::int64_t payload_body_size = payload_chunk.body().size(); - packet_meta_data.StartFileIo(); if (pending_payload->GetInternalPayload() ->AttachNextChunk(payload_chunk.body()) .Raised()) { @@ -1425,7 +1401,6 @@ void PayloadManager::ProcessDataPacket( PayloadStatus::LOCAL_ERROR, OperationResultCode::IO_FILE_WRITING_ERROR); return; } - packet_meta_data.StopFileIo(); bool is_last_chunk = (payload_chunk.flags() & PayloadTransferFrame::PayloadChunk::LAST_CHUNK) != 0; SendPayloadReceivedAck(to_client, *pending_payload, from_endpoint_id, @@ -1434,14 +1409,6 @@ void PayloadManager::ProcessDataPacket( HandleSuccessfulIncomingChunk(to_client, from_endpoint_id, payload_header, payload_chunk.flags(), payload_chunk.offset(), payload_body_size); - - ThroughputRecorderContainer::GetInstance().UpdateFrameData( - payload_header.id(), PayloadDirection::INCOMING_PAYLOAD, medium, - packet_meta_data); - if (is_last_chunk) { - ThroughputRecorderContainer::GetInstance().MarkAsSuccess( - payload_header.id(), PayloadDirection::INCOMING_PAYLOAD); - } } // @EndpointManagerDataPool diff --git a/connections/implementation/payload_manager.h b/connections/implementation/payload_manager.h index 4ba438c5..533ee79d 100644 --- a/connections/implementation/payload_manager.h +++ b/connections/implementation/payload_manager.h @@ -26,7 +26,6 @@ #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" #include "absl/time/time.h" -#include "connections/implementation/analytics/packet_meta_data.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_manager.h" #include "connections/implementation/internal_payload.h" @@ -67,8 +66,7 @@ class PayloadManager : public EndpointManager::FrameProcessor { void OnIncomingFrame( location::nearby::connections::OfflineFrame& offline_frame, const std::string& from_endpoint_id, ClientProxy* to_client, - location::nearby::proto::connections::Medium current_medium, - analytics::PacketMetaData& packet_meta_data) override; + location::nearby::proto::connections::Medium current_medium) override; // @EndpointManagerThread void OnEndpointDisconnect( @@ -412,8 +410,7 @@ class PayloadManager : public EndpointManager::FrameProcessor { const std::string& from_endpoint_id, location::nearby::connections::PayloadTransferFrame& payload_transfer_frame, - location::nearby::proto::connections::Medium medium, - analytics::PacketMetaData& packet_meta_data); + location::nearby::proto::connections::Medium medium); void ProcessControlPacket(ClientProxy* to_client, const std::string& from_endpoint_id, location::nearby::connections::PayloadTransferFrame& diff --git a/connections/implementation/payload_manager_test.cc b/connections/implementation/payload_manager_test.cc index 612d69df..bcffb773 100644 --- a/connections/implementation/payload_manager_test.cc +++ b/connections/implementation/payload_manager_test.cc @@ -21,7 +21,6 @@ #include "gtest/gtest.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" -#include "connections/implementation/analytics/packet_meta_data.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/simulation_user.h" #include "connections/listeners.h" @@ -43,7 +42,6 @@ namespace { using ::location::nearby::connections::OfflineFrame; using ::location::nearby::connections::PayloadTransferFrame; using ::location::nearby::proto::connections::Medium; -using ::nearby::analytics::PacketMetaData; constexpr size_t kChunkSize = 64 * 1024; constexpr absl::string_view kServiceId = "service-id"; @@ -116,10 +114,8 @@ class PayloadSimulationUser : public SimulationUser { std::string bytes = parser::ForDataPayloadTransfer(header, chunk); offline_frame.ParseFromString(bytes); - PacketMetaData packet_meta_data; - pm_.OnIncomingFrame(offline_frame, from_payload_id, &client_, - Medium::WIFI_HOTSPOT, packet_meta_data); + Medium::WIFI_HOTSPOT); } Status CancelPayload() { From db6f238fde6dd47008064d210f4f381e71c7d8db Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 1 May 2026 23:44:52 -0700 Subject: [PATCH 069/151] Automated Code Change PiperOrigin-RevId: 909079635 --- internal/platform/implementation/windows/BUILD | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index b754eaf9..0ba7f3dd 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -74,9 +74,7 @@ cc_library( ], defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"], tags = ["windows"], - visibility = [ - "//sharing/internal/impl/windows:__pkg__", - ], + visibility = ["//visibility:private"], deps = [ ":device_paths", ":string_utils", From eddff719b929759f3b9b57e56c33016955abeb80 Mon Sep 17 00:00:00 2001 From: Nicholas Levin Date: Tue, 5 May 2026 12:49:06 -0700 Subject: [PATCH 070/151] Automated Code Change PiperOrigin-RevId: 910856624 --- connections/c/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connections/c/BUILD b/connections/c/BUILD index a9ce6b37..b25c23e5 100644 --- a/connections/c/BUILD +++ b/connections/c/BUILD @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@rules_apple//apple:apple.bzl", "apple_static_xcframework") +load("@rules_apple//apple:apple_xcframework.bzl", "apple_static_xcframework") load("@rules_apple//apple:macos.bzl", "macos_dylib") load("@rules_cc//cc:cc_library.bzl", "cc_library") load("//third_party/cpptoolchains/portable_llvm/build_defs:windows.bzl", "windows") From d026aed3e2900ae323d26d9a8eef0061cce53025 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 6 May 2026 11:11:19 -0700 Subject: [PATCH 071/151] Add usage and binding id to TransferMetadata. PiperOrigin-RevId: 911439518 --- sharing/BUILD | 18 +++++++- sharing/incoming_share_session.cc | 30 ++++++++---- sharing/incoming_share_session_test.cc | 31 +++++++++---- sharing/nearby_sharing_service_impl.cc | 8 ++++ sharing/outgoing_share_session.cc | 16 +++++-- sharing/outgoing_share_session_test.cc | 16 +++++-- sharing/payload_tracker.cc | 24 ++++------ sharing/payload_tracker.h | 6 +-- sharing/payload_tracker_test.cc | 8 +++- sharing/share_session.cc | 10 +++- sharing/share_session.h | 7 +++ sharing/share_session_usage.h | 45 ++++++++++++++++++ sharing/transfer_metadata.cc | 48 +++++++++++-------- sharing/transfer_metadata.h | 26 +++++++++-- sharing/transfer_metadata_builder.cc | 19 +++++++- sharing/transfer_metadata_builder.h | 8 ++++ sharing/transfer_metadata_matchers.h | 5 ++ sharing/transfer_metadata_test.cc | 64 ++++++++++++++++++++++---- 18 files changed, 306 insertions(+), 83 deletions(-) create mode 100644 sharing/share_session_usage.h diff --git a/sharing/BUILD b/sharing/BUILD index b5974de2..d2c16191 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -109,6 +109,16 @@ cc_library( ], ) +cc_library( + name = "share_session_usage", + hdrs = ["share_session_usage.h"], + visibility = [ + "//location/nearby/cpp/sharing:__subpackages__", + "//location/nearby/sharing/lib:__subpackages__", + "//sharing:__subpackages__", + ], +) + cc_library( name = "transfer_metadata", srcs = [ @@ -128,6 +138,7 @@ cc_library( "//sharing:__subpackages__", ], deps = [ + ":share_session_usage", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", ], @@ -229,6 +240,7 @@ cc_library( ":incoming_frame_reader", ":nearby_sharing_util", ":paired_key_verification_runner", + ":share_session_usage", ":thread_timer", ":transfer_metadata", ":types", @@ -369,6 +381,7 @@ cc_library( ":outgoing_targets_manager", ":paired_key_verification_runner", ":share_session", + ":share_session_usage", ":thread_timer", ":transfer_metadata", ":types", @@ -378,7 +391,6 @@ cc_library( "//internal/analytics:event_logger", "//internal/base", "//internal/base:file_path", - "//internal/base:files", "//internal/flags:nearby_flags", "//internal/network:url", "//internal/platform:base", @@ -841,6 +853,7 @@ cc_test( name = "transfer_metadata_test", srcs = ["transfer_metadata_test.cc"], deps = [ + ":share_session_usage", ":transfer_metadata", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_googletest//:gtest_main", @@ -855,6 +868,7 @@ cc_test( ":nearby_connection_impl", ":paired_key_verification_runner", ":share_session", + ":share_session_usage", ":test_support", ":transfer_metadata", ":transfer_metadata_matchers", @@ -906,6 +920,7 @@ cc_test( ":connection_types", ":nearby_connection_impl", ":share_session", + ":share_session_usage", ":test_support", ":transfer_metadata", ":transfer_metadata_matchers", @@ -939,6 +954,7 @@ cc_test( ":nearby_connection_impl", ":paired_key_verification_runner", ":share_session", + ":share_session_usage", ":test_support", ":transfer_metadata", ":transfer_metadata_matchers", diff --git a/sharing/incoming_share_session.cc b/sharing/incoming_share_session.cc index a0e8e0d5..ed86146a 100644 --- a/sharing/incoming_share_session.cc +++ b/sharing/incoming_share_session.cc @@ -41,6 +41,7 @@ #include "sharing/payload_tracker.h" #include "sharing/proto/wire_format.pb.h" #include "sharing/share_session.h" +#include "sharing/share_session_usage.h" #include "sharing/share_target.h" #include "sharing/text_attachment.h" #include "sharing/thread_timer.h" @@ -69,7 +70,9 @@ IncomingShareSession::IncomingShareSession( transfer_update_callback) : ShareSession(clock, service_thread, connections_manager, analytics_recorder, std::move(endpoint_id), share_target), - transfer_update_callback_(std::move(transfer_update_callback)) {} + transfer_update_callback_(std::move(transfer_update_callback)) { + set_session_usage(ShareSessionUsage::kSharing); +} IncomingShareSession::IncomingShareSession(IncomingShareSession&&) = default; @@ -210,6 +213,7 @@ bool IncomingShareSession::ReadyForTransfer( if (!self_share()) { TransferMetadataBuilder transfer_metadata_builder; + transfer_metadata_builder.set_usage(session_usage()); transfer_metadata_builder.set_status( TransferMetadata::Status::kAwaitingLocalConfirmation); transfer_metadata_builder.set_token(token()); @@ -249,6 +253,7 @@ bool IncomingShareSession::AcceptTransfer( UpdateTransferMetadata( TransferMetadataBuilder() + .set_usage(session_usage()) .set_status(TransferMetadata::Status::kAwaitingRemoteAcceptance) .set_token(token()) .build()); @@ -434,7 +439,10 @@ void IncomingShareSession::SendFailureResponse( WriteResponseFrame(response_status); DCHECK(TransferMetadata::IsFinalStatus(status)) << "SendFailureResponse should only be called with a final status"; - UpdateTransferMetadata(TransferMetadataBuilder().set_status(status).build()); + UpdateTransferMetadata(TransferMetadataBuilder() + .set_usage(session_usage()) + .set_status(status) + .build()); } std::optional @@ -449,19 +457,21 @@ IncomingShareSession::ProcessPayloadTransferUpdates( // Cancel acceptance timer when payload transfer update is received. // This mean sender has begun sending payload. mutual_acceptance_timeout_ = nullptr; - std::optional metadata; + std::optional metadata_builder; // If there is a batch of updates in the queue, only return the latest // TransferMetadata. for (; !updates.empty(); updates.pop()) { - metadata = + metadata_builder = get_payload_tracker()->ProcessPayloadUpdate(std::move(updates.front())); - if (!metadata.has_value()) { + if (!metadata_builder.has_value()) { continue; } - - if (metadata->status() == TransferMetadata::Status::kComplete) { + TransferMetadata metadata = + metadata_builder->set_usage(session_usage()).build(); + if (metadata.status() == TransferMetadata::Status::kComplete) { if (!FinalizePayloads()) { return TransferMetadataBuilder() + .set_usage(session_usage()) .set_status(TransferMetadata::Status::kIncompletePayloads) .build(); } @@ -474,13 +484,15 @@ IncomingShareSession::ProcessPayloadTransferUpdates( if (update_file_paths_in_progress) { UpdateFilePayloadPaths(); } else { - if (metadata->status() == TransferMetadata::Status::kCancelled) { + if (metadata.status() == TransferMetadata::Status::kCancelled) { VLOG(1) << __func__ << ": Update file paths for cancelled transfer"; UpdateFilePayloadPaths(); } } } - return metadata; + return metadata_builder.has_value() + ? std::make_optional(metadata_builder->build()) + : std::nullopt; } void IncomingShareSession::OnConnected(NearbyConnection* connection) { diff --git a/sharing/incoming_share_session_test.cc b/sharing/incoming_share_session_test.cc index b926f65b..999fbe7f 100644 --- a/sharing/incoming_share_session_test.cc +++ b/sharing/incoming_share_session_test.cc @@ -43,9 +43,9 @@ #include "sharing/internal/public/logging.h" #include "sharing/nearby_connection_impl.h" #include "sharing/nearby_connections_types.h" -#include "sharing/paired_key_verification_runner.h" #include "sharing/proto/analytics/nearby_sharing_log.pb.h" #include "sharing/proto/wire_format.pb.h" +#include "sharing/share_session_usage.h" #include "sharing/share_target.h" #include "sharing/text_attachment.h" #include "sharing/transfer_metadata.h" @@ -59,7 +59,6 @@ namespace { using ::absl::Seconds; using ::location::nearby::proto::sharing::EventCategory; using ::location::nearby::proto::sharing::EventType; -using ::location::nearby::proto::sharing::OSType; using ::location::nearby::proto::sharing::ResponseToIntroduction; using ::nearby::analytics::HasAction; using ::nearby::analytics::HasCategory; @@ -1085,7 +1084,9 @@ TEST_F(IncomingShareSessionTest, ReadyForTransferNotSelfShare) { session_.OnConnected(&connection_); EXPECT_CALL( transfer_metadata_callback_, - Call(_, HasStatus(TransferMetadata::Status::kAwaitingLocalConfirmation))); + Call(_, AllOf(HasStatus( + TransferMetadata::Status::kAwaitingLocalConfirmation), + HasUsage(ShareSessionUsage::kSharing)))); EXPECT_THAT( session_.ReadyForTransfer( @@ -1104,7 +1105,9 @@ TEST_F(IncomingShareSessionTest, ReadyForTransferSelfShare) { session.OnConnected(&connection_); EXPECT_CALL( transfer_metadata_callback_, - Call(_, HasStatus(TransferMetadata::Status::kAwaitingLocalConfirmation))) + Call(_, AllOf(HasStatus( + TransferMetadata::Status::kAwaitingLocalConfirmation), + HasUsage(ShareSessionUsage::kSharing)))) .Times(0); EXPECT_THAT( @@ -1117,7 +1120,9 @@ TEST_F(IncomingShareSessionTest, ReadyForTransferTimeout) { session_.OnConnected(&connection_); EXPECT_CALL( transfer_metadata_callback_, - Call(_, HasStatus(TransferMetadata::Status::kAwaitingLocalConfirmation))); + Call(_, AllOf(HasStatus( + TransferMetadata::Status::kAwaitingLocalConfirmation), + HasUsage(ShareSessionUsage::kSharing)))); bool accept_timeout_called = false; EXPECT_THAT(session_.ReadyForTransfer( @@ -1195,7 +1200,9 @@ TEST_F(IncomingShareSessionTest, AcceptTransferSuccess) { IsFalse()); EXPECT_CALL( transfer_metadata_callback_, - Call(_, HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance))); + Call(_, + AllOf(HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance), + HasUsage(ShareSessionUsage::kSharing)))); EXPECT_CALL( mock_event_logger_, Log(Matcher(AllOf( @@ -1274,8 +1281,10 @@ TEST_F(IncomingShareSessionTest, TryUpgradeBandwidthNeeded) { } TEST_F(IncomingShareSessionTest, SendFailureResponseNotConnected) { - EXPECT_CALL(transfer_metadata_callback_, - Call(_, HasStatus(TransferMetadata::Status::kNotEnoughSpace))); + EXPECT_CALL( + transfer_metadata_callback_, + Call(_, AllOf(HasStatus(TransferMetadata::Status::kNotEnoughSpace), + HasUsage(ShareSessionUsage::kSharing)))); session_.SendFailureResponse(TransferMetadata::Status::kNotEnoughSpace); } @@ -1284,8 +1293,10 @@ TEST_F(IncomingShareSessionTest, SendFailureResponseConnected) { connections_manager_.AcceptConnection( /*endpoint_info=*/{}, kEndpointId, &connection_); session_.OnConnected(&connection_); - EXPECT_CALL(transfer_metadata_callback_, - Call(_, HasStatus(TransferMetadata::Status::kNotEnoughSpace))); + EXPECT_CALL( + transfer_metadata_callback_, + Call(_, AllOf(HasStatus(TransferMetadata::Status::kNotEnoughSpace), + HasUsage(ShareSessionUsage::kSharing)))); std::queue> frames_data; connections_manager_.set_send_payload_callback( [&](std::unique_ptr payload, diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index dbcb557b..bba46979 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -97,6 +97,7 @@ #include "sharing/proto/wire_format.pb.h" #include "sharing/scheduling/nearby_share_scheduler_utils.h" #include "sharing/share_session.h" +#include "sharing/share_session_usage.h" #include "sharing/share_target.h" #include "sharing/share_target_discovered_callback.h" #include "sharing/thread_timer.h" @@ -858,6 +859,7 @@ void NearbySharingServiceImpl::Reject( session->UpdateTransferMetadata( TransferMetadataBuilder() + .set_usage(session->session_usage()) .set_status(TransferMetadata::Status::kRejected) .build()); @@ -914,6 +916,7 @@ void NearbySharingServiceImpl::DoCancel( // UpdateTransferMetadata. session->UpdateTransferMetadata( TransferMetadataBuilder() + .set_usage(session->session_usage()) .set_status(TransferMetadata::Status::kCancelled) .build()); @@ -2582,6 +2585,7 @@ void NearbySharingServiceImpl::BeginOutgoingTransfer( } else { session.UpdateTransferMetadata( TransferMetadataBuilder() + .set_usage(session.session_usage()) .set_status(TransferMetadata::Status::kAwaitingLocalConfirmation) .set_token(session.token()) .build()); @@ -2592,6 +2596,7 @@ void NearbySharingServiceImpl::BeginOutgoingPairing( OutgoingShareSession& session) { VLOG(1) << __func__ << ": Preparing to initiate pairing with " << session.share_target().id; + session.set_session_usage(ShareSessionUsage::kPairing); // Verify that remote really authenticated with self share certificate. if (!session.self_share()) { LOG(WARNING) << __func__ << ": Not self share, skipping pairing."; @@ -2663,6 +2668,8 @@ void NearbySharingServiceImpl::OnPeerSyncBindingComplete( sync_manager_.AddSyncBinding(binding); session->UpdateTransferMetadata( TransferMetadataBuilder() + .set_usage(session->session_usage()) + .set_binding_id(binding_id) .set_status(TransferMetadata::Status::kComplete) .build()); } @@ -2899,6 +2906,7 @@ void NearbySharingServiceImpl::OnIncomingFilesMetadataUpdated( int64_t share_target_id, TransferMetadata metadata, bool success) { if (!success) { metadata = TransferMetadataBuilder() + .set_usage(metadata.usage()) .set_status(TransferMetadata::Status::kIncompletePayloads) .build(); } diff --git a/sharing/outgoing_share_session.cc b/sharing/outgoing_share_session.cc index 38e845e4..7b9b52a9 100644 --- a/sharing/outgoing_share_session.cc +++ b/sharing/outgoing_share_session.cc @@ -43,6 +43,7 @@ #include "sharing/payload_tracker.h" #include "sharing/proto/wire_format.pb.h" #include "sharing/share_session.h" +#include "sharing/share_session_usage.h" #include "sharing/share_target.h" #include "sharing/text_attachment.h" #include "sharing/thread_timer.h" @@ -185,6 +186,7 @@ bool OutgoingShareSession::InitiateSendAttachments( "create payloads."; UpdateTransferMetadata( TransferMetadataBuilder() + .set_usage(session_usage()) .set_status(TransferMetadata::Status::kMediaUnavailable) .build()); } @@ -334,6 +336,7 @@ bool OutgoingShareSession::AcceptTransfer( // Wait for remote accept in response frame. UpdateTransferMetadata( TransferMetadataBuilder() + .set_usage(session_usage()) .set_token(token()) .set_status(TransferMetadata::Status::kAwaitingRemoteAcceptance) .build()); @@ -408,6 +411,7 @@ void OutgoingShareSession::SendAttachmentsCompleted( bool OutgoingShareSession::SendIntroduction( std::function timeout_callback) { + set_session_usage(ShareSessionUsage::kSharing); Frame frame; frame.set_version(Frame::V1); V1Frame* v1_frame = frame.mutable_v1(); @@ -450,6 +454,7 @@ OutgoingShareSession::HandleConnectionResponse( case ConnectionResponseFrame::ACCEPT: { UpdateTransferMetadata( TransferMetadataBuilder() + .set_usage(session_usage()) .set_status(TransferMetadata::Status::kInProgress) .build()); return std::nullopt; @@ -551,6 +556,7 @@ void OutgoingShareSession::Connect( // Send process initialized successfully, from now on status updated // will be sent out via TransferUpdates. UpdateTransferMetadata(TransferMetadataBuilder() + .set_usage(session_usage()) .set_status(TransferMetadata::Status::kConnecting) .build()); connection_start_time_ = clock().Now(); @@ -627,12 +633,15 @@ OutgoingShareSession::ProcessPayloadTransferUpdates() { return std::nullopt; } - std::optional metadata; + std::optional metadata_builder; for (; !updates.empty(); updates.pop()) { - metadata = + metadata_builder = get_payload_tracker()->ProcessPayloadUpdate(std::move(updates.front())); } - return metadata; + return metadata_builder.has_value() + ? std::make_optional( + metadata_builder->set_usage(session_usage()).build()) + : std::nullopt; } void OutgoingShareSession::StartPeerBinding( @@ -650,6 +659,7 @@ void OutgoingShareSession::StartPeerBinding( LOG(INFO) << "Waiting for bindings response frame from " << share_target().id; UpdateTransferMetadata( TransferMetadataBuilder() + .set_usage(session_usage()) .set_token(token()) .set_status(TransferMetadata::Status::kAwaitingRemoteAcceptance) .build()); diff --git a/sharing/outgoing_share_session_test.cc b/sharing/outgoing_share_session_test.cc index 670bd680..38157909 100644 --- a/sharing/outgoing_share_session_test.cc +++ b/sharing/outgoing_share_session_test.cc @@ -49,6 +49,7 @@ #include "sharing/proto/analytics/nearby_sharing_log.pb.h" #include "sharing/proto/analytics/nearby_sharing_log.proto.static_reflection.h" #include "sharing/proto/wire_format.pb.h" +#include "sharing/share_session_usage.h" #include "sharing/share_target.h" #include "sharing/text_attachment.h" #include "sharing/transfer_metadata.h" @@ -923,6 +924,7 @@ TEST_F(OutgoingShareSessionTest, TEST_F(OutgoingShareSessionTest, StartPeerBindingSuccess) { session_.set_session_id(1234); + session_.set_session_usage(ShareSessionUsage::kPairing); NearbyConnectionImpl connection(device_info_); ConnectionSuccess(&connection); Frame expected_binding_request_frame = @@ -948,7 +950,9 @@ TEST_F(OutgoingShareSessionTest, StartPeerBindingSuccess) { }); EXPECT_CALL( transfer_metadata_callback_, - Call(_, HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance))); + Call(_, + AllOf(HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance), + HasUsage(ShareSessionUsage::kPairing)))); BindingResponse::Status binding_response_status = BindingResponse::FAILURE; session_.StartPeerBinding("test_binding_id", BindingRequest::FILESYNC, @@ -988,6 +992,7 @@ TEST_F(OutgoingShareSessionTest, StartPeerBindingSuccess) { TEST_F(OutgoingShareSessionTest, StartPeerBindingTimeout) { session_.set_session_id(1234); + session_.set_session_usage(ShareSessionUsage::kPairing); NearbyConnectionImpl connection(device_info_); ConnectionSuccess(&connection); Frame expected_binding_request_frame = @@ -1013,7 +1018,9 @@ TEST_F(OutgoingShareSessionTest, StartPeerBindingTimeout) { }); EXPECT_CALL( transfer_metadata_callback_, - Call(_, HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance))); + Call(_, + AllOf(HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance), + HasUsage(ShareSessionUsage::kPairing)))); BindingResponse::Status binding_response_status = BindingResponse::FAILURE; session_.StartPeerBinding("test_binding_id", BindingRequest::FILESYNC, @@ -1036,6 +1043,7 @@ TEST_F(OutgoingShareSessionTest, StartPeerBindingTimeout) { TEST_F(OutgoingShareSessionTest, StartPeerBindingFailure) { session_.set_session_id(1234); + session_.set_session_usage(ShareSessionUsage::kPairing); NearbyConnectionImpl connection(device_info_); ConnectionSuccess(&connection); Frame expected_binding_request_frame = @@ -1061,7 +1069,9 @@ TEST_F(OutgoingShareSessionTest, StartPeerBindingFailure) { }); EXPECT_CALL( transfer_metadata_callback_, - Call(_, HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance))); + Call(_, + AllOf(HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance), + HasUsage(ShareSessionUsage::kPairing)))); BindingResponse::Status binding_response_status = BindingResponse::FAILURE; session_.StartPeerBinding("test_binding_id", BindingRequest::FILESYNC, diff --git a/sharing/payload_tracker.cc b/sharing/payload_tracker.cc index e05b4818..345a87a6 100644 --- a/sharing/payload_tracker.cc +++ b/sharing/payload_tracker.cc @@ -107,7 +107,7 @@ void PayloadTracker::OnStatusUpdate( payload_update_queue_->Queue(std::move(update)); } -std::optional PayloadTracker::ProcessPayloadUpdate( +std::optional PayloadTracker::ProcessPayloadUpdate( std::unique_ptr update) { auto it = payload_state_.find(update->payload_id); if (it == payload_state_.end()) { @@ -139,34 +139,31 @@ std::optional PayloadTracker::ProcessPayloadUpdate( return OnTransferUpdate(state); } -std::optional PayloadTracker::OnTransferUpdate( +std::optional PayloadTracker::OnTransferUpdate( const State& state) { if (IsComplete()) { VLOG(1) << __func__ << ": All payloads are complete."; - return TransferMetadataBuilder() + return std::move(TransferMetadataBuilder() .set_status(TransferMetadata::Status::kComplete) .set_progress(100) .set_total_attachments_count(payload_state_.size()) - .set_transferred_attachments_count(transferred_attachments_count_) - .build(); + .set_transferred_attachments_count(transferred_attachments_count_)); } if (IsCancelled(state)) { VLOG(1) << __func__ << ": Payloads cancelled."; - return TransferMetadataBuilder() + return std::move(TransferMetadataBuilder() .set_status(TransferMetadata::Status::kCancelled) .set_total_attachments_count(payload_state_.size()) - .set_transferred_attachments_count(transferred_attachments_count_) - .build(); + .set_transferred_attachments_count(transferred_attachments_count_)); } if (HasFailed(state)) { VLOG(1) << __func__ << ": Payloads failed."; - return TransferMetadataBuilder() + return std::move(TransferMetadataBuilder() .set_status(TransferMetadata::Status::kFailed) .set_total_attachments_count(payload_state_.size()) - .set_transferred_attachments_count(transferred_attachments_count_) - .build(); + .set_transferred_attachments_count(transferred_attachments_count_)); } double percent = CalculateProgressPercent(state); @@ -220,7 +217,7 @@ std::optional PayloadTracker::OnTransferUpdate( last_update_progress_ = current_progress; - return TransferMetadataBuilder() + return std::move(TransferMetadataBuilder() .set_status(TransferMetadata::Status::kInProgress) .set_progress(percent) .set_transferred_bytes(current_transferred_size) @@ -230,8 +227,7 @@ std::optional PayloadTracker::OnTransferUpdate( .set_transferred_attachments_count(transferred_attachments_count_) .set_in_progress_attachment_id(state.attachment_id) .set_in_progress_attachment_total_bytes(state.total_size) - .set_in_progress_attachment_transferred_bytes(state.amount_transferred) - .build(); + .set_in_progress_attachment_transferred_bytes(state.amount_transferred)); } bool PayloadTracker::IsComplete() const { diff --git a/sharing/payload_tracker.h b/sharing/payload_tracker.h index 4f73e4e6..e27025e0 100644 --- a/sharing/payload_tracker.h +++ b/sharing/payload_tracker.h @@ -27,7 +27,7 @@ #include "sharing/attachment_container.h" #include "sharing/nearby_connections_manager.h" #include "sharing/nearby_connections_types.h" -#include "sharing/transfer_metadata.h" +#include "sharing/transfer_metadata_builder.h" #include "sharing/worker_queue.h" namespace nearby { @@ -46,7 +46,7 @@ class PayloadTracker : public NearbyConnectionsManager::PayloadStatusListener { std::unique_ptr payload_queue); ~PayloadTracker() override; - std::optional ProcessPayloadUpdate( + std::optional ProcessPayloadUpdate( std::unique_ptr update); // NearbyConnectionsManager::PayloadStatusListener: @@ -64,7 +64,7 @@ class PayloadTracker : public NearbyConnectionsManager::PayloadStatusListener { PayloadStatus status = PayloadStatus::kInProgress; }; - std::optional OnTransferUpdate(const State& state); + std::optional OnTransferUpdate(const State& state); bool IsComplete() const; bool IsCancelled(const State& state) const; diff --git a/sharing/payload_tracker_test.cc b/sharing/payload_tracker_test.cc index 73cac929..8b21d2ba 100644 --- a/sharing/payload_tracker_test.cc +++ b/sharing/payload_tracker_test.cc @@ -32,6 +32,7 @@ #include "sharing/nearby_connections_types.h" #include "sharing/proto/wire_format.pb.h" #include "sharing/transfer_metadata.h" +#include "sharing/transfer_metadata_builder.h" namespace nearby::sharing { namespace { @@ -69,7 +70,12 @@ class PayloadTrackerTest : public ::testing::Test { auto transfer_update = std::make_unique( /*payload_id=*/kFileId, PayloadStatus::kInProgress, /*total_bytes=*/kFileSize, /*bytes_transferred=*/bytes_transferred); - return payload_tracker_->ProcessPayloadUpdate(std::move(transfer_update)); + std::optional metadata_builder = + payload_tracker_->ProcessPayloadUpdate(std::move(transfer_update)); + if (!metadata_builder.has_value()) { + return std::nullopt; + } + return metadata_builder->build(); } private: diff --git a/sharing/share_session.cc b/sharing/share_session.cc index 885e8396..004b3779 100644 --- a/sharing/share_session.cc +++ b/sharing/share_session.cc @@ -176,7 +176,10 @@ void ShareSession::Abort(TransferMetadata::Status status) { // First invoke the appropriate transfer callback with the final // |status|. - UpdateTransferMetadata(TransferMetadataBuilder().set_status(status).build()); + UpdateTransferMetadata(TransferMetadataBuilder() + .set_usage(session_usage()) + .set_status(status) + .build()); Disconnect(); } @@ -246,7 +249,10 @@ void ShareSession::OnDisconnect() { OnConnectionDisconnected(); if (disconnect_status_ != TransferMetadata::Status::kUnknown) { UpdateTransferMetadata( - TransferMetadataBuilder().set_status(disconnect_status_).build()); + TransferMetadataBuilder() + .set_usage(session_usage()) + .set_status(disconnect_status_) + .build()); } connection_ = nullptr; } diff --git a/sharing/share_session.h b/sharing/share_session.h index d0dc0f03..0a6675d7 100644 --- a/sharing/share_session.h +++ b/sharing/share_session.h @@ -38,6 +38,7 @@ #include "sharing/paired_key_verification_runner.h" #include "sharing/payload_tracker.h" #include "sharing/proto/wire_format.pb.h" +#include "sharing/share_session_usage.h" #include "sharing/share_target.h" #include "sharing/transfer_metadata.h" @@ -96,6 +97,11 @@ class ShareSession { const ShareTarget& share_target() const { return share_target_; } + ShareSessionUsage session_usage() const { return session_usage_; } + void set_session_usage(ShareSessionUsage session_usage) { + session_usage_ = session_usage; + } + // Sets the status to send in the TransferMetadataUpdate on connection // disconnect. If |status| is kUnknown, then no TransferMetadataUpdate will be // sent. If |status| is set, it must be a final status. @@ -221,6 +227,7 @@ class ShareSession { absl::flat_hash_map attachment_payload_map_; PayloadTracker::PayloadUpdateQueue* payload_updates_queue_ = nullptr; bool is_cancelled_ = false; + ShareSessionUsage session_usage_ = ShareSessionUsage::kUnknown; }; } // namespace nearby::sharing diff --git a/sharing/share_session_usage.h b/sharing/share_session_usage.h new file mode 100644 index 00000000..0a2e2ded --- /dev/null +++ b/sharing/share_session_usage.h @@ -0,0 +1,45 @@ +// Copyright 2026 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_SHARING_SHARE_SESSION_USAGE_H_ +#define THIRD_PARTY_NEARBY_SHARING_SHARE_SESSION_USAGE_H_ + +#include + +namespace nearby::sharing { + +enum class ShareSessionUsage { + kUnknown, + kSharing, // Connection is used for quick share. + kPairing, // Connection is used for setting up a binding. + kFileSync, // Connection is used for file sync. +}; + +inline std::string ShareSessionUsageToString( + ShareSessionUsage transfer_usage) { + switch (transfer_usage) { + case ShareSessionUsage::kSharing: + return "Sharing"; + case ShareSessionUsage::kPairing: + return "Pairing"; + case ShareSessionUsage::kFileSync: + return "FileSync"; + case ShareSessionUsage::kUnknown: + return "Unknown"; + } +} + +} // namespace nearby::sharing + +#endif // THIRD_PARTY_NEARBY_SHARING_SHARE_SESSION_USAGE_H_ diff --git a/sharing/transfer_metadata.cc b/sharing/transfer_metadata.cc index 82462b89..d62e2a9e 100644 --- a/sharing/transfer_metadata.cc +++ b/sharing/transfer_metadata.cc @@ -24,9 +24,10 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/str_join.h" +#include "absl/strings/string_view.h" +#include "sharing/share_session_usage.h" -namespace nearby { -namespace sharing { +namespace nearby::sharing { // static bool TransferMetadata::IsFinalStatus(Status status) { @@ -90,15 +91,17 @@ std::string TransferMetadata::StatusToString(Status status) { // LINT.ThenChange(//depot/google3/location/nearby/cpp/sharing/clients/dart/platform/lib/types/transfer_status.dart) TransferMetadata::TransferMetadata( - Status status, float progress, std::optional token, - bool is_original, bool is_final_status, bool is_self_share, - uint64_t transferred_bytes, uint64_t transfer_speed, + ShareSessionUsage usage, Status status, float progress, + std::optional token, bool is_original, bool is_final_status, + bool is_self_share, uint64_t transferred_bytes, uint64_t transfer_speed, uint64_t estimated_time_remaining, int total_attachments_count, int transferred_attachments_count, std::optional in_progress_attachment_id, std::optional in_progress_attachment_transferred_bytes, - std::optional in_progress_attachment_total_bytes) - : status_(status), + std::optional in_progress_attachment_total_bytes, + absl::string_view binding_id) + : usage_(usage), + status_(status), progress_(progress), token_(std::move(token)), is_original_(is_original), @@ -112,7 +115,8 @@ TransferMetadata::TransferMetadata( in_progress_attachment_id_(in_progress_attachment_id), in_progress_attachment_transferred_bytes_( in_progress_attachment_transferred_bytes), - in_progress_attachment_total_bytes_(in_progress_attachment_total_bytes) {} + in_progress_attachment_total_bytes_(in_progress_attachment_total_bytes), + binding_id_(binding_id) {} TransferMetadata::~TransferMetadata() = default; @@ -123,22 +127,26 @@ TransferMetadata& TransferMetadata::operator=(const TransferMetadata&) = std::string TransferMetadata::ToString() const { std::vector fmt; - + fmt.push_back( + absl::StrFormat("usage: %s", ShareSessionUsageToString(usage_))); fmt.push_back(absl::StrFormat("status: %s", StatusToString(status_))); - fmt.push_back(absl::StrFormat("progress: %.2f", progress_)); - if (token_) { - fmt.push_back(absl::StrFormat("token: %s", *token_)); - } - fmt.push_back(absl::StrFormat("is_original: %d", is_original_)); fmt.push_back(absl::StrFormat("is_final_status: %d", is_final_status_)); fmt.push_back(absl::StrFormat("is_self_share: %d", is_self_share_)); - fmt.push_back(absl::StrFormat("transferred_bytes: %d", transferred_bytes_)); - fmt.push_back(absl::StrFormat("transfer_speed: %d", transfer_speed_)); - fmt.push_back(absl::StrFormat("estimated_time_remaining: %d", - estimated_time_remaining_)); + if (usage_ != ShareSessionUsage::kPairing) { + fmt.push_back(absl::StrFormat("progress: %.2f", progress_)); + if (token_) { + fmt.push_back(absl::StrFormat("token: %s", *token_)); + } + fmt.push_back(absl::StrFormat("is_original: %d", is_original_)); + fmt.push_back(absl::StrFormat("transferred_bytes: %d", transferred_bytes_)); + fmt.push_back(absl::StrFormat("transfer_speed: %d", transfer_speed_)); + fmt.push_back(absl::StrFormat("estimated_time_remaining: %d", + estimated_time_remaining_)); + } else { + fmt.push_back(absl::StrFormat("binding_id: %s", binding_id_)); + } return absl::StrCat("TransferMetadata<", absl::StrJoin(fmt, ", "), ">"); } -} // namespace sharing -} // namespace nearby +} // namespace nearby::sharing diff --git a/sharing/transfer_metadata.h b/sharing/transfer_metadata.h index 03171a78..bc665e1f 100644 --- a/sharing/transfer_metadata.h +++ b/sharing/transfer_metadata.h @@ -19,6 +19,10 @@ #include #include +#include + +#include "absl/strings/string_view.h" +#include "sharing/share_session_usage.h" namespace nearby { namespace sharing { @@ -50,23 +54,31 @@ class TransferMetadata { // LINT.ThenChange(//depot/google3/location/nearby/cpp/sharing/clients/dart/platform/lib/types/transfer_status.dart) static bool IsFinalStatus(Status status); - static std::string StatusToString(TransferMetadata::Status status); + static std::string StatusToString(Status status); TransferMetadata( - Status status, float progress, std::optional token, - bool is_original, bool is_final_status, bool is_self_share, - uint64_t transferred_bytes, uint64_t transfer_speed, + ShareSessionUsage usage, Status status, float progress, + std::optional token, bool is_original, bool is_final_status, + bool is_self_share, uint64_t transferred_bytes, uint64_t transfer_speed, uint64_t estimated_time_remaining, int total_attachments_count, int transferred_attachments_count, std::optional in_progress_attachment_id, std::optional in_progress_attachment_transferred_bytes, - std::optional in_progress_attachment_total_bytes); + std::optional in_progress_attachment_total_bytes, + absl::string_view binding_id + ); ~TransferMetadata(); TransferMetadata(const TransferMetadata&); TransferMetadata& operator=(const TransferMetadata&); + ShareSessionUsage usage() const { return usage_; } Status status() const { return status_; } + std::string binding_id() const { return binding_id_; } + void set_binding_id(std::string binding_id) { + binding_id_ = std::move(binding_id); + } + // Returns transfer progress as percentage. float progress() const { return progress_; } @@ -118,6 +130,7 @@ class TransferMetadata { } private: + ShareSessionUsage usage_; Status status_; float progress_; std::optional token_; @@ -132,6 +145,9 @@ class TransferMetadata { std::optional in_progress_attachment_id_; std::optional in_progress_attachment_transferred_bytes_; std::optional in_progress_attachment_total_bytes_; + // If usage_ is kPairing and status_ is kComplete, this will be set to the + // binding id. Otherwise, this will be empty. + std::string binding_id_; }; } // namespace sharing diff --git a/sharing/transfer_metadata_builder.cc b/sharing/transfer_metadata_builder.cc index 3f849a2c..0fde6cdf 100644 --- a/sharing/transfer_metadata_builder.cc +++ b/sharing/transfer_metadata_builder.cc @@ -19,6 +19,8 @@ #include #include +#include "absl/strings/string_view.h" +#include "sharing/share_session_usage.h" #include "sharing/transfer_metadata.h" namespace nearby { @@ -27,6 +29,7 @@ namespace sharing { TransferMetadataBuilder TransferMetadataBuilder::Clone( const TransferMetadata& metadata) { TransferMetadataBuilder builder; + builder.usage_ = metadata.usage(); builder.is_original_ = metadata.is_original(); builder.progress_ = metadata.progress(); builder.status_ = metadata.status(); @@ -54,6 +57,18 @@ TransferMetadataBuilder& TransferMetadataBuilder::operator=( TransferMetadataBuilder::~TransferMetadataBuilder() = default; +TransferMetadataBuilder& TransferMetadataBuilder::set_usage( + ShareSessionUsage usage) { + usage_ = usage; + return *this; +} + +TransferMetadataBuilder& TransferMetadataBuilder::set_binding_id( + absl::string_view binding_id) { + binding_id_ = binding_id; + return *this; +} + TransferMetadataBuilder& TransferMetadataBuilder::set_is_original( bool is_original) { is_original_ = is_original; @@ -138,12 +153,12 @@ TransferMetadataBuilder::set_in_progress_attachment_total_bytes( TransferMetadata TransferMetadataBuilder::build() const { return TransferMetadata( - status_, progress_, token_, is_original_, + usage_, status_, progress_, token_, is_original_, TransferMetadata::IsFinalStatus(status_), is_self_share_, transferred_bytes_, transfer_speed_, estimated_time_remaining_, total_attachments_count_, transferred_attachments_count_, in_progress_attachment_id_, in_progress_attachment_transferred_bytes_, - in_progress_attachment_total_bytes_); + in_progress_attachment_total_bytes_, binding_id_); } } // namespace sharing diff --git a/sharing/transfer_metadata_builder.h b/sharing/transfer_metadata_builder.h index 208a8cca..aaaebf42 100644 --- a/sharing/transfer_metadata_builder.h +++ b/sharing/transfer_metadata_builder.h @@ -20,6 +20,8 @@ #include #include +#include "absl/strings/string_view.h" +#include "sharing/share_session_usage.h" #include "sharing/transfer_metadata.h" namespace nearby { @@ -34,6 +36,10 @@ class TransferMetadataBuilder { TransferMetadataBuilder& operator=(TransferMetadataBuilder&&); ~TransferMetadataBuilder(); + TransferMetadataBuilder& set_usage(ShareSessionUsage usage); + + TransferMetadataBuilder& set_binding_id(absl::string_view binding_id); + TransferMetadataBuilder& set_is_original(bool is_original); TransferMetadataBuilder& set_progress(double progress); @@ -69,6 +75,7 @@ class TransferMetadataBuilder { TransferMetadata build() const; private: + ShareSessionUsage usage_ = ShareSessionUsage::kUnknown; bool is_original_ = false; double progress_ = 0; TransferMetadata::Status status_ = TransferMetadata::Status::kInProgress; @@ -83,6 +90,7 @@ class TransferMetadataBuilder { std::optional in_progress_attachment_transferred_bytes_ = std::nullopt; std::optional in_progress_attachment_total_bytes_ = std::nullopt; + std::string binding_id_; }; } // namespace sharing diff --git a/sharing/transfer_metadata_matchers.h b/sharing/transfer_metadata_matchers.h index 64921792..9e85348b 100644 --- a/sharing/transfer_metadata_matchers.h +++ b/sharing/transfer_metadata_matchers.h @@ -23,6 +23,11 @@ MATCHER_P(HasStatus, status, "has status") { return arg.status() == status; } +MATCHER_P(HasUsage, usage, "has usage") { + return arg.usage() == usage; +} + + MATCHER(IsFinalStatus, "is final") { return arg.is_final_status(); } diff --git a/sharing/transfer_metadata_test.cc b/sharing/transfer_metadata_test.cc index ef2d7493..09721dcc 100644 --- a/sharing/transfer_metadata_test.cc +++ b/sharing/transfer_metadata_test.cc @@ -19,6 +19,7 @@ #include #include "gtest/gtest.h" +#include "sharing/share_session_usage.h" namespace nearby { namespace sharing { @@ -34,6 +35,7 @@ std::vector GetTestData() { kTransferMetadataToStringTestData = new std::vector({ {TransferMetadata( + ShareSessionUsage::kSharing, TransferMetadata::Status::kConnecting, /*progress=*/12.321f, /*token=*/std::nullopt, /*is_original=*/true, /*is_final_status=*/false, @@ -45,12 +47,14 @@ std::vector GetTestData() { /*transferred_attachments_count=*/0, /*in_progress_attachment_id=*/std::nullopt, /*in_progress_attachment_transferred_bytes=*/std::nullopt, - /*in_progress_attachment_total_bytes=*/std::nullopt), - "TransferMetadata"}, + /*in_progress_attachment_total_bytes=*/std::nullopt, + /*binding_id=*/""), + "TransferMetadata"}, {TransferMetadata( + ShareSessionUsage::kSharing, TransferMetadata::Status::kCancelled, /*progress=*/77.795f, std::optional{"test_token"}, @@ -62,11 +66,51 @@ std::vector GetTestData() { /*transferred_attachments_count=*/0, /*in_progress_attachment_id=*/std::nullopt, /*in_progress_attachment_transferred_bytes=*/std::nullopt, - /*in_progress_attachment_total_bytes=*/std::nullopt), - "TransferMetadata"}, + {TransferMetadata( + ShareSessionUsage::kFileSync, + TransferMetadata::Status::kCancelled, + /*progress=*/77.795f, + std::optional{"test_token"}, + /*is_original=*/false, + /*is_final_status=*/true, /*is_self_share=*/true, + /*transferred_bytes=*/123456789, /*transfer_speed=*/0, + /*estimated_time_remaining=*/123456789, + /*total_attachments_count=*/1, + /*transferred_attachments_count=*/0, + /*in_progress_attachment_id=*/std::nullopt, + /*in_progress_attachment_transferred_bytes=*/std::nullopt, + /*in_progress_attachment_total_bytes=*/std::nullopt, + /*binding_id=*/""), + "TransferMetadata"}, + {TransferMetadata( + ShareSessionUsage::kPairing, + TransferMetadata::Status::kComplete, + /*progress=*/0.0f, + std::optional{"test_token"}, + /*is_original=*/false, + /*is_final_status=*/true, /*is_self_share=*/true, + /*transferred_bytes=*/0, /*transfer_speed=*/0, + /*estimated_time_remaining=*/0, + /*total_attachments_count=*/0, + /*transferred_attachments_count=*/0, + /*in_progress_attachment_id=*/std::nullopt, + /*in_progress_attachment_transferred_bytes=*/std::nullopt, + /*in_progress_attachment_total_bytes=*/std::nullopt, + /*binding_id=*/"test_binding_id"), + "TransferMetadata"}, }); return *kTransferMetadataToStringTestData; @@ -80,7 +124,7 @@ TEST_P(TransferMetadataToStringTest, ToStringResultMatches) { GetParam().transfer_metadata.ToString()); } -INSTANTIATE_TEST_CASE_P(TransferMetadataToStringTest, +INSTANTIATE_TEST_SUITE_P(TransferMetadataToStringTest, TransferMetadataToStringTest, testing::ValuesIn(GetTestData())); From 353f7d5a1d34bd6c2af638709a780eae25f6ee1a Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 6 May 2026 13:33:27 -0700 Subject: [PATCH 072/151] Remove dependency on multiplex sockets. PiperOrigin-RevId: 911520556 --- connections/implementation/mediums/BUILD | 1 - connections/implementation/mediums/awdl.cc | 8 -- connections/implementation/mediums/awdl.h | 4 - .../mediums/bluetooth_classic.cc | 116 +-------------- .../mediums/bluetooth_classic.h | 8 -- .../implementation/mediums/multiplex/BUILD | 1 + .../implementation/mediums/wifi_lan.cc | 134 +----------------- connections/implementation/mediums/wifi_lan.h | 8 -- 8 files changed, 3 insertions(+), 277 deletions(-) diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index beca2b4e..df6b27fe 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -58,7 +58,6 @@ cc_library( "//connections/implementation/mediums/ble:ble_advertisement_header", "//connections/implementation/mediums/ble:ble_socket", "//connections/implementation/mediums/ble:bloom_filter", - "//connections/implementation/mediums/multiplex", "//connections/implementation/mediums/webrtc", "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/flags:nearby_flags", diff --git a/connections/implementation/mediums/awdl.cc b/connections/implementation/mediums/awdl.cc index cf380fcb..81698ab3 100644 --- a/connections/implementation/mediums/awdl.cc +++ b/connections/implementation/mediums/awdl.cc @@ -15,7 +15,6 @@ #include "connections/implementation/mediums/awdl.h" #include -#include #include #include #include @@ -23,28 +22,21 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" -#include "connections/implementation/mediums/multiplex/multiplex_socket.h" #include "connections/implementation/mediums/utils.h" -#include "connections/medium_selector.h" #include "internal/platform/awdl.h" -#include "internal/platform/base64_utils.h" #include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" #include "internal/platform/expected.h" #include "internal/platform/implementation/psk_info.h" -#include "internal/platform/implementation/wifi_utils.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" #include "internal/platform/nsd_service_info.h" -#include "internal/platform/socket.h" -#include "internal/platform/types.h" namespace nearby { namespace connections { namespace { -using MultiplexSocket = mediums::multiplex::MultiplexSocket; using location::nearby::proto::connections::OperationResultCode; constexpr absl::string_view kAwdlServiceIdSuffixForServiceType = "_AWDL"; diff --git a/connections/implementation/mediums/awdl.h b/connections/implementation/mediums/awdl.h index b2a620d5..c6336946 100644 --- a/connections/implementation/mediums/awdl.h +++ b/connections/implementation/mediums/awdl.h @@ -24,12 +24,8 @@ #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/functional/any_invocable.h" -#include "connections/implementation/flags/nearby_connections_feature_flags.h" -#include "connections/implementation/mediums/multiplex/multiplex_socket.h" -#include "internal/flags/nearby_flags.h" #include "internal/platform/awdl.h" #include "internal/platform/cancellation_flag.h" -#include "internal/platform/exception.h" #include "internal/platform/expected.h" #include "internal/platform/implementation/psk_info.h" #include "internal/platform/multi_thread_executor.h" diff --git a/connections/implementation/mediums/bluetooth_classic.cc b/connections/implementation/mediums/bluetooth_classic.cc index 290defb5..2a971d8a 100644 --- a/connections/implementation/mediums/bluetooth_classic.cc +++ b/connections/implementation/mediums/bluetooth_classic.cc @@ -18,11 +18,7 @@ #include #include -#include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/mediums/bluetooth_radio.h" -#include "connections/implementation/mediums/multiplex/multiplex_socket.h" -#include "connections/medium_selector.h" -#include "internal/flags/nearby_flags.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_classic.h" #include "internal/platform/cancellation_flag.h" @@ -30,8 +26,6 @@ #include "internal/platform/logging.h" #include "internal/platform/mac_address.h" #include "internal/platform/mutex_lock.h" -#include "internal/platform/socket.h" -#include "internal/platform/types.h" #include "internal/platform/uuid.h" namespace nearby { @@ -54,8 +48,6 @@ std::string ScanModeToString(BluetoothAdapter::ScanMode mode) { } } // namespace -using MultiplexSocket = mediums::multiplex::MultiplexSocket; - BluetoothClassic::BluetoothClassic(BluetoothRadio& radio) : BluetoothClassic(radio, std::make_unique( radio.GetBluetoothAdapter())) {} @@ -74,20 +66,6 @@ BluetoothClassic::~BluetoothClassic() { } TurnOffDiscoverability(); - { - MutexLock lock(&mutex_); - LOG(INFO) << "Closing multiplex sockets for " << multiplex_sockets_.size() - << " devices"; - if (is_multiplex_enabled_) { - for (auto& [bt_mac, multiplex_socket] : multiplex_sockets_) { - LOG(INFO) << "Closing multiplex sockets for " - << GetRemoteDevice(bt_mac).GetName(); - multiplex_socket->Shutdown(); - } - } - multiplex_sockets_.clear(); - } - // All the AcceptLoopRunnable objects in here should already have gotten an // opportunity to shut themselves down cleanly in the calls to // StopAcceptingConnections() above. @@ -376,24 +354,13 @@ ErrorOr BluetoothClassic::StartAcceptingConnections( auto owned_socket = server_sockets_.emplace(service_id, std::move(socket)).first->second; - if (is_multiplex_enabled_) { - MultiplexSocket::ListenForIncomingConnection( - service_id, Medium::BLUETOOTH, - [&callback](const std::string& listening_service_id, - std::shared_ptr virtual_socket) mutable { - if (callback) { - callback(listening_service_id, - *(down_cast(virtual_socket.get()))); - } - }); - } // Start the accept loop on a dedicated thread - this stays alive and // listening for new incoming connections until StopAcceptingConnections() // is invoked. accept_loops_runner_.Execute("bt-accept", [callback = std::move(callback), server_socket = std::move(owned_socket), - service_id, this]() mutable { + service_id]() mutable { while (true) { BluetoothSocket client_socket = server_socket.Accept(); if (!client_socket.IsValid()) { @@ -403,35 +370,6 @@ ErrorOr BluetoothClassic::StartAcceptingConnections( } LOG(INFO) << "Accepted connection for " << service_id; bool callback_called = false; - { - MutexLock lock(&mutex_); - if (is_multiplex_enabled_) { - BluetoothSocket client_socket_bak = client_socket; - auto physical_socket_ptr = - std::make_shared(client_socket_bak); - MultiplexSocket* multiplex_socket = - MultiplexSocket::CreateIncomingSocket(physical_socket_ptr, - service_id, 0); - - if (multiplex_socket != nullptr) { - if (auto virtual_socket = - multiplex_socket->GetVirtualSocket(service_id)) { - multiplex_sockets_.emplace( - client_socket.GetRemoteDevice().GetAddress(), - multiplex_socket); - MultiplexSocket::StopListeningForIncomingConnection( - service_id, Medium::BLUETOOTH); - LOG(INFO) << "Multiplex virtaul socket created for " - << client_socket.GetRemoteDevice().GetName(); - if (callback) { - callback(service_id, *(down_cast( - virtual_socket.get()))); - callback_called = true; - } - } - } - } - } if (callback && !callback_called) { LOG(INFO) << "Call back triggered for physical socket."; callback(service_id, std::move(client_socket)); @@ -468,10 +406,6 @@ bool BluetoothClassic::StopAcceptingConnections(const std::string& service_id) { << " because it was never started."; return false; } - if (is_multiplex_enabled_) { - MultiplexSocket::StopListeningForIncomingConnection(service_id, - Medium::BLUETOOTH); - } // Closing the BluetoothServerSocket will kick off the suicide of the thread // in accept_loops_thread_pool_ that blocks on @@ -500,30 +434,6 @@ bool BluetoothClassic::StopAcceptingConnections(const std::string& service_id) { ErrorOr BluetoothClassic::Connect( BluetoothDevice& bluetooth_device, const std::string& service_id, CancellationFlag* cancellation_flag) { - { - MutexLock lock(&mutex_); - if (is_multiplex_enabled_) { - LOG(INFO) << "multiplex_sockets_ size:" << multiplex_sockets_.size(); - auto it = multiplex_sockets_.find(bluetooth_device.GetAddress()); - if (it != multiplex_sockets_.end()) { - MultiplexSocket* multiplex_socket = it->second; - if (multiplex_socket->IsEnabled()) { - std::shared_ptr virtual_socket = - multiplex_socket->EstablishVirtualSocket(service_id); - // Should not happen. - auto* bluetooth_socket = - down_cast(virtual_socket.get()); - if (bluetooth_socket == nullptr) { - LOG(INFO) << "Failed to cast to BluetoothSocket for " << service_id - << " with " << bluetooth_device.GetName(); - return {Error(OperationResultCode:: - NEARBY_BT_VIRTUAL_SOCKET_CREATION_FAILURE)}; - } - return *bluetooth_socket; - } - } - } - } service_id_to_connect_attempts_count_map_[service_id] = 1; while (service_id_to_connect_attempts_count_map_[service_id] <= kConnectAttemptsLimit) { @@ -599,30 +509,6 @@ ErrorOr BluetoothClassic::AttemptToConnect( return {Error( OperationResultCode::CONNECTIVITY_BT_CLIENT_SOCKET_CREATION_FAILURE)}; } - - if (is_multiplex_enabled_) { - // New MultiplexSocket but default disabled, should be enabled after - // negotiated - auto physical_socket_ptr = std::make_shared(socket); - MultiplexSocket* multiplex_socket = MultiplexSocket::CreateOutgoingSocket( - std::move(physical_socket_ptr), service_id); - - std::shared_ptr virtual_socket = - multiplex_socket->GetVirtualSocket(service_id); - - auto* bluetooth_socket = down_cast(virtual_socket.get()); - if (bluetooth_socket == nullptr) { - LOG(INFO) << "Failed to cast to BluetoothSocket for " << service_id - << " with " << bluetooth_device.GetName(); - return {Error( - OperationResultCode::NEARBY_BT_VIRTUAL_SOCKET_CREATION_FAILURE)}; - } - LOG(INFO) << "Multiplex socket created for " << bluetooth_device.GetName(); - multiplex_sockets_.emplace(bluetooth_device.GetAddress(), - multiplex_socket); - return *bluetooth_socket; - } - return socket; } diff --git a/connections/implementation/mediums/bluetooth_classic.h b/connections/implementation/mediums/bluetooth_classic.h index 984112da..37bf8bd3 100644 --- a/connections/implementation/mediums/bluetooth_classic.h +++ b/connections/implementation/mediums/bluetooth_classic.h @@ -23,7 +23,6 @@ #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" #include "connections/implementation/mediums/bluetooth_radio.h" -#include "connections/implementation/mediums/multiplex/multiplex_socket.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_classic.h" #include "internal/platform/cancellation_flag.h" @@ -232,13 +231,6 @@ class BluetoothClassic { mutable Mutex discovery_callbacks_mutex_; absl::flat_hash_map discovery_callbacks_ ABSL_GUARDED_BY(discovery_callbacks_mutex_); - - // Whether the multiplex feature is enabled. - bool is_multiplex_enabled_ = false; - - // A map of Bluetooth MacAddress -> MultiplexSocket. - absl::flat_hash_map - multiplex_sockets_ ABSL_GUARDED_BY(mutex_); }; } // namespace connections diff --git a/connections/implementation/mediums/multiplex/BUILD b/connections/implementation/mediums/multiplex/BUILD index fc1a59ff..63c05094 100644 --- a/connections/implementation/mediums/multiplex/BUILD +++ b/connections/implementation/mediums/multiplex/BUILD @@ -54,6 +54,7 @@ cc_test( "multiplex_output_stream_test.cc", "multiplex_socket_test.cc", ], + tags = ["notap"], deps = [ ":multiplex", "//connections/implementation:internal", diff --git a/connections/implementation/mediums/wifi_lan.cc b/connections/implementation/mediums/wifi_lan.cc index 9f30ea5d..51ae771a 100644 --- a/connections/implementation/mediums/wifi_lan.cc +++ b/connections/implementation/mediums/wifi_lan.cc @@ -15,36 +15,28 @@ #include "connections/implementation/mediums/wifi_lan.h" #include -#include #include #include #include #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" -#include "connections/implementation/mediums/multiplex/multiplex_socket.h" #include "connections/implementation/mediums/utils.h" -#include "connections/medium_selector.h" -#include "internal/platform/base64_utils.h" #include "internal/platform/byte_array.h" #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" #include "internal/platform/nsd_service_info.h" #include "internal/platform/service_address.h" -#include "internal/platform/socket.h" -#include "internal/platform/types.h" #include "internal/platform/wifi_lan.h" namespace nearby { namespace connections { namespace { -using MultiplexSocket = mediums::multiplex::MultiplexSocket; using location::nearby::proto::connections::OperationResultCode; } // namespace @@ -59,18 +51,6 @@ WifiLan::~WifiLan() { while (!advertising_info_.nsd_service_infos.empty()) { StopAdvertising(advertising_info_.nsd_service_infos.begin()->first); } - { - MutexLock lock(&mutex_); - if (is_multiplex_enabled_) { - LOG(INFO) << "Closing multiplex sockets for " << multiplex_sockets_.size() - << " IPs"; - for (auto& [ip_addr, multiplex_socket] : multiplex_sockets_) { - LOG(INFO) << "Closing multiplex sockets for: " << ip_addr; - multiplex_socket->~MultiplexSocket(); - } - multiplex_sockets_.clear(); - } - } // All the AcceptLoopRunnable objects in here should already have gotten an // opportunity to shut themselves down cleanly in the calls to // StopAcceptingConnections() above. @@ -265,18 +245,6 @@ ErrorOr WifiLan::StartAcceptingConnectionsLocked( server_sockets_.insert({service_id, std::move(server_socket)}) .first->second; - // Register the callback to listen for incoming multiplex virtual socket. - if (is_multiplex_enabled_) { - MultiplexSocket::ListenForIncomingConnection( - service_id, Medium::WIFI_LAN, - [&callback](const std::string& listening_service_id, - std::shared_ptr virtual_socket) mutable { - if (callback) { - callback(listening_service_id, - *(down_cast(virtual_socket.get()))); - } - }); - } port = owned_server_socket.GetPort(); // Start the accept loop on a dedicated thread - this stays alive and // listening for new incoming connections until StopAcceptingConnections() is @@ -284,7 +252,7 @@ ErrorOr WifiLan::StartAcceptingConnectionsLocked( accept_loops_runner_.Execute( "wifi-lan-accept", [callback = std::move(callback), server_socket = std::move(owned_server_socket), - service_id, this]() mutable { + service_id]() mutable { while (true) { WifiLanSocket client_socket = server_socket.Accept(); if (!client_socket.IsValid()) { @@ -293,54 +261,6 @@ ErrorOr WifiLan::StartAcceptingConnectionsLocked( } LOG(INFO) << "Accepted connection for " << service_id; bool callback_called = false; - { - MutexLock lock(&mutex_); - if (is_multiplex_enabled_) { - // Observed from the log that when the sender tries to connect to - // the receiver's server socket, the server side will somehow - // receive 3 connection request events(don’t know what’s happening - // in Windows’s lower layer code). The 2nd normally is the real - // one. The other two will result in a failed data receiving in - // Windows platform layer. To avoid creating multiplex - // IncomingSocket, we will check if the first read is successful - // or not. If not, discard it. If yes, save that packet - // content(the first frame length), then create the multiplex - // socket, then feed that content to that multiplex socket. - ExceptionOr read_int = - Base64Utils::ReadInt(&client_socket.GetInputStream()); - if (!read_int.ok()) { - LOG(WARNING) - << __func__ - << "Failed to read. Exception:" << read_int.exception() - << "Discard the connection."; - continue; - } - WifiLanSocket client_socket_bak = client_socket; - auto physical_socket_ptr = - std::make_shared(client_socket_bak); - - MultiplexSocket* multiplex_socket = - MultiplexSocket::CreateIncomingSocket( - physical_socket_ptr, service_id, read_int.result()); - if (multiplex_socket != nullptr) { - std::shared_ptr virtual_socket = - multiplex_socket->GetVirtualSocket(service_id); - if (virtual_socket) { - multiplex_sockets_.emplace(server_socket.GetIPAddress(), - multiplex_socket); - MultiplexSocket::StopListeningForIncomingConnection( - service_id, Medium::WIFI_LAN); - LOG(INFO) << "Multiplex virtaul socket created for " - << server_socket.GetIPAddress(); - if (callback) { - callback(service_id, *(down_cast( - virtual_socket.get()))); - callback_called = true; - } - } - } - } - } if (callback && !callback_called) { LOG(INFO) << "Call back triggered for physical socket."; callback(service_id, std::move(client_socket)); @@ -403,10 +323,6 @@ bool WifiLan::StopAcceptingConnectionsLocked(const std::string& service_id) { << " because it was never started."; return false; } - if (is_multiplex_enabled_) { - MultiplexSocket::StopListeningForIncomingConnection(service_id, - Medium::WIFI_LAN); - } // Closing the WifiLanServerSocket will kick off the suicide of the thread // in accept_loops_thread_pool_ that blocks on WifiLanServerSocket.accept(). @@ -556,60 +472,12 @@ ErrorOr WifiLan::Connect(const std::string& service_id, ExceptionOr WifiLan::ConnectWithMultiplexSocketLocked( const std::string& service_id, const std::string& ip_address) { - if (is_multiplex_enabled_) { - LOG(INFO) << "multiplex_sockets_ size:" << multiplex_sockets_.size(); - auto it = multiplex_sockets_.find(ip_address); - if (it != multiplex_sockets_.end()) { - MultiplexSocket* multiplex_socket = it->second; - if (multiplex_socket->IsShutdown()) { - LOG(INFO) << "Erase multiplex_socket(already shutdown) for ip_address: " - << WifiUtils::GetHumanReadableIpAddress(ip_address); - multiplex_socket->~MultiplexSocket(); - multiplex_sockets_.erase(it); - return ExceptionOr(Exception::kFailed); - } - if (multiplex_socket->IsEnabled()) { - std::shared_ptr virtual_socket = - multiplex_socket->EstablishVirtualSocket(service_id); - // Should not happen. - auto* wlan_socket = down_cast(virtual_socket.get()); - if (wlan_socket == nullptr) { - LOG(INFO) << "Failed to cast to WifiLanSocket for " << service_id - << " with ip_address: " - << WifiUtils::GetHumanReadableIpAddress(ip_address); - return ExceptionOr(Exception::kFailed); - } - return ExceptionOr(*wlan_socket); - } - } - } return ExceptionOr(Exception::kFailed); } ExceptionOr WifiLan::CreateOutgoingMultiplexSocketLocked( WifiLanSocket& socket, const std::string& service_id, const std::string& ip_address) { - if (is_multiplex_enabled_) { - // Create MultiplexSocket, but set it to be disabled as default. It will be - // enabled if both side support multiplex for WIFI_LAN - auto physical_socket_ptr = std::make_shared(socket); - MultiplexSocket* multiplex_socket = - MultiplexSocket::CreateOutgoingSocket(physical_socket_ptr, service_id); - - std::shared_ptr virtual_socket = - multiplex_socket->GetVirtualSocket(service_id); - auto* wlan_socket = down_cast(virtual_socket.get()); - if (wlan_socket == nullptr) { - LOG(INFO) << "Failed to cast to WifiLanSocket for " << service_id - << " with ip_address: " - << WifiUtils::GetHumanReadableIpAddress(ip_address); - return ExceptionOr(Exception::kFailed); - } - LOG(INFO) << "Multiplex socket created for ip_address: " - << WifiUtils::GetHumanReadableIpAddress(ip_address); - multiplex_sockets_.emplace(ip_address, multiplex_socket); - return ExceptionOr(*wlan_socket); - } return ExceptionOr(Exception::kFailed); } diff --git a/connections/implementation/mediums/wifi_lan.h b/connections/implementation/mediums/wifi_lan.h index 0307806f..39a5cc6a 100644 --- a/connections/implementation/mediums/wifi_lan.h +++ b/connections/implementation/mediums/wifi_lan.h @@ -23,7 +23,6 @@ #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/functional/any_invocable.h" -#include "connections/implementation/mediums/multiplex/multiplex_socket.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" #include "internal/platform/expected.h" @@ -215,13 +214,6 @@ class WifiLan { absl::flat_hash_map server_sockets_ ABSL_GUARDED_BY(mutex_); - // Whether the multiplex feature is enabled. - bool is_multiplex_enabled_ = false; - - // A map of IpAddress -> MultiplexSocket. - absl::flat_hash_map - multiplex_sockets_ ABSL_GUARDED_BY(mutex_); - std::string last_mdns_service_name_ ABSL_GUARDED_BY(mutex_); int last_server_port_ ABSL_GUARDED_BY(mutex_) = 0; }; From 6b2f1b96eb26111e825375adfcc8077cad31ca4a Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 6 May 2026 13:52:54 -0700 Subject: [PATCH 073/151] remove unused code. PiperOrigin-RevId: 911531448 --- .github/workflows/validate.yaml | 12 - internal/interop/BUILD | 6 +- internal/platform/BUILD | 10 +- internal/platform/implementation/BUILD | 6 +- internal/platform/implementation/g3/BUILD | 2 +- .../platform/implementation/windows/BUILD | 2 +- presence/BUILD | 223 ----- presence/broadcast_options.h | 36 - presence/broadcast_options_test.cc | 53 -- presence/broadcast_request.h | 77 -- presence/credential_test.cc | 79 -- presence/data_element.h | 111 --- presence/data_types.h | 64 -- presence/device_motion.cc | 28 - presence/device_motion.h | 47 - presence/device_motion_test.cc | 61 -- presence/discovery_filter.cc | 36 - presence/discovery_filter.h | 43 - presence/discovery_filter_test.cc | 51 -- presence/discovery_options.h | 34 - presence/discovery_options_test.cc | 51 -- presence/fake_presence_client.cc | 67 -- presence/fake_presence_client.h | 73 -- presence/fake_presence_service.cc | 107 --- presence/fake_presence_service.h | 122 --- presence/fpp/BUILD | 93 -- presence/fpp/fpp/Cargo.lock | 25 - presence/fpp/fpp/Cargo.toml | 9 - presence/fpp/fpp/src/fspl_converter.rs | 37 - presence/fpp/fpp/src/fspl_converter_test.rs | 30 - presence/fpp/fpp/src/fused_presence_utils.rs | 107 --- presence/fpp/fpp/src/lib.rs | 37 - presence/fpp/fpp/src/presence_detector.rs | 131 --- .../fpp/fpp/src/presence_detector_test.rs | 105 --- presence/fpp/fpp_c_ffi/Cargo.lock | 105 --- presence/fpp/fpp_c_ffi/Cargo.toml | 11 - .../fpp/fpp_c_ffi/include/presence_detector.h | 148 ---- presence/fpp/fpp_c_ffi/src/handle_map.rs | 72 -- presence/fpp/fpp_c_ffi/src/lib.rs | 141 --- presence/fpp/fpp_manager.cc | 168 ---- presence/fpp/fpp_manager.h | 86 -- presence/fpp/fpp_manager_test.cc | 243 ----- presence/fpp/sensor_fusion_impl.cc | 68 -- presence/fpp/sensor_fusion_impl.h | 51 -- presence/fpp/sensor_fusion_test.cc | 110 --- presence/implementation/BUILD | 493 ----------- presence/implementation/action_factory.cc | 106 --- presence/implementation/action_factory.h | 45 - .../implementation/action_factory_test.cc | 107 --- .../implementation/advertisement_decoder.h | 59 -- .../advertisement_decoder_impl.cc | 287 ------ .../advertisement_decoder_impl.h | 51 -- .../advertisement_decoder_new_format_test.cc | 156 ---- .../advertisement_decoder_rust_impl.cc | 241 ----- .../advertisement_decoder_rust_impl.h | 61 -- .../advertisement_decoder_test.cc | 226 ----- .../implementation/advertisement_factory.cc | 236 ----- .../implementation/advertisement_factory.h | 63 -- .../advertisement_factory_test.cc | 148 ---- .../implementation/advertisement_filter.cc | 119 --- .../implementation/advertisement_filter.h | 46 - .../advertisement_filter_test.cc | 174 ---- .../implementation/base_broadcast_request.cc | 112 --- .../implementation/base_broadcast_request.h | 102 --- .../base_broadcast_request_test.cc | 94 -- presence/implementation/broadcast_manager.cc | 269 ------ presence/implementation/broadcast_manager.h | 109 --- .../implementation/broadcast_manager_test.cc | 177 ---- .../implementation/connection_authenticator.h | 103 --- .../connection_authenticator_impl.cc | 197 ----- .../connection_authenticator_impl.h | 85 -- .../connection_authenticator_impl_test.cc | 272 ------ presence/implementation/credential_manager.h | 115 --- .../implementation/credential_manager_impl.cc | 834 ------------------ .../implementation/credential_manager_impl.h | 262 ------ .../credential_manager_impl_test.cc | 721 --------------- presence/implementation/ldt.cc | 109 --- presence/implementation/ldt.h | 76 -- presence/implementation/ldt_stub.c | 47 - presence/implementation/ldt_test.cc | 98 -- presence/implementation/mediums/BUILD | 70 -- .../mediums/advertisement_data.h | 34 - presence/implementation/mediums/ble.h | 111 --- presence/implementation/mediums/ble_test.cc | 177 ---- presence/implementation/mediums/mediums.h | 41 - .../mock_connection_authenticator.h | 63 -- .../implementation/mock_credential_manager.h | 86 -- .../implementation/mock_service_controller.h | 82 -- presence/implementation/np_ldt.h | 125 --- presence/implementation/scan_manager.cc | 280 ------ presence/implementation/scan_manager.h | 109 --- presence/implementation/scan_manager_test.cc | 453 ---------- presence/implementation/sensor_fusion.h | 153 ---- presence/implementation/service_controller.h | 76 -- .../implementation/service_controller_impl.cc | 91 -- .../implementation/service_controller_impl.h | 110 --- .../service_controller_impl_test.cc | 102 --- presence/power_mode.h | 35 - presence/presence_action.cc | 31 - presence/presence_action.h | 41 - presence/presence_action_test.cc | 59 -- presence/presence_client.h | 85 -- presence/presence_client_impl.cc | 98 -- presence/presence_client_impl.h | 75 -- presence/presence_client_test.cc | 151 ---- presence/presence_device.cc | 172 ---- presence/presence_device.h | 129 --- presence/presence_device_provider.cc | 261 ------ presence/presence_device_provider.h | 94 -- presence/presence_device_provider_test.cc | 296 ------- presence/presence_device_test.cc | 201 ----- presence/presence_identity_test.cc | 44 - presence/presence_service.h | 72 -- presence/presence_service_impl.cc | 83 -- presence/presence_service_impl.h | 109 --- presence/presence_service_test.cc | 152 ---- presence/presence_zone.cc | 82 -- presence/presence_zone.h | 108 --- presence/presence_zone_test.cc | 221 ----- presence/proto/BUILD | 29 - presence/proto/presence_frame.proto | 205 ----- presence/rust/README | 1 - presence/scan_request.h | 151 ---- presence/scan_request_builder.cc | 89 -- presence/scan_request_builder.h | 56 -- presence/scan_request_builder_test.cc | 194 ---- 126 files changed, 13 insertions(+), 15052 deletions(-) delete mode 100644 presence/BUILD delete mode 100644 presence/broadcast_options.h delete mode 100644 presence/broadcast_options_test.cc delete mode 100644 presence/broadcast_request.h delete mode 100644 presence/credential_test.cc delete mode 100644 presence/data_element.h delete mode 100644 presence/data_types.h delete mode 100644 presence/device_motion.cc delete mode 100644 presence/device_motion.h delete mode 100644 presence/device_motion_test.cc delete mode 100644 presence/discovery_filter.cc delete mode 100644 presence/discovery_filter.h delete mode 100644 presence/discovery_filter_test.cc delete mode 100644 presence/discovery_options.h delete mode 100644 presence/discovery_options_test.cc delete mode 100644 presence/fake_presence_client.cc delete mode 100644 presence/fake_presence_client.h delete mode 100644 presence/fake_presence_service.cc delete mode 100644 presence/fake_presence_service.h delete mode 100644 presence/fpp/BUILD delete mode 100644 presence/fpp/fpp/Cargo.lock delete mode 100644 presence/fpp/fpp/Cargo.toml delete mode 100644 presence/fpp/fpp/src/fspl_converter.rs delete mode 100644 presence/fpp/fpp/src/fspl_converter_test.rs delete mode 100644 presence/fpp/fpp/src/fused_presence_utils.rs delete mode 100644 presence/fpp/fpp/src/lib.rs delete mode 100644 presence/fpp/fpp/src/presence_detector.rs delete mode 100644 presence/fpp/fpp/src/presence_detector_test.rs delete mode 100644 presence/fpp/fpp_c_ffi/Cargo.lock delete mode 100644 presence/fpp/fpp_c_ffi/Cargo.toml delete mode 100644 presence/fpp/fpp_c_ffi/include/presence_detector.h delete mode 100644 presence/fpp/fpp_c_ffi/src/handle_map.rs delete mode 100644 presence/fpp/fpp_c_ffi/src/lib.rs delete mode 100644 presence/fpp/fpp_manager.cc delete mode 100644 presence/fpp/fpp_manager.h delete mode 100644 presence/fpp/fpp_manager_test.cc delete mode 100644 presence/fpp/sensor_fusion_impl.cc delete mode 100644 presence/fpp/sensor_fusion_impl.h delete mode 100644 presence/fpp/sensor_fusion_test.cc delete mode 100644 presence/implementation/BUILD delete mode 100644 presence/implementation/action_factory.cc delete mode 100644 presence/implementation/action_factory.h delete mode 100644 presence/implementation/action_factory_test.cc delete mode 100644 presence/implementation/advertisement_decoder.h delete mode 100644 presence/implementation/advertisement_decoder_impl.cc delete mode 100644 presence/implementation/advertisement_decoder_impl.h delete mode 100644 presence/implementation/advertisement_decoder_new_format_test.cc delete mode 100644 presence/implementation/advertisement_decoder_rust_impl.cc delete mode 100644 presence/implementation/advertisement_decoder_rust_impl.h delete mode 100644 presence/implementation/advertisement_decoder_test.cc delete mode 100644 presence/implementation/advertisement_factory.cc delete mode 100644 presence/implementation/advertisement_factory.h delete mode 100644 presence/implementation/advertisement_factory_test.cc delete mode 100644 presence/implementation/advertisement_filter.cc delete mode 100644 presence/implementation/advertisement_filter.h delete mode 100644 presence/implementation/advertisement_filter_test.cc delete mode 100644 presence/implementation/base_broadcast_request.cc delete mode 100644 presence/implementation/base_broadcast_request.h delete mode 100644 presence/implementation/base_broadcast_request_test.cc delete mode 100644 presence/implementation/broadcast_manager.cc delete mode 100644 presence/implementation/broadcast_manager.h delete mode 100644 presence/implementation/broadcast_manager_test.cc delete mode 100644 presence/implementation/connection_authenticator.h delete mode 100644 presence/implementation/connection_authenticator_impl.cc delete mode 100644 presence/implementation/connection_authenticator_impl.h delete mode 100644 presence/implementation/connection_authenticator_impl_test.cc delete mode 100644 presence/implementation/credential_manager.h delete mode 100644 presence/implementation/credential_manager_impl.cc delete mode 100644 presence/implementation/credential_manager_impl.h delete mode 100644 presence/implementation/credential_manager_impl_test.cc delete mode 100644 presence/implementation/ldt.cc delete mode 100644 presence/implementation/ldt.h delete mode 100644 presence/implementation/ldt_stub.c delete mode 100644 presence/implementation/ldt_test.cc delete mode 100644 presence/implementation/mediums/BUILD delete mode 100644 presence/implementation/mediums/advertisement_data.h delete mode 100644 presence/implementation/mediums/ble.h delete mode 100644 presence/implementation/mediums/ble_test.cc delete mode 100644 presence/implementation/mediums/mediums.h delete mode 100644 presence/implementation/mock_connection_authenticator.h delete mode 100644 presence/implementation/mock_credential_manager.h delete mode 100644 presence/implementation/mock_service_controller.h delete mode 100644 presence/implementation/np_ldt.h delete mode 100644 presence/implementation/scan_manager.cc delete mode 100644 presence/implementation/scan_manager.h delete mode 100644 presence/implementation/scan_manager_test.cc delete mode 100644 presence/implementation/sensor_fusion.h delete mode 100644 presence/implementation/service_controller.h delete mode 100644 presence/implementation/service_controller_impl.cc delete mode 100644 presence/implementation/service_controller_impl.h delete mode 100644 presence/implementation/service_controller_impl_test.cc delete mode 100644 presence/power_mode.h delete mode 100644 presence/presence_action.cc delete mode 100644 presence/presence_action.h delete mode 100644 presence/presence_action_test.cc delete mode 100644 presence/presence_client.h delete mode 100644 presence/presence_client_impl.cc delete mode 100644 presence/presence_client_impl.h delete mode 100644 presence/presence_client_test.cc delete mode 100644 presence/presence_device.cc delete mode 100644 presence/presence_device.h delete mode 100644 presence/presence_device_provider.cc delete mode 100644 presence/presence_device_provider.h delete mode 100644 presence/presence_device_provider_test.cc delete mode 100644 presence/presence_device_test.cc delete mode 100644 presence/presence_identity_test.cc delete mode 100644 presence/presence_service.h delete mode 100644 presence/presence_service_impl.cc delete mode 100644 presence/presence_service_impl.h delete mode 100644 presence/presence_service_test.cc delete mode 100644 presence/presence_zone.cc delete mode 100644 presence/presence_zone.h delete mode 100644 presence/presence_zone_test.cc delete mode 100644 presence/proto/BUILD delete mode 100644 presence/proto/presence_frame.proto delete mode 100644 presence/rust/README delete mode 100644 presence/scan_request.h delete mode 100644 presence/scan_request_builder.cc delete mode 100644 presence/scan_request_builder.h delete mode 100644 presence/scan_request_builder_test.cc diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 7d7d8621..3c84c33d 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -48,15 +48,3 @@ jobs: - uses: actions/checkout@v6 - name: Build Connections run: CC=clang-18 CXX=clang-18++ BAZEL_CXXOPTS="-std=c++20" bazel build --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc=true --copt='-DGITHUB_BUILD' //connections:core -# - name: Build Presence -# run: CC=clang-18 CXX=clang-18++ BAZEL_CXXOPTS="-std=c++20" bazel build --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc=true --copt='-DGITHUB_BUILD' //presence - - build-rust-linux: - name: Build Rust on Linux - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - name: Build FPP - run: cargo build --manifest-path presence/fpp/fpp/Cargo.toml diff --git a/internal/interop/BUILD b/internal/interop/BUILD index ee6deda7..f90f8936 100644 --- a/internal/interop/BUILD +++ b/internal/interop/BUILD @@ -35,7 +35,7 @@ cc_library( ], visibility = [ "//connections:__subpackages__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":authentication_status", @@ -54,8 +54,8 @@ cc_library( ], visibility = [ "//connections:__subpackages__", - "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], ) @@ -70,7 +70,7 @@ cc_library( ], compatible_with = ["//buildenv/target:non_prod"], visibility = [ - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":authentication_status", diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 77fc1061..d077fda5 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -164,7 +164,7 @@ cc_library( visibility = [ "//connections/implementation:__subpackages__", "//internal/platform/implementation:__subpackages__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":base", @@ -191,7 +191,7 @@ cc_library( "//connections/implementation:__pkg__", "//connections/v3:__pkg__", "//internal/interop:__pkg__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":logging", @@ -293,7 +293,7 @@ cc_library( "//connections:__subpackages__", "//internal/platform/implementation:__subpackages__", "//internal/test:__subpackages__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":base", @@ -349,7 +349,7 @@ cc_library( "//connections:__subpackages__", "//internal/platform/implementation:__subpackages__", "//internal/test:__subpackages__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":base", @@ -404,7 +404,7 @@ cc_library( visibility = [ "//connections:__subpackages__", "//internal/platform/implementation:__subpackages__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":base", diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 225e78c7..b1d9877e 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -49,8 +49,8 @@ cc_library( "//internal/test:__subpackages__", "//location/nearby/analytics/cpp:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", - "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ "//internal/base:file_path", @@ -112,8 +112,8 @@ cc_library( "//internal/network:__subpackages__", "//internal/platform:__pkg__", "//internal/platform/implementation:__subpackages__", - "//presence:__subpackages__", - "//presence/implementation:__subpackages__", + "//third_party/nearby/presence:__subpackages__", + "//third_party/nearby/presence/implementation:__subpackages__", ], deps = [ "//connections/implementation/proto:offline_wire_formats_cc_proto", diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index 4aa9171c..4fee0569 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -193,8 +193,8 @@ cc_library( "//internal/weave:__subpackages__", "//location/nearby/cpp:__subpackages__", "//location/nearby/sharing/sdk:__subpackages__", - "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":comm", diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 0ba7f3dd..b7e93a57 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -328,8 +328,8 @@ cc_library( "//connections:partners", "//internal/platform:__subpackages__", "//location/nearby:__subpackages__", - "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":crypto", # build_cleaner: keep diff --git a/presence/BUILD b/presence/BUILD deleted file mode 100644 index 858a5ec9..00000000 --- a/presence/BUILD +++ /dev/null @@ -1,223 +0,0 @@ -# Copyright 2020 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. - -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -package(default_visibility = ["//:__subpackages__"]) - -licenses(["notice"]) - -cc_library( - name = "presence", - srcs = [ - "presence_client_impl.cc", - "presence_device_provider.cc", - "presence_service_impl.cc", - ], - hdrs = [ - "presence_client.h", - "presence_client_impl.h", - "presence_device_provider.h", - "presence_service.h", - "presence_service_impl.h", - ], - deps = [ - ":types", - "//internal/interop:authentication_status", - "//internal/interop:authentication_transport_interface", - "//internal/interop:device", - "//internal/platform:base", - "//internal/platform:logging", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:local_credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "//presence/implementation:internal", # build_cleaner: keep - "//presence/implementation/mediums", - "//presence/proto:presence_frame_cc_proto", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings:string_view", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:variant", - ], -) - -cc_library( - name = "test_support", - testonly = 1, - srcs = [ - "fake_presence_client.cc", - "fake_presence_service.cc", - ], - hdrs = [ - "fake_presence_client.h", - "fake_presence_service.h", - ], - deps = [ - ":presence", - ":types", - "//internal/interop:device", - "//internal/interop:test_support", - "//internal/platform:types", - "//internal/proto:metadata_cc_proto", - "//presence/implementation:internal", # build_cleaner: keep - "@com_google_absl//absl/status:statusor", - ], -) - -cc_library( - name = "types", - srcs = [ - "device_motion.cc", - "discovery_filter.cc", - "presence_action.cc", - "presence_device.cc", - "presence_zone.cc", - "scan_request_builder.cc", - ], - hdrs = [ - "broadcast_options.h", - "broadcast_request.h", - "data_element.h", - "data_types.h", - "device_motion.h", - "discovery_filter.h", - "discovery_options.h", - "power_mode.h", - "presence_action.h", - "presence_device.h", - "presence_zone.h", - "scan_request.h", - "scan_request_builder.h", - ], - deps = [ - "//connections/implementation/proto:offline_wire_formats_cc_proto", - "//internal/interop:device", - "//internal/platform:base", - "//internal/platform:connection_info", - "//internal/platform:logging", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:variant", - ], -) - -cc_test( - name = "types_test", - size = "small", - srcs = [ - "broadcast_options_test.cc", - "device_motion_test.cc", - "discovery_filter_test.cc", - "discovery_options_test.cc", - "presence_action_test.cc", - "presence_device_test.cc", - "presence_identity_test.cc", - "presence_zone_test.cc", - "scan_request_builder_test.cc", - ], - shard_count = 6, - deps = [ - ":types", - "//connections/implementation/proto:offline_wire_formats_cc_proto", - "//internal/platform:connection_info", - "//internal/platform:types", - "//internal/proto:credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/types:variant", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "credential_test", - size = "small", - srcs = [ - "credential_test.cc", - "presence_identity_test.cc", - ], - shard_count = 6, - deps = [ - "//internal/platform:uuid", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "presence_test", - size = "small", - srcs = [ - "presence_client_test.cc", - "presence_device_provider_test.cc", - "presence_service_test.cc", - ], - shard_count = 6, - deps = [ - ":presence", - ":types", - "//internal/crypto", - "//internal/interop:authentication_status", - "//internal/interop:authentication_transport_interface", - "//internal/interop:device", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "//presence/implementation:internal", - "//presence/implementation:internal_test", - "//presence/proto:presence_frame_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) diff --git a/presence/broadcast_options.h b/presence/broadcast_options.h deleted file mode 100644 index 18d11440..00000000 --- a/presence/broadcast_options.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2020 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_PRESENCE_BROADCAST_OPTIONS_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_OPTIONS_H_ - -#include -namespace nearby { -namespace presence { -struct BroadcastOptions { - const std::int64_t reporting_interval_millis; -}; - -inline bool operator==(const BroadcastOptions& o1, const BroadcastOptions& o2) { - return o1.reporting_interval_millis == o2.reporting_interval_millis; -} - -inline bool operator!=(const BroadcastOptions& o1, const BroadcastOptions& o2) { - return !(o1 == o2); -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_OPTIONS_H_ diff --git a/presence/broadcast_options_test.cc b/presence/broadcast_options_test.cc deleted file mode 100644 index e2e5c381..00000000 --- a/presence/broadcast_options_test.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2020 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. - -#include "presence/broadcast_options.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace presence { -namespace { - -constexpr std::int64_t kReportingIntervalMillis1 = 1000; -constexpr std::int64_t kReportingIntervalMillis2 = 2000; -TEST(BroadcastOptionsTest, NoDefaultConstructor) { - EXPECT_FALSE(std::is_trivially_constructible::value); -} - -TEST(BroadcastOptionsTest, ExplicitInitEquals) { - BroadcastOptions option1 = {kReportingIntervalMillis1}; - BroadcastOptions option2 = {kReportingIntervalMillis1}; - EXPECT_EQ(option1, option2); - EXPECT_EQ(option1.reporting_interval_millis, kReportingIntervalMillis1); -} - -TEST(BroadcastOptionsTest, ExplicitInitNotEquals) { - BroadcastOptions option1 = {kReportingIntervalMillis1}; - BroadcastOptions option2 = {kReportingIntervalMillis2}; - EXPECT_NE(option1, option2); -} - -TEST(BroadcastOptionsTest, CopyInitEquals) { - BroadcastOptions option1 = {kReportingIntervalMillis1}; - BroadcastOptions option2 = {option1}; - - EXPECT_EQ(option1, option2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/broadcast_request.h b/presence/broadcast_request.h deleted file mode 100644 index 598ffdf3..00000000 --- a/presence/broadcast_request.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2022 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_PRESENCE_BROADCAST_REQUEST_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_REQUEST_H_ - -#include -#include - -#include "absl/types/variant.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/power_mode.h" - -namespace nearby { -namespace presence { - -// Broadcast parameter for presence features. -struct PresenceBroadcast { - struct BroadcastSection { - // Presence identity type. - ::nearby::internal::IdentityType identity = - ::nearby::internal::IdentityType::IDENTITY_TYPE_UNSPECIFIED; - - // Additional Data Elements. - // The Presence SDK generates: - // - Salt, - // - (Private/Trusted/Public/Provisioned) Identity, - // - TX power, - // - Advertisement signature - // Data Elements when they are required in the advertisement. Other Data - // Elements are provided by the client application. - // Nearby SDK encrypts Data ELements before broadcasting if a non-public - // `PresenceIdentity` is provided. - std::vector extended_properties; - - // Account name used to select private credentials. - std::string account_name; - - // Manager app id, used to select private credentials. - std::string manager_app_id; - }; - - std::vector sections; -}; - -// Broadcast request for legacy Android T, which needs to provide credential -// and salt in the broadcast parameters. -// TODO(b/243443813) - Support Legacy Broadcast Request -struct LegacyPresenceBroadcast {}; - -// Nearby Presence advertisement request options. -struct BroadcastRequest { - // Calibrated TX power. The broadcast recipient uses it to calculate the - // distance between both devices. - int tx_power; - - // The broadcast frequency hint. - PowerMode power_mode; - - absl::variant variant; -}; - -} // namespace presence -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_REQUEST_H_ diff --git a/presence/credential_test.cc b/presence/credential_test.cc deleted file mode 100644 index 8b1ba211..00000000 --- a/presence/credential_test.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2020 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. - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "internal/platform/uuid.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" - -namespace nearby { -namespace presence { -namespace { -using ::nearby::internal::LocalCredential; -using ::nearby::internal::SharedCredential; -using ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; - -using ::protobuf_matchers::EqualsProto; - -TEST(CredentialsTest, NoDefaultConstructor) { - EXPECT_FALSE(std::is_trivially_constructible::value); - EXPECT_FALSE(std::is_trivially_constructible::value); -} - -TEST(CredentialsTest, InitSharedCredential) { - SharedCredential pc1 = {}; - SharedCredential pc2 = {}; - EXPECT_THAT(pc1, EqualsProto(pc2)); - pc1.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_THAT(pc1, ::testing::Not(EqualsProto(pc2))); - pc2.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_THAT(pc1, EqualsProto(pc2)); -} - -TEST(CredentialsTest, InitLocalCredential) { - LocalCredential pc1 = {}; - LocalCredential pc2 = {}; - EXPECT_THAT(pc1, EqualsProto(pc2)); - pc1.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_THAT(pc1, ::testing::Not(EqualsProto(pc2))); - pc2.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_THAT(pc1, EqualsProto(pc2)); -} - -TEST(CredentialsTest, CopyLocalCredential) { - LocalCredential pc1 = {}; - pc1.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - auto salts = pc1.mutable_consumed_salts(); - salts->insert(std::pair(15, true)); - LocalCredential pc1_copy = {pc1}; - EXPECT_THAT(pc1, EqualsProto(pc1_copy)); -} - -TEST(CredentialsTest, CopySharedCredential) { - SharedCredential pc1 = {}; - pc1.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - for (const uint8_t byte : nearby::Uuid().data()) { - pc1.mutable_secret_id()->push_back(byte); - } - SharedCredential pc1_copy = {pc1}; - EXPECT_THAT(pc1, EqualsProto(pc1_copy)); -} -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/data_element.h b/presence/data_element.h deleted file mode 100644 index eb2ffebb..00000000 --- a/presence/data_element.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2022 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_PRESENCE_DATA_ELEMENT_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_DATA_ELEMENT_H_ - -#include - -#include -#include -#include - -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -namespace nearby { -namespace presence { - -// Reserved Action types when the field type is kActionFieldType. -// The values are bit numbers in BE ordering. -// TODO(b/338107166): these are out of date, need to be updated to latest spec -enum class ActionBit { - kCallTransferAction = 4, - kActiveUnlockAction = 8, - kNearbyShareAction = 9, - kInstantTetheringAction = 10, - kPhoneHubAction = 11, - kPresenceManagerAction = 12, - kFinderAction = 13, - kFastPairSassAction = 14, - kTapToTransferAction = 15, - kLastAction -}; - -// helpful for enumerating overall all possible action bit types, this must be -// kept in sync with the above enum -constexpr std::initializer_list kAllActionBits = { - ActionBit::kCallTransferAction, ActionBit::kActiveUnlockAction, - ActionBit::kNearbyShareAction, ActionBit::kInstantTetheringAction, - ActionBit::kPhoneHubAction, ActionBit::kPresenceManagerAction, - ActionBit::kFinderAction, ActionBit::kFastPairSassAction, - ActionBit::kTapToTransferAction}; - -/** Describes a custom Data element in NP advertisement. */ -class DataElement { - public: - // The field types listed below require special processing when generating and - // parsing NP advertisements. - static constexpr int kSaltFieldType = 0; - static constexpr int kPrivateGroupIdentityFieldType = 1; - static constexpr int kContactsGroupIdentityFieldType = 2; - static constexpr int kPublicIdentityFieldType = 3; - static constexpr int kTxPowerFieldType = 5; - static constexpr int kActionFieldType = 6; - static constexpr int kModelIdFieldType = 7; - static constexpr int kEddystoneIdFieldType = 8; - static constexpr int kAccountKeyDataFieldType = 9; - static constexpr int kConnectionStatusFieldType = 10; - static constexpr int kBatteryFieldType = 11; - static constexpr int kAdvertisementSignature = 12; - static constexpr int kContextTimestampFieldType = 13; - // Maximum allowed Data Element's value length - static constexpr int kMaxDataElementLength = 15; - // Maximum allowed Data Element's type - static constexpr int kMaxDataElementType = 15; - // The DE header is (length << kDataElementLengthShift | type) - static constexpr int kDataElementLengthShift = 4; - - DataElement(uint16_t type, absl::string_view value) - : type_(type), value_(value) {} - - DataElement(uint16_t type, uint8_t value) - : type_(type), - value_(reinterpret_cast(&value), sizeof(value)) {} - - explicit DataElement(ActionBit action) - : DataElement(kActionFieldType, static_cast(action)) {} - - ~DataElement() = default; - - uint16_t GetType() const { return type_; } - absl::string_view GetValue() const { return value_; } - - private: - uint16_t type_; - std::string value_; -}; - -inline bool operator==(const DataElement& i1, const DataElement& i2) { - return i1.GetType() == i2.GetType() && i1.GetValue() == i2.GetValue(); -} - -inline std::ostream& operator<<(std::ostream& os, const DataElement& elem) { - return os << "DataElement(" << elem.GetType() << ", " - << absl::BytesToHexString(elem.GetValue()) << ")"; -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_DATA_ELEMENT_H_ diff --git a/presence/data_types.h b/presence/data_types.h deleted file mode 100644 index 48fdde74..00000000 --- a/presence/data_types.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2020 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_PRESENCE_SCAN_CALLBACK_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_SCAN_CALLBACK_H_ - -#include - -#include "absl/functional/any_invocable.h" -#include "internal/platform/logging.h" -#include "presence/presence_device.h" - -namespace nearby { -namespace presence { - -// Unique Scan Session Identifier. -using ScanSessionId = uint64_t; - -// Callers would provide the implementation of these callbacks. If callers -// don't need these signal updates, they can skip with the provided default -// empty functions. -struct ScanCallback { - // Updates client with the result of start scanning. - absl::AnyInvocable start_scan_cb = [](absl::Status) {}; - - // Reports a {@link PresenceDevice} being discovered. - absl::AnyInvocable on_discovered_cb = - [](PresenceDevice) {}; - - // Reports a {@link PresenceDevice} information(distance, and etc) - // changed. - absl::AnyInvocable on_updated_cb = [](PresenceDevice) { - }; - - // Reports a {@link PresenceDevice} is no longer within range. - absl::AnyInvocable on_lost_cb = [](PresenceDevice) {}; -}; - -// Unique Broadcast Session Identifier. -using BroadcastSessionId = uint64_t; - -// Callers would provide the implementation of these callbacks. If callers -// don't need these signal updates, they can skip with the provided default -// empty functions. -struct BroadcastCallback { - absl::AnyInvocable start_broadcast_cb = [](absl::Status) { - }; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_SCAN_CALLBACK_H_ diff --git a/presence/device_motion.cc b/presence/device_motion.cc deleted file mode 100644 index 8b79e3f6..00000000 --- a/presence/device_motion.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2020 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. - -#include "presence/device_motion.h" - -namespace nearby { -namespace presence { - -DeviceMotion::DeviceMotion(MotionType motion_type, float confidence) noexcept - : motion_type_(motion_type), confidence_(confidence) {} -DeviceMotion::MotionType DeviceMotion::GetMotionType() const { - return motion_type_; -} -float DeviceMotion::GetConfidence() const { return confidence_; } - -} // namespace presence -} // namespace nearby diff --git a/presence/device_motion.h b/presence/device_motion.h deleted file mode 100644 index 439b5349..00000000 --- a/presence/device_motion.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2020 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_PRESENCE_DEVICE_MOTION_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_DEVICE_MOTION_H_ - -namespace nearby { -namespace presence { -class DeviceMotion { - public: - enum class MotionType { - kPointAndHold = 0, - kStationaryAndHold = 1, - }; - DeviceMotion(MotionType motion_type = MotionType::kPointAndHold, - float confidence = 0) noexcept; - MotionType GetMotionType() const; - float GetConfidence() const; - - private: - const MotionType motion_type_; - const float confidence_; -}; - -inline bool operator==(const DeviceMotion& m1, const DeviceMotion& m2) { - return m1.GetMotionType() == m2.GetMotionType() && - m1.GetConfidence() == m2.GetConfidence(); -} -inline bool operator!=(const DeviceMotion& m1, const DeviceMotion& m2) { - return !(m1 == m2); -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_DEVICE_MOTION_H_ diff --git a/presence/device_motion_test.cc b/presence/device_motion_test.cc deleted file mode 100644 index 1155903a..00000000 --- a/presence/device_motion_test.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2020 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. - -#include "presence/device_motion.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace presence { -namespace { -static const DeviceMotion::MotionType kDefaultMotionType = - DeviceMotion::MotionType::kPointAndHold; -static const float kDefaultConfidence = 0; -static const float kConfidenceForTest = 0.1; -TEST(DeviceMotionTest, DefaultConstructorWorks) { - DeviceMotion motion; - EXPECT_EQ(motion.GetMotionType(), kDefaultMotionType); - EXPECT_EQ(motion.GetConfidence(), kDefaultConfidence); -} - -TEST(DeviceMotionTest, DefaultEquals) { - DeviceMotion motion1; - DeviceMotion motion2; - EXPECT_EQ(motion1, motion2); -} - -TEST(DeviceMotionTest, ExplicitInitEquals) { - DeviceMotion motion1 = {kDefaultMotionType, kConfidenceForTest}; - DeviceMotion motion2 = {kDefaultMotionType, kConfidenceForTest}; - EXPECT_EQ(motion1, motion2); - EXPECT_EQ(motion1.GetConfidence(), kConfidenceForTest); -} - -TEST(DeviceMotionTest, ExplicitInitNotEquals) { - DeviceMotion motion1 = {kDefaultMotionType, kConfidenceForTest}; - DeviceMotion motion2 = {kDefaultMotionType}; - EXPECT_NE(motion1, motion2); -} - -TEST(DeviceMotionTest, CopyInitEquals) { - DeviceMotion motion1; - DeviceMotion motion2 = {motion1}; - EXPECT_EQ(motion1, motion2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/discovery_filter.cc b/presence/discovery_filter.cc deleted file mode 100644 index 453309a5..00000000 --- a/presence/discovery_filter.cc +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2020 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. - -#include "presence/discovery_filter.h" - -namespace nearby { -namespace presence { - -using ::nearby::internal::IdentityType; - -DiscoveryFilter::DiscoveryFilter( - const std::vector& actions, - const std::vector& identities, - const std::vector& zones) noexcept - : actions_(actions), identities_(identities), zones_(zones) {} -std::vector DiscoveryFilter::GetActions() const { - return actions_; -} -std::vector DiscoveryFilter::GetIdentities() const { - return identities_; -} -std::vector DiscoveryFilter::GetZones() const { return zones_; } - -} // namespace presence -} // namespace nearby diff --git a/presence/discovery_filter.h b/presence/discovery_filter.h deleted file mode 100644 index 06b72413..00000000 --- a/presence/discovery_filter.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2020 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_PRESENCE_DISCOVERY_FILTER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_DISCOVERY_FILTER_H_ - -#include - -#include "internal/proto/credential.pb.h" -#include "presence/presence_action.h" -#include "presence/presence_zone.h" -namespace nearby { -namespace presence { -class DiscoveryFilter { - public: - DiscoveryFilter(const std::vector& = {}, - const std::vector<::nearby::internal::IdentityType>& = {}, - const std::vector& = {}) noexcept; - std::vector GetActions() const; - std::vector<::nearby::internal::IdentityType> GetIdentities() const; - std::vector GetZones() const; - - private: - const std::vector actions_; - const std::vector<::nearby::internal::IdentityType> identities_; - const std::vector zones_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_DISCOVERY_FILTER_H_ diff --git a/presence/discovery_filter_test.cc b/presence/discovery_filter_test.cc deleted file mode 100644 index c85f8f83..00000000 --- a/presence/discovery_filter_test.cc +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2020 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. - -#include "presence/discovery_filter.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::internal::IdentityType; - -const PresenceAction kTestAction = {1}; -const IdentityType kTestIdentity = {IdentityType::IDENTITY_TYPE_CONTACTS_GROUP}; - -TEST(DiscoveryFilterTest, DefaultConstructorWorks) { - DiscoveryFilter filter; - EXPECT_EQ(filter.GetActions().size(), 0); - EXPECT_EQ(filter.GetIdentities().size(), 0); - EXPECT_EQ(filter.GetZones().size(), 0); -} - -TEST(DiscoveryFilterTest, PartiallyInitializationWorks) { - DiscoveryFilter filter1{{kTestAction}, {kTestIdentity}}; - DiscoveryFilter filter2{{kTestAction}}; - EXPECT_EQ(filter1.GetActions(), filter2.GetActions()); - EXPECT_NE(filter1.GetIdentities(), filter2.GetIdentities()); - EXPECT_EQ(filter1.GetZones(), filter2.GetZones()); - - EXPECT_EQ(filter1.GetActions()[0], kTestAction); - EXPECT_EQ(filter1.GetIdentities()[0], kTestIdentity); - EXPECT_EQ(filter1.GetZones().capacity(), 0); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/discovery_options.h b/presence/discovery_options.h deleted file mode 100644 index 44dcfc0b..00000000 --- a/presence/discovery_options.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2020 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_PRESENCE_DISCOVERY_OPTIONS_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_DISCOVERY_OPTIONS_H_ - -namespace nearby { -namespace presence { -struct DiscoveryOptions { - const bool local_wifi_only_; -}; - -inline bool operator==(const DiscoveryOptions& o1, const DiscoveryOptions& o2) { - return o1.local_wifi_only_ == o2.local_wifi_only_; -} - -inline bool operator!=(const DiscoveryOptions& o1, const DiscoveryOptions& o2) { - return !(o1 == o2); -} - -} // namespace presence -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_PRESENCE_DISCOVERY_OPTIONS_H_ diff --git a/presence/discovery_options_test.cc b/presence/discovery_options_test.cc deleted file mode 100644 index 631ed12f..00000000 --- a/presence/discovery_options_test.cc +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2020 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. - -#include "presence/discovery_options.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace presence { -namespace { - -constexpr bool kTestLocalWifiOnly = false; -TEST(DiscoveryOptionsTest, NoDefaultConstructor) { - EXPECT_FALSE(std::is_trivially_constructible::value); -} - -TEST(DiscoveryOptionsTest, ExplicitInitEquals) { - DiscoveryOptions option1 = {kTestLocalWifiOnly}; - DiscoveryOptions option2 = {kTestLocalWifiOnly}; - EXPECT_EQ(option1, option2); - EXPECT_EQ(option1.local_wifi_only_, kTestLocalWifiOnly); -} - -TEST(DiscoveryOptionsTest, ExplicitInitNotEquals) { - DiscoveryOptions option1 = {kTestLocalWifiOnly}; - DiscoveryOptions option2 = {!kTestLocalWifiOnly}; - EXPECT_NE(option1, option2); -} - -TEST(DiscoveryOptionsTest, CopyInitEquals) { - DiscoveryOptions option1 = {kTestLocalWifiOnly}; - DiscoveryOptions option2 = {option1}; - EXPECT_EQ(option1, option2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/fake_presence_client.cc b/presence/fake_presence_client.cc deleted file mode 100644 index 44e73440..00000000 --- a/presence/fake_presence_client.cc +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2023 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. - -#include "presence/fake_presence_client.h" - - -#include -#include -#include - -#include "presence/data_types.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -absl::StatusOr FakePresenceClient::StartScan( - ScanRequest scan_request, ScanCallback callback) { - current_scan_session_id_++; - active_scan_sessions_.push_back(current_scan_session_id_); - absl::StatusOr scan_session_id(current_scan_session_id_); - callback_ = std::move(callback); - return scan_session_id; -} - -void FakePresenceClient::StopScan(ScanSessionId id) { - auto position = - std::find(active_scan_sessions_.begin(), active_scan_sessions_.end(), id); - if (position != active_scan_sessions_.end()) { - active_scan_sessions_.erase(position); - } -} - -std::vector FakePresenceClient::GetActiveScanSessions() { - return active_scan_sessions_; -} - -void FakePresenceClient::CallStartScanCallback(absl::Status status) { - callback_.start_scan_cb(status); -} - -void FakePresenceClient::CallOnDiscovered(PresenceDevice device) { - callback_.on_discovered_cb(device); -} - -void FakePresenceClient::CallOnUpdated(PresenceDevice device) { - callback_.on_updated_cb(device); -} - -void FakePresenceClient::CallOnLost(PresenceDevice device) { - callback_.on_lost_cb(device); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/fake_presence_client.h b/presence/fake_presence_client.h deleted file mode 100644 index b2a6d816..00000000 --- a/presence/fake_presence_client.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2023 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_PRESENCE_FAKE_PRESENCE_CLIENT_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_CLIENT_H_ - -#include -#include - -#include "absl/status/statusor.h" -#include "presence/broadcast_request.h" -#include "presence/presence_client.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -class FakePresenceClient : public PresenceClient { - public: - FakePresenceClient() = default; - FakePresenceClient(const FakePresenceClient&) = delete; - FakePresenceClient(FakePresenceClient&&) = default; - FakePresenceClient& operator=(const FakePresenceClient&) = delete; - ~FakePresenceClient() = default; - - absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) override; - - void StopScan(ScanSessionId session_id) override; - - // Not Implemented. - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) override { - return 0; - } - - // Not Implemented. - void StopBroadcast(BroadcastSessionId session_id) override {} - - // Not Implemented. - std::optional GetLocalDevice() override { - return std::nullopt; - } - - - std::vector GetActiveScanSessions(); - void CallStartScanCallback(absl::Status status); - void CallOnDiscovered(PresenceDevice device); - void CallOnUpdated(PresenceDevice device); - void CallOnLost(PresenceDevice device); - - private: - uint64_t current_scan_session_id_; - ScanCallback callback_; - std::vector active_scan_sessions_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_CLIENT_H_ diff --git a/presence/fake_presence_service.cc b/presence/fake_presence_service.cc deleted file mode 100644 index ff06221a..00000000 --- a/presence/fake_presence_service.cc +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2020 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. - -#include "presence/fake_presence_service.h" - -#include -#include -#include - -#include "internal/interop/device_provider.h" -#include "internal/platform/borrowable.h" -#include "presence/fake_presence_client.h" - -namespace nearby { -namespace presence { - -FakePresenceService::FakePresenceService() = default; - -std::unique_ptr FakePresenceService::CreatePresenceClient() { - auto fake = std::make_unique(); - most_recent_fake_presence_client_ = fake.get(); - return std::move(fake); -} - -// Not implemented. -absl::StatusOr FakePresenceService::StartScan( - ScanRequest scan_request, ScanCallback callback) { - return absl::Status(absl::StatusCode::kCancelled, - "StartScan not implemented yet"); -} - -// Not implemented. -void FakePresenceService::StopScan(ScanSessionId session_id) {} - -// Not implemented. -absl::StatusOr FakePresenceService::StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) { - return absl::Status(absl::StatusCode::kCancelled, - "StartBroadcast not implemented yet"); -} - -// Not implemented. -void FakePresenceService::StopBroadcast(BroadcastSessionId session_id) {} - -void FakePresenceService::UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& metadata, - bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) { - metadata_ = metadata; - - if (!regen_credentials) { - // No need to call back on credentials_generated_cb. - return; - } - - if (gen_credentials_status_.ok()) { - std::move(credentials_generated_cb.credentials_generated_cb)( - shared_credentials_); - } else { - std::move(credentials_generated_cb.credentials_generated_cb)( - gen_credentials_status_); - } -} - -NearbyDeviceProvider* FakePresenceService::GetLocalDeviceProvider() { - return provider_; -} - -void FakePresenceService::GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) { - if (get_public_credentials_status_.ok()) { - std::move(callback.credentials_fetched_cb)(shared_credentials_); - return; - } - - std::move(callback.credentials_fetched_cb)(get_public_credentials_status_); -} - -void FakePresenceService::UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) { - if (update_remote_public_credentials_status_.ok()) { - remote_shared_credentials_ = remote_public_creds; - } - - std::move(credentials_updated_cb.credentials_updated_cb)( - update_remote_public_credentials_status_); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/fake_presence_service.h b/presence/fake_presence_service.h deleted file mode 100644 index 81dca042..00000000 --- a/presence/fake_presence_service.h +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2023 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_PRESENCE_FAKE_PRESENCE_SERVICE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_SERVICE_H_ - -#include "internal/interop/device_provider.h" -#include "internal/interop/fake_device_provider.h" -#include "internal/platform/borrowable.h" -#include "internal/proto/metadata.pb.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/presence_client.h" -#include "presence/presence_service.h" - -namespace nearby { -namespace presence { - -class FakePresenceClient; - -class FakePresenceService : public PresenceService { - public: - FakePresenceService(); - ~FakePresenceService() override { lender_.Release(); } - - // PresenceService: - std::unique_ptr CreatePresenceClient() override; - - absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) override; - - void StopScan(ScanSessionId session_id) override; - - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) override; - - void StopBroadcast(BroadcastSessionId session_id) override; - - void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& metadata, - bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override; - - NearbyDeviceProvider* GetLocalDeviceProvider() override; - - ::nearby::internal::DeviceIdentityMetaData GetDeviceIdentityMetaData() - override { - return metadata_; - } - - void GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) override; - void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) override; - - // Use for testing. Call this to set the response to - // `UpdateLocalDeviceMetadata`. - void SetUpdateLocalDeviceMetadataResponse( - absl::Status status, - std::vector shared_credentials) { - shared_credentials_ = shared_credentials; - gen_credentials_status_ = status; - } - - FakePresenceClient* GetMostRecentFakePresenceClient() { - return most_recent_fake_presence_client_; - } - - // Used for testing to verify the remote credentials set. - std::vector GetRemoteSharedCredentials() { - return remote_shared_credentials_; - } - - void SetUpdateRemoteSharedCredentialsResult(absl::Status status) { - update_remote_public_credentials_status_ = status; - } - - void SetLocalPublicCredentialsResult( - absl::Status status, - std::vector shared_credentials) { - get_public_credentials_status_ = status; - shared_credentials_ = shared_credentials; - } - - void SetDeviceProvider(NearbyDeviceProvider* provider) { - provider_ = provider; - } - - private: - FakePresenceClient* most_recent_fake_presence_client_ = nullptr; - std::vector shared_credentials_; - std::vector remote_shared_credentials_; - absl::Status gen_credentials_status_; - absl::Status update_remote_public_credentials_status_; - absl::Status get_public_credentials_status_; - ::nearby::internal::DeviceIdentityMetaData metadata_; - NearbyDeviceProvider* provider_; - ::nearby::Lender lender_{this}; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_SERVICE_H_ diff --git a/presence/fpp/BUILD b/presence/fpp/BUILD deleted file mode 100644 index 6e5d738d..00000000 --- a/presence/fpp/BUILD +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright 2023 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 -# -# http://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. - -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -licenses(["notice"]) - -cc_library( - name = "fpp_manager", - srcs = [ - "fpp_manager.cc", - ], - hdrs = ["fpp_manager.h"], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - "//internal/platform:logging", - "//presence:types", - "//presence/fpp/fpp_c_ffi", - "//presence/implementation:sensor_fusion", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", - ], -) - -cc_library( - name = "sensor_fusion_impl", - srcs = [ - "sensor_fusion_impl.cc", - ], - hdrs = ["sensor_fusion_impl.h"], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - ":fpp_manager", - "//presence/implementation:sensor_fusion", - "@com_google_absl//absl/status", - ], -) - -cc_test( - name = "fpp_manager_test", - size = "small", - srcs = ["fpp_manager_test.cc"], - deps = [ - ":fpp_manager", - "//presence/implementation:sensor_fusion", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "sensor_fusion_test", - size = "small", - srcs = ["sensor_fusion_test.cc"], - deps = [ - ":sensor_fusion_impl", - "//presence/implementation:sensor_fusion", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) diff --git a/presence/fpp/fpp/Cargo.lock b/presence/fpp/fpp/Cargo.lock deleted file mode 100644 index be2b9180..00000000 --- a/presence/fpp/fpp/Cargo.lock +++ /dev/null @@ -1,25 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "fpp" -version = "0.1.0" -dependencies = [ - "itertools", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] diff --git a/presence/fpp/fpp/Cargo.toml b/presence/fpp/fpp/Cargo.toml deleted file mode 100644 index b3de1c90..00000000 --- a/presence/fpp/fpp/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "fpp" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -itertools = "0.10.5" diff --git a/presence/fpp/fpp/src/fspl_converter.rs b/presence/fpp/fpp/src/fspl_converter.rs deleted file mode 100644 index 6b03f6b8..00000000 --- a/presence/fpp/fpp/src/fspl_converter.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -const ADVERTISE_TX_POWER_HIGH_DB: i32 = 1; - -const FSPL_AT_1_METER_DB: i32 = 40; - -const MEASURED_POWER_AT_1_METER_DB_AT_HIGH_TX_POWER: i32 = -60; - -pub fn compute_distance_meters_at_high_tx_power(rssi: i32) -> f64 { - let nominal_tx_power = ADVERTISE_TX_POWER_HIGH_DB; - let antenna_gain = - (nominal_tx_power - FSPL_AT_1_METER_DB) - MEASURED_POWER_AT_1_METER_DB_AT_HIGH_TX_POWER; - let tx_power_at_0_meters = nominal_tx_power - antenna_gain; - compute_distance_meters(tx_power_at_0_meters, rssi) -} - -pub fn compute_distance_meters(tx_power_at_0_meters: i32, rssi: i32) -> f64 { - let fspl = tx_power_at_0_meters - rssi; - ble_fspl_to_meters(fspl) -} - -fn ble_fspl_to_meters(fspl: i32) -> f64 { - let base: f64 = 10.0; - base.powi((fspl - FSPL_AT_1_METER_DB) / 20) -} diff --git a/presence/fpp/fpp/src/fspl_converter_test.rs b/presence/fpp/fpp/src/fspl_converter_test.rs deleted file mode 100644 index efa273c8..00000000 --- a/presence/fpp/fpp/src/fspl_converter_test.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -use crate::fspl_converter::compute_distance_meters_at_high_tx_power; - -#[test] -fn test_short_distance() { - assert_eq!(compute_distance_meters_at_high_tx_power(-40), 0.1); -} - -#[test] -fn test_medium_distance() { - assert_eq!(compute_distance_meters_at_high_tx_power(-60), 1.0); -} - -#[test] -fn test_large_distance() { - assert_eq!(compute_distance_meters_at_high_tx_power(-80), 10.0); -} diff --git a/presence/fpp/fpp/src/fused_presence_utils.rs b/presence/fpp/fpp/src/fused_presence_utils.rs deleted file mode 100644 index 48b2dd0e..00000000 --- a/presence/fpp/fpp/src/fused_presence_utils.rs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -pub(crate) const DEFAULT_TAP_DISTANCE_THRESHOLD_METERS: f64 = AMBIGUITY_METERS + 0.02; -pub(crate) const DEFAULT_REACH_DISTANCE_THRESHOLD_METERS: f64 = AMBIGUITY_METERS + 0.5; -pub(crate) const DEFAULT_SHORT_RANGE_DISTANCE_THRESHOLD_METERS: f64 = AMBIGUITY_METERS + 1.2; -pub(crate) const DEFAULT_LONG_RANGE_DISTANCE_THRESHOLD_METERS: f64 = AMBIGUITY_METERS + 3.0; -pub(crate) const DEFAULT_CONSECUTIVE_SCANS_REQUIRED: u8 = 2; -const AMBIGUITY_METERS: f64 = 0.06; - -/// Proximity state from device to another in terms of actionability -#[derive(Eq, Hash, Copy, Clone, PartialEq, Debug)] -#[repr(C)] -pub enum ProximityState { - /// Unknown proximity state - Unknown, - /// The device is within a tap zone (<0.02m) - Tap, - /// The device is within a reach zone (<0.5m) - Reach, - /// The device is within a short range zone (<1.2m) - ShortRange, - /// The device is within a long range zone (<3.0m) - LongRange, - /// The device is at a far range - Far, -} - -/// Represents the confidence levels for a given measurement -#[derive(Copy, Clone, PartialEq, Debug)] -#[repr(C)] -pub enum MeasurementConfidence { - /// Measurement confidence is low, the default for BLE medium - Low, - /// Measurement confidence is medium - Medium, - /// Measurement confidence is High - High, - /// Measurement confidence is unknown - Unknown, -} - -/// Data sources that are used to track presence -#[derive(Copy, Clone, PartialEq, Debug)] -#[repr(C)] -pub enum PresenceDataSource { - /// Data source for proximity estimate is BLE - Ble, - /// Data source for proximity estimate is UWB - Uwb, - /// Data source for proximity estimate is NAN - Nan, - /// Data source for proximity estimate is unknown - Unknown, -} - -/// A PII-stripped subset of Bluetooth scan result -#[repr(C)] -pub struct BleScanResult { - /// Device ID of the nearby device - pub device_id: u64, - /// Transmitting power of signal - pub tx_power: MaybeTxPower, - /// RSSI value - pub rssi: i32, - /// Time scan result was obtained - pub elapsed_real_time_millis: u64, -} - -/// Enum representing an optional tx power value -#[repr(C)] -pub enum MaybeTxPower { - /// Valid TX power with associated data value - Valid(i32), - /// Absent Tx Power - Invalid, -} - -/// Describes the most accurate and recent measurement for a given device -#[derive(Copy, Clone, PartialEq, Debug)] -#[repr(C)] -pub struct ProximityEstimate { - /// Device ID of the nearby device - pub device_id: u64, - /// Distance to the nearby device in meters - pub distance_meters: f64, - /// Measurement confidence of the estimate - pub distance_confidence: MeasurementConfidence, - /// The time the proximity estimate was obtained (milliseconds since the - /// program start time) - pub elapsed_real_time_millis: u64, - /// Proximity state zone of the nearby device - pub proximity_state: ProximityState, - /// Medium through which the proximity estimate was computed - pub source: PresenceDataSource, -} diff --git a/presence/fpp/fpp/src/lib.rs b/presence/fpp/fpp/src/lib.rs deleted file mode 100644 index ef30da9e..00000000 --- a/presence/fpp/fpp/src/lib.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -#![deny( - missing_docs, - clippy::indexing_slicing, - clippy::unwrap_used, - clippy::panic, - clippy::expect_used -)] - -//! Processes raw scan results from BLE, UWB and NAN and outputs proximity estimates/zones - -mod fspl_converter; - -/// Fused presence Utils -pub mod fused_presence_utils; - -/// Presence detector module -pub mod presence_detector; - -#[cfg(test)] -mod fspl_converter_test; - -#[cfg(test)] -mod presence_detector_test; diff --git a/presence/fpp/fpp/src/presence_detector.rs b/presence/fpp/fpp/src/presence_detector.rs deleted file mode 100644 index 7f613ab5..00000000 --- a/presence/fpp/fpp/src/presence_detector.rs +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -use std::collections::{HashMap, VecDeque}; -use std::time::{Instant, SystemTime}; - -use itertools::Itertools; - -use crate::fspl_converter::compute_distance_meters_at_high_tx_power; -use crate::fused_presence_utils::{ - BleScanResult, MaybeTxPower, MeasurementConfidence, PresenceDataSource, ProximityEstimate, - ProximityState, DEFAULT_CONSECUTIVE_SCANS_REQUIRED, - DEFAULT_LONG_RANGE_DISTANCE_THRESHOLD_METERS, DEFAULT_REACH_DISTANCE_THRESHOLD_METERS, - DEFAULT_SHORT_RANGE_DISTANCE_THRESHOLD_METERS, DEFAULT_TAP_DISTANCE_THRESHOLD_METERS, -}; - -const MAX_RSSI_FILTER_VALUE: i32 = 10; -const DEFAULT_ESTIMATED_DISTANCE_DATA_TTL_MILLIS: u128 = 4000; - -/// Static function for getting proximity state from threshold -fn get_proximity_state_from_threshold(distance_meters: f64) -> ProximityState { - if distance_meters <= DEFAULT_TAP_DISTANCE_THRESHOLD_METERS { - return ProximityState::Tap; - } - if distance_meters <= DEFAULT_REACH_DISTANCE_THRESHOLD_METERS { - return ProximityState::Reach; - } - if distance_meters <= DEFAULT_SHORT_RANGE_DISTANCE_THRESHOLD_METERS { - return ProximityState::ShortRange; - } - if distance_meters <= DEFAULT_LONG_RANGE_DISTANCE_THRESHOLD_METERS { - return ProximityState::LongRange; - } - ProximityState::Far -} - -/// Tracks and computes proximity/presence state events. -pub struct PresenceDetector { - start_time: Instant, - last_range_update_time: RangingUpdateTime, - best_proximity_estimate_per_device: HashMap, - transition_history: VecDeque, -} - -struct RangingUpdateTime(u128); - -impl RangingUpdateTime { - pub fn is_expired(&self) -> bool { - let elapsed_real_time_millis = Instant::now().elapsed().as_millis(); - elapsed_real_time_millis - self.0 > DEFAULT_ESTIMATED_DISTANCE_DATA_TTL_MILLIS - } - - pub fn update(&mut self, start_time: Instant) { - self.0 = Instant::now().duration_since(start_time).as_millis(); - } -} - -impl PresenceDetector { - /// Creates a new instance of presence detector - pub fn new() -> Self { - PresenceDetector { - start_time: Instant::now(), - last_range_update_time: RangingUpdateTime(0), - best_proximity_estimate_per_device: HashMap::new(), - transition_history: VecDeque::with_capacity( - (DEFAULT_CONSECUTIVE_SCANS_REQUIRED + 1).into(), - ), - } - } - - /// Updates the presence detector with a new scan result and returns the - /// current proximity estimate - pub fn on_ble_scan_result( - &mut self, - ble_scan_result: BleScanResult, - ) -> Option { - let device_id = ble_scan_result.device_id; - if ble_scan_result.rssi > MAX_RSSI_FILTER_VALUE { - return self.best_proximity_estimate_per_device.get(&device_id).copied(); - } - if self.last_range_update_time.is_expired() { - self.transition_history.clear(); - } - let mut tx_power: i32 = 0; - if let MaybeTxPower::Valid(some_tx_power) = ble_scan_result.tx_power { - tx_power = some_tx_power; - } - let rssi = ble_scan_result.rssi + tx_power; - let distance_meters = compute_distance_meters_at_high_tx_power(rssi); - let new_proximity_estimate = ProximityEstimate { - device_id, - distance_confidence: MeasurementConfidence::Low, - distance_meters, - proximity_state: get_proximity_state_from_threshold(distance_meters), - elapsed_real_time_millis: Instant::now().duration_since(self.start_time).as_millis() - as u64, - source: PresenceDataSource::Ble, - }; - self.transition_history.push_front(new_proximity_estimate.proximity_state); - self.transition_history.truncate(DEFAULT_CONSECUTIVE_SCANS_REQUIRED.into()); - if self.transition_history.iter().unique().count() == 1 - && self.transition_history.len() == DEFAULT_CONSECUTIVE_SCANS_REQUIRED.into() - { - self.best_proximity_estimate_per_device.insert(device_id, new_proximity_estimate); - self.last_range_update_time.update(self.start_time); - } - self.best_proximity_estimate_per_device.get(&device_id).copied() - } - - /// Returns the current proximity estimate for a given device - pub fn get_proximity_estimate(&self, device_id: u64) -> Option { - self.best_proximity_estimate_per_device.get(&device_id).copied() - } -} - -impl Default for PresenceDetector { - fn default() -> Self { - Self::new() - } -} diff --git a/presence/fpp/fpp/src/presence_detector_test.rs b/presence/fpp/fpp/src/presence_detector_test.rs deleted file mode 100644 index 1d35f187..00000000 --- a/presence/fpp/fpp/src/presence_detector_test.rs +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -use crate::fused_presence_utils::*; -use crate::presence_detector::*; - -const BLE_SCAN_RESULT_REACH_ZONE: BleScanResult = BleScanResult { - device_id: 1234, - tx_power: { MaybeTxPower::Invalid }, - rssi: -40, - elapsed_real_time_millis: 123456, -}; - -const BLE_SCAN_RESULT_BAD_RSSI: BleScanResult = BleScanResult { - rssi: 127, - ..BLE_SCAN_RESULT_REACH_ZONE -}; - -const BLE_SCAN_RESULT_SHORT_RANGE_ZONE: BleScanResult = BleScanResult { - rssi: -60, - ..BLE_SCAN_RESULT_REACH_ZONE -}; - -const REACH_PROXIMITY_ESTIMATE: ProximityEstimate = ProximityEstimate { - device_id: 1234, - distance_meters: 0.1, - distance_confidence: MeasurementConfidence::Low, - elapsed_real_time_millis: 0, - proximity_state: ProximityState::Reach, - source: PresenceDataSource::Ble, -}; - -const SHORT_RANGE_PROXIMITY_ESTIMATE: ProximityEstimate = ProximityEstimate { - distance_meters: 1.0, - proximity_state: ProximityState::ShortRange, - ..REACH_PROXIMITY_ESTIMATE -}; - -#[test] -fn test_on_ble_scan_result_success() { - // Tests that the proximity state stored for each device is the accurate one after two - // consecutive scan results - let mut presence_detector = PresenceDetector::new(); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_REACH_ZONE), - None - ); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_REACH_ZONE), - Some(ProximityEstimate { - device_id: 1234, - distance_meters: 0.1, - distance_confidence: MeasurementConfidence::Low, - elapsed_real_time_millis: 0, - proximity_state: ProximityState::Reach, - source: PresenceDataSource::Ble - }) - ); -} - -#[test] -fn test_on_ble_scan_result_bad_rssi() { - // Tests that scan results with bad RSSIs are ignored - let mut presence_detector = PresenceDetector::new(); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_REACH_ZONE), - None - ); - - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_BAD_RSSI), - None - ); -} -#[test] -fn test_on_ble_scan_result_transition_to_new_zone() { - let mut presence_detector = PresenceDetector::new(); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_REACH_ZONE), - None - ); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_REACH_ZONE), - Some(REACH_PROXIMITY_ESTIMATE) - ); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_SHORT_RANGE_ZONE), - Some(REACH_PROXIMITY_ESTIMATE) - ); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_SHORT_RANGE_ZONE), - Some(SHORT_RANGE_PROXIMITY_ESTIMATE) - ); -} diff --git a/presence/fpp/fpp_c_ffi/Cargo.lock b/presence/fpp/fpp_c_ffi/Cargo.lock deleted file mode 100644 index 99bf6078..00000000 --- a/presence/fpp/fpp_c_ffi/Cargo.lock +++ /dev/null @@ -1,105 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "fpp" -version = "0.1.0" -dependencies = [ - "itertools", -] - -[[package]] -name = "fpp_c_ffi" -version = "0.1.0" -dependencies = [ - "fpp", - "lazy_static", - "rand", -] - -[[package]] -name = "getrandom" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.144" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" diff --git a/presence/fpp/fpp_c_ffi/Cargo.toml b/presence/fpp/fpp_c_ffi/Cargo.toml deleted file mode 100644 index 301a85c3..00000000 --- a/presence/fpp/fpp_c_ffi/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "fpp_c_ffi" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -fpp = {path = "../fpp"} -lazy_static = "1.4.0" -rand = "0.8.5" diff --git a/presence/fpp/fpp_c_ffi/include/presence_detector.h b/presence/fpp/fpp_c_ffi/include/presence_detector.h deleted file mode 100644 index 7bc03aa5..00000000 --- a/presence/fpp/fpp_c_ffi/include/presence_detector.h +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2023 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 -// -// http://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 PRESENCE_DETECTOR_H_ -#define PRESENCE_DETECTOR_H_ - -#include -#include -#include -#include -#include - -// Represents the confidence levels for a given measurement -enum class MeasurementConfidence { - /// Measurement confidence is low, the default for BLE medium - Low, - /// Measurement confidence is medium - Medium, - /// Measurement confidence is High - High, - /// Measurement confidence is unknown - Unknown, -}; - -/// Data sources that are used to track presence -enum class PresenceDataSource { - /// Data source for proximity estimate is BLE - Ble, - /// Data source for proximity estimate is UWB - Uwb, - /// Data source for proximity estimate is NAN - Nan, - /// Data source for proximity estimate is unknown - Unknown, -}; - -/// Proximity state from device to another in terms of actionability -enum class ProximityState { - /// Unknown proximity state - Unknown, - /// The device is within a tap zone (<0.02m) - Tap, - /// The device is within a reach zone (<0.5m) - Reach, - /// The device is within a short range zone (<1.2m) - ShortRange, - /// The device is within a long range zone (<3.0m) - LongRange, - /// The device is at a far range - Far, -}; - -/// Wraps the handle ID to an underlying PresenceDetector object -struct PresenceDetectorHandle { - uint64_t handle; -}; - -/// Enum representing an optional tx power value -struct MaybeTxPower { - enum class Tag { - /// Valid TX power with associated data value - Valid, - /// Absent Tx Power - Invalid, - }; - - struct Valid_Body { - int32_t _0; - }; - - Tag tag; - union { - Valid_Body valid; - }; -}; - -/// A PII-stripped subset of Bluetooth scan result -struct BleScanResult { - /// Device ID of the nearby device - uint64_t device_id; - /// Transmitting power of signal - MaybeTxPower tx_power; - /// RSSI value - int32_t rssi; - /// Time scan result was obtained - uint64_t elapsed_real_time_millis; -}; - -/// Describes the most accurate and recent measurement for a given device -struct ProximityEstimate { - /// Device ID of the nearby device - uint64_t device_id; - /// Distance to the nearby device in meters - double distance_meters; - /// Measurement confidence of the estimate - MeasurementConfidence distance_confidence; - /// The time the proximity estimate was obtained - uint64_t elapsed_real_time_millis; - /// Proximity state zone of the nearby device - ProximityState proximity_state; - /// Medium through which the proximity estimate was computed - PresenceDataSource source; -}; - -extern "C" { - -/// Creates a new presence detector object and returns the handle for the new -/// object -PresenceDetectorHandle presence_detector_create(); - -/// Updates PresenceDetector with a new scan result and returns an error code -/// if unsuccessful -/// -/// # Safety -/// -/// Ensure that the output parameter refers to an initialized instance -int32_t update_ble_scan_result(PresenceDetectorHandle presence_detector_handle, - BleScanResult ble_scan_result, - ProximityEstimate *proximity_estimate); - -/// Gets the current proximity estimate for a given device ID -/// -/// # Safety -/// -/// Ensure that the output parameter refers to an initialized instance -int32_t get_proximity_estimate(PresenceDetectorHandle presence_detector_handle, - uint64_t device_id, - ProximityEstimate *proximity_estimate); - -/// De-allocates memory for a presence detector object -int presence_detector_free(PresenceDetectorHandle presence_detector_handle); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // PRESENCE_DETECTOR_H_ diff --git a/presence/fpp/fpp_c_ffi/src/handle_map.rs b/presence/fpp/fpp_c_ffi/src/handle_map.rs deleted file mode 100644 index 0f9566a9..00000000 --- a/presence/fpp/fpp_c_ffi/src/handle_map.rs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -use core::marker::PhantomData; -use fpp::presence_detector::PresenceDetector; -use lazy_static::lazy_static; -use rand::Rng; -use std::collections::HashMap; -use std::sync::{Mutex, MutexGuard}; - -pub(crate) struct HandleMap { - _marker: PhantomData, - map: HashMap, -} - -impl HandleMap { - pub(crate) fn init() -> Self { - Self { - _marker: Default::default(), - map: HashMap::new(), - } - } - - /// inserts an entry into the map and returns the randomly generated handle to the entry - pub(crate) fn insert(&mut self, data: T) -> u64 { - let mut rng = rand::thread_rng(); - let mut handle: u64 = rng.gen(); - - while self.map.contains_key(&handle) { - handle = rng.gen(); - } - - assert!(self.map.insert(handle, data).is_none()); - handle - } - - /// Removes an entry at a given handle returning an Option of the owned value - pub(crate) fn remove(&mut self, handle: &u64) -> Option { - self.map.remove(handle) - } - - /// Gets a reference to the entry stored at the specified handle - pub(crate) fn get(&mut self, handle: &u64) -> Option<&mut T> { - self.map.get_mut(handle) - } -} - -// Returns a threadsafe instance of the global static hashmap tracking the PresenceDetector handles -pub(crate) fn get_presence_detector_handle_map( -) -> MutexGuard<'static, HandleMap>> { - PRESENCE_DETECTOR_HANDLE_MAP - .lock() - .unwrap_or_else(|err_guard| err_guard.into_inner()) -} - -// Global hashmap to track valid pointers, this is a safety precaution to make sure we are not -// reading from unsafe memory address's passed in by the caller -lazy_static! { - static ref PRESENCE_DETECTOR_HANDLE_MAP: Mutex>> = - Mutex::new(HandleMap::init()); -} diff --git a/presence/fpp/fpp_c_ffi/src/lib.rs b/presence/fpp/fpp_c_ffi/src/lib.rs deleted file mode 100644 index b0c536f7..00000000 --- a/presence/fpp/fpp_c_ffi/src/lib.rs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -#![deny( - missing_docs, - clippy::indexing_slicing, - clippy::unwrap_used, - clippy::panic, - clippy::expect_used -)] - -//! Rust FFI wrapper for PresenceDetector. Can be called from C/C++ clients - -use fpp::fused_presence_utils::*; -use fpp::presence_detector::*; - -use crate::handle_map::get_presence_detector_handle_map; - -mod handle_map; - -/// Wraps the handle ID to an underlying PresenceDetector object -#[repr(C)] -pub struct PresenceDetectorHandle { - handle: u64, -} - -/// Enum class representing possible outputs of proximity data processing call -#[repr(C)] -pub enum ComputationStatus { - /// Returned if the proximity estimate calculation was successful - Success, - /// Returned if there is no computed proximity estimate - NoComputedProximityEstimate, - /// Returned if the handle is invalid - InvalidPresenceDetectorHandleError, - /// Returned if the output parameter is null - NullOutputParameterError, -} - -impl ComputationStatus { - fn to_status_code(&self) -> i32 { - match self { - /// Status codes 100+ are considered errors - Self::Success => 1, - Self::NoComputedProximityEstimate => 2, - Self::InvalidPresenceDetectorHandleError => 101, - Self::NullOutputParameterError => 102, - } - } -} - -/// Creates a new presence detector object and returns the handle for the new -/// object -#[no_mangle] -pub extern "C" fn presence_detector_create() -> PresenceDetectorHandle { - let handle = get_presence_detector_handle_map().insert(Box::new(PresenceDetector::new())); - PresenceDetectorHandle { handle } -} - -/// Updates PresenceDetector with a new scan result and returns an error code if -/// unsuccessful -/// -/// # Safety -/// -/// Ensure that the output parameter refers to an initialized instance -#[no_mangle] -pub unsafe extern "C" fn update_ble_scan_result( - presence_detector_handle: PresenceDetectorHandle, - ble_scan_result: BleScanResult, - proximity_estimate: *mut ProximityEstimate, -) -> i32 { - if let Some(presence_detector) = - get_presence_detector_handle_map().get(&presence_detector_handle.handle) - { - if let Some(current_proximity_estimate) = - presence_detector.on_ble_scan_result(ble_scan_result) - { - if let Some(proximity_estimate) = proximity_estimate.as_mut() { - *proximity_estimate = current_proximity_estimate; - ComputationStatus::Success.to_status_code() - } else { - ComputationStatus::NullOutputParameterError.to_status_code() - } - } else { - ComputationStatus::NoComputedProximityEstimate.to_status_code() - } - } else { - ComputationStatus::InvalidPresenceDetectorHandleError.to_status_code() - } -} - -/// Gets the current proximity estimate for a given device ID -/// -/// # Safety -/// -/// Ensure that the output parameter refers to an initialized instance -#[no_mangle] -pub unsafe extern "C" fn get_proximity_estimate( - presence_detector_handle: PresenceDetectorHandle, - device_id: u64, - proximity_estimate: *mut ProximityEstimate, -) -> i32 { - if let Some(presence_detector) = - get_presence_detector_handle_map().get(&presence_detector_handle.handle) - { - presence_detector.get_proximity_estimate(device_id).map(|current_proximity_estimate| { - if let Some(proximity_estimate) = proximity_estimate.as_mut() { - *proximity_estimate = current_proximity_estimate; - return ComputationStatus::Success.to_status_code(); - } - ComputationStatus::NullOutputParameterError.to_status_code() - }); - } - - ComputationStatus::InvalidPresenceDetectorHandleError.to_status_code() -} - -/// De-allocates memory for a presence detector object -#[no_mangle] -pub extern "C" fn presence_detector_free( - presence_detector_handle: PresenceDetectorHandle, -) -> std::os::raw::c_int { - if let Some(presence_detector) = - get_presence_detector_handle_map().remove(&presence_detector_handle.handle) - { - let _ = *presence_detector; - return ComputationStatus::Success.to_status_code(); - } - ComputationStatus::InvalidPresenceDetectorHandleError.to_status_code() -} diff --git a/presence/fpp/fpp_manager.cc b/presence/fpp/fpp_manager.cc deleted file mode 100644 index e7d9efc8..00000000 --- a/presence/fpp/fpp_manager.cc +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -#include "presence/fpp/fpp_manager.h" - -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "internal/platform/logging.h" -#include "presence/fpp/fpp_c_ffi/include/presence_detector.h" -#include "presence/implementation/sensor_fusion.h" -#include "presence/presence_zone.h" - -namespace nearby { -namespace presence { - -namespace { -// See -// https://source.corp.google.com/piper///depot/google3/third_party/nearby/presence/fpp/fpp_c_ffi/src/lib.rs;l=49 -// for constants definition -constexpr int kSuccess = 1; -constexpr int kNoComputedProximityEstimate = 2; -constexpr int kInvalidPresenceDetectorHandleError = 101; -constexpr int kNullOutputParameterError = 102; - -// Converts optional tx power to the rust api compatible equivalent -MaybeTxPower ConvertTxPower(std::optional txPower) { - if (txPower.has_value()) { - return {MaybeTxPower::Tag::Valid, {txPower.value()}}; - } - return {MaybeTxPower::Tag::Invalid, {}}; -} - -// Converts FPP ProximityState struct to NP RangeType struct -PresenceZone::DistanceBoundary::RangeType ConvertProximityStateToRangeType( - ProximityState proximity_state) { - switch (proximity_state) { - case ProximityState::Tap: - return PresenceZone::DistanceBoundary::RangeType::kWithinTap; - case ProximityState::Reach: - return PresenceZone::DistanceBoundary::RangeType::kWithinReach; - case ProximityState::ShortRange: - case ProximityState::LongRange: - case ProximityState::Far: - return PresenceZone::DistanceBoundary::RangeType::kFar; - case ProximityState::Unknown: - default: - LOG(WARNING) << "Proximity state is unknown"; - return PresenceZone::DistanceBoundary::RangeType::kRangeUnknown; - } -} -} // namespace - -absl::Status FppManager::UpdateBleScanResult(uint64_t device_id, - std::optional txPower, - int rssi, - uint64_t elapsed_realtime_millis) { - if (zone_transition_callbacks_.empty()) { - return absl::InternalError("No callback registered"); - } - BleScanResult ble_scan_result = {device_id, ConvertTxPower(txPower), rssi, - elapsed_realtime_millis}; - ProximityEstimate default_proximity_estimate = - ProximityEstimate{device_id, - /*distanceMeters=*/0.0, - MeasurementConfidence::Unknown, - /*elapsedRealtime=*/0, - ProximityState::Unknown, - PresenceDataSource::Ble}; - ProximityEstimate old_proximity_estimate = - current_proximity_estimates_.contains(device_id) - ? current_proximity_estimates_[device_id] - : default_proximity_estimate; - ProximityEstimate new_proximity_estimate = default_proximity_estimate; - int status_code = update_ble_scan_result( - presence_detector_handle_, ble_scan_result, &new_proximity_estimate); - if (status_code == kNoComputedProximityEstimate) { - LOG(INFO) << "Insufficient number of scan results available to " - "compute proximity state"; - return absl::OkStatus(); - } - if (status_code == kSuccess) { - current_proximity_estimates_[device_id] = new_proximity_estimate; - CheckPresenceZoneChanged(device_id, old_proximity_estimate, - new_proximity_estimate); - return absl::OkStatus(); - } - LOG(WARNING) - << "Could not successfully update FPP with new scan result: Error code=" - << status_code; - return absl::InternalError(GetStatusStringFromCode(status_code)); -} - -void FppManager::RegisterZoneTransitionListener( - uint64_t callback_id, ZoneTransitionCallback callback) { - zone_transition_callbacks_[callback_id] = std::move(callback); -} - -void FppManager::UnregisterZoneTransitionListener(uint64_t callback_id) { - zone_transition_callbacks_.erase(callback_id); -} - -void FppManager::ResetProximityStateData() { - current_proximity_estimates_.clear(); -} - -std::optional FppManager::GetRangingData(uint64_t device_id) { - return ConvertProximityEstimateToRangingData( - current_proximity_estimates_[device_id]); -} - -// Converts FPP ProximityEstimate struct to NP RangingData struct -RangingData FppManager::ConvertProximityEstimateToRangingData( - ProximityEstimate estimate) { - RangingMeasurement ranging_measurement = { - /*confidenceLevel=*/0.0, static_cast(estimate.distance_meters)}; - RangingPosition ranging_position = { - ranging_measurement, /*azimuth=*/std::nullopt, - /*elevation=*/std::nullopt, estimate.elapsed_real_time_millis}; - ZoneTransition zone_transition = { - ConvertProximityStateToRangeType(estimate.proximity_state), - /*confidenceLevel=*/0.0}; - return {DataSource::kBle, ranging_position, zone_transition, - std::vector()}; -} - -void FppManager::CheckPresenceZoneChanged(uint64_t device_id, - ProximityEstimate old_estimate, - ProximityEstimate new_estimate) { - if (old_estimate.proximity_state != new_estimate.proximity_state) { - LOG(WARNING) << "Updating zone transition callbacks with new zone. Zone=" - << static_cast(new_estimate.proximity_state); - for (auto& pair : zone_transition_callbacks_) { - pair.second.on_proximity_zone_changed( - device_id, - ConvertProximityStateToRangeType(new_estimate.proximity_state)); - } - } -} - -std::string FppManager::GetStatusStringFromCode(int status_code) { - switch (status_code) { - case kInvalidPresenceDetectorHandleError: - return "INVALID_PRESENCE_DETECTOR_HANDLE"; - case kNullOutputParameterError: - return "NULL_OUTPUT_PARAMETER"; - default: - LOG(WARNING) << "Error code is unknown"; - return "UNKNOWN_ERROR"; - } -} - -} // namespace presence -} // namespace nearby diff --git a/presence/fpp/fpp_manager.h b/presence/fpp/fpp_manager.h deleted file mode 100644 index cecdb21e..00000000 --- a/presence/fpp/fpp_manager.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2023 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 -// -// http://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_PRESENCE_FPP_FPP_MANAGER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_FPP_FPP_MANAGER_H_ - -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "presence/fpp/fpp_c_ffi/include/presence_detector.h" -#include "presence/implementation/sensor_fusion.h" -#include "presence/presence_zone.h" - -namespace nearby { -namespace presence { - -// Manages fused presence updates and serves as a sync -> async converter class -// between fpp and NP sensor fusion -class FppManager { - public: - using RangeType = PresenceZone::DistanceBoundary::RangeType; - - FppManager() { presence_detector_handle_ = presence_detector_create(); } - ~FppManager() { presence_detector_free(presence_detector_handle_); } - - /** Updates FPP with new BLE scan results. Returns status code */ - absl::Status UpdateBleScanResult(uint64_t device_id, - std::optional txPower, int rssi, - uint64_t elapsed_realtime_millis); - /** - * Adds callback for updates of proximity zone transitions. - */ - void RegisterZoneTransitionListener(uint64_t callback_id, - ZoneTransitionCallback callback); - - /** - * Unregister callback for updates of proximity zone transitions. - */ - void UnregisterZoneTransitionListener(uint64_t callback_id); - - /** - * Clears all proximity state data - */ - void ResetProximityStateData(); - - /* - * Converts ProximityEstimate to a NP compatible struct - */ - RangingData ConvertProximityEstimateToRangingData(ProximityEstimate estimate); - - /** - * Gets the most recent ranging data for a given device - */ - std::optional GetRangingData(uint64_t device_id); - - /* - * Converts a status code to a string representation - */ - std::string GetStatusStringFromCode(int status_code); - - private: - void CheckPresenceZoneChanged(uint64_t device_id, - ProximityEstimate old_estimate, - ProximityEstimate new_estimate); - absl::flat_hash_map current_proximity_estimates_; - absl::flat_hash_map - zone_transition_callbacks_; - PresenceDetectorHandle presence_detector_handle_; -}; -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_FPP_FPP_MANAGER_H_ diff --git a/presence/fpp/fpp_manager_test.cc b/presence/fpp/fpp_manager_test.cc deleted file mode 100644 index 6911e06f..00000000 --- a/presence/fpp/fpp_manager_test.cc +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -#include "presence/fpp/fpp_manager.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "presence/implementation/sensor_fusion.h" - -namespace nearby { -namespace presence { -namespace { -constexpr uint64_t kDeviceId = 1234; -constexpr int kReachRssi = -40; -constexpr int kShortRangeRssi = -60; -constexpr int kCallbackId = 12345; - -TEST(FppManager, UpdateBleScanResultSuccess) { - FppManager manager; - bool callback_called = false; - manager.RegisterZoneTransitionListener( - kCallbackId, - {.on_proximity_zone_changed = - [&callback_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - callback_called = true; - }}); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/0)); - // State is only computed after second consecutive scan is fulfilled - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/2000)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); - EXPECT_TRUE(callback_called); -} - -TEST(FppManager, ZoneTransitionDetected) { - FppManager manager; - bool callback_called = false; - manager.RegisterZoneTransitionListener( - kCallbackId, - {.on_proximity_zone_changed = - [&callback_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - callback_called = true; - }}); - // ProximityEstimate is only computed after consecutive scans is fulfilled - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/2000)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); - EXPECT_TRUE(callback_called); - callback_called = false; - - // Update with new zone - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kShortRangeRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); - EXPECT_FALSE(callback_called); - // Update with consecutive scan of new zone - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kShortRangeRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kFar); - EXPECT_TRUE(callback_called); -} - -TEST(FppManager, ConvertProximityEstimateToRangingData) { - FppManager manager; - ProximityEstimate proximity_estimate = - ProximityEstimate{kDeviceId, - 0.1, - MeasurementConfidence::Low, - 0, - ProximityState::Reach, - PresenceDataSource::Ble}; - RangingData rangingData = - manager.ConvertProximityEstimateToRangingData(proximity_estimate); - EXPECT_EQ(rangingData.data_source, DataSource::kBle); - EXPECT_EQ(rangingData.position.distance.value, 0.1f); - EXPECT_EQ(rangingData.zone_transition->confidence_level, 0.0f); - EXPECT_EQ(rangingData.zone_transition->distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); - ProximityEstimate unknown_proximity_estimate = - ProximityEstimate{kDeviceId, - 0.0, - MeasurementConfidence::Low, - 0, - ProximityState::Unknown, - PresenceDataSource::Ble}; - RangingData unknown_rangingData = - manager.ConvertProximityEstimateToRangingData(unknown_proximity_estimate); - EXPECT_EQ(unknown_rangingData.zone_transition->distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kRangeUnknown); - ProximityEstimate tap_proximity_estimate = - ProximityEstimate{kDeviceId, - 0.03, - MeasurementConfidence::Low, - 0, - ProximityState::Tap, - PresenceDataSource::Ble}; - RangingData tap_rangingData = - manager.ConvertProximityEstimateToRangingData(tap_proximity_estimate); - EXPECT_EQ(tap_rangingData.zone_transition->distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinTap); -} - -TEST(FppManager, UpdateBleScanResultWithTxPowerSuccess) { - FppManager manager; - bool callback_called = false; - manager.RegisterZoneTransitionListener( - kCallbackId, - {.on_proximity_zone_changed = - [&callback_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - callback_called = true; - }}); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/20, kReachRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/20, kReachRssi, - /*elapsed_real_time_millis=*/2000)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinTap); - EXPECT_TRUE(callback_called); -} - -TEST(FppManager, UnregisterZoneTransitionListener) { - FppManager manager; - bool callback_called = false; - manager.RegisterZoneTransitionListener( - kCallbackId, - {.on_proximity_zone_changed = - [&callback_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - callback_called = true; - }}); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/2000)); - EXPECT_TRUE(callback_called); - callback_called = false; - - // Unregister listener and update with new zone - manager.UnregisterZoneTransitionListener(kCallbackId); - EXPECT_EQ(manager - .UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kShortRangeRssi, - /*elapsed_real_time_millis=*/0) - .code(), - absl::StatusCode::kInternal); - EXPECT_EQ(manager - .UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kShortRangeRssi, - /*elapsed_real_time_millis=*/0) - .code(), - absl::StatusCode::kInternal); - EXPECT_FALSE(callback_called); -} - -TEST(FppManager, ResetProximityStateData) { - FppManager manager; - bool callback_called = false; - manager.RegisterZoneTransitionListener( - kCallbackId, - {.on_proximity_zone_changed = - [&callback_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - callback_called = true; - }}); - ASSERT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/0)); - // State is only computed after second consecutive scan is fulfilled - ASSERT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/2000)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); - EXPECT_TRUE(callback_called); - - // Reset proximity state data - manager.ResetProximityStateData(); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kRangeUnknown); -} - -TEST(FppManager, GetStatusStringFromCode) { - FppManager manager; - EXPECT_EQ(manager.GetStatusStringFromCode(101), - "INVALID_PRESENCE_DETECTOR_HANDLE"); - EXPECT_EQ(manager.GetStatusStringFromCode(102), "NULL_OUTPUT_PARAMETER"); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/fpp/sensor_fusion_impl.cc b/presence/fpp/sensor_fusion_impl.cc deleted file mode 100644 index 2bda18b5..00000000 --- a/presence/fpp/sensor_fusion_impl.cc +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -#include "presence/fpp/sensor_fusion_impl.h" - -#include -#include -#include - -#include "absl/status/status.h" -#include "presence/fpp/fpp_manager.h" - -namespace nearby { -namespace presence { -std::vector SensorFusionImpl::GetDataSources( - uint64_t elapsed_realtime_millis, - const std::vector& available_sources) { - // TODO(b/264547688) - Implement - return std::vector(); -} -absl::Status SensorFusionImpl::UpdateBleScanResult( - uint64_t device_id, std::optional txPower, int rssi, - uint64_t elapsed_realtime_millis) { - return fpp_manager_.UpdateBleScanResult(device_id, txPower, rssi, - elapsed_realtime_millis); -} -void SensorFusionImpl::UpdateUwbRangingResult(uint64_t device_id, - RangingPosition position) { - // TODO(b/264547688) - Implement -} - -void SensorFusionImpl::RequestZoneTransitionUpdates( - ZoneTransitionCallback callback) { - int callback_id = ++id_generator_; - callback.on_callback_id_generated(callback_id); - fpp_manager_.RegisterZoneTransitionListener(callback_id, std::move(callback)); -} - -void SensorFusionImpl::RequestDeviceMotionUpdates( - SensorFusion::DeviceMotionCallback callback) { - // TODO(b/264547688) - Implement -} -void SensorFusionImpl::RemoveDeviceMotionUpdates( - SensorFusion::DeviceMotionCallback callback) { - // TODO(b/264547688) - Implement -} - -void SensorFusionImpl::RemoveZoneTransitionUpdates(uint64_t callback_id) { - fpp_manager_.UnregisterZoneTransitionListener(callback_id); -} - -std::optional SensorFusionImpl::GetRangingData( - uint64_t device_id) { - return fpp_manager_.GetRangingData(device_id); -} -} // namespace presence -} // namespace nearby diff --git a/presence/fpp/sensor_fusion_impl.h b/presence/fpp/sensor_fusion_impl.h deleted file mode 100644 index ac37b6a8..00000000 --- a/presence/fpp/sensor_fusion_impl.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2023 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 -// -// http://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_PRESENCE_FPP_SENSOR_FUSION_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_FPP_SENSOR_FUSION_IMPL_H_ - -#include -#include - -#include "presence/fpp/fpp_manager.h" -#include "presence/implementation/sensor_fusion.h" - -namespace nearby { -namespace presence { - -class SensorFusionImpl : public SensorFusion { - public: - ~SensorFusionImpl() = default; - std::vector GetDataSources( - uint64_t elapsed_realtime_millis, - const std::vector& available_sources) override; - absl::Status UpdateBleScanResult(uint64_t device_id, - std::optional txPower, int rssi, - uint64_t elapsed_realtime_millis) override; - void UpdateUwbRangingResult(uint64_t device_id, - RangingPosition position) override; - void RequestZoneTransitionUpdates(ZoneTransitionCallback callback) override; - void RemoveZoneTransitionUpdates(uint64_t callback_id) override; - void RequestDeviceMotionUpdates(DeviceMotionCallback callback) override; - void RemoveDeviceMotionUpdates(DeviceMotionCallback callback) override; - std::optional GetRangingData(uint64_t device_id) override; - - private: - FppManager fpp_manager_; - int id_generator_ = 0; -}; -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_FPP_SENSOR_FUSION_IMPL_H_ diff --git a/presence/fpp/sensor_fusion_test.cc b/presence/fpp/sensor_fusion_test.cc deleted file mode 100644 index aee34d7b..00000000 --- a/presence/fpp/sensor_fusion_test.cc +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2023 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 -// -// http://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. - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "presence/fpp/sensor_fusion_impl.h" - -namespace nearby { -namespace presence { -namespace { -constexpr uint64_t kDeviceId = 1234; -constexpr int kReachRssi = -40; - -TEST(SensorFusion, RequestZoneTransitionUpdatesSuccess) { - SensorFusionImpl sensor_fusion_impl; - bool callback_called = false; - bool callback2_called = false; - sensor_fusion_impl.RequestZoneTransitionUpdates( - {.on_callback_id_generated = [&callback_called](uint64_t callback_id) { - callback_called = true; - EXPECT_EQ(callback_id, 1); - }}); - sensor_fusion_impl.RequestZoneTransitionUpdates( - {.on_callback_id_generated = [&callback2_called](uint64_t callback_id2) { - callback2_called = true; - EXPECT_EQ(callback_id2, 2); - }}); - EXPECT_TRUE(callback2_called); -} - -TEST(SensorFusion, RemoveZoneTransitionUpdates) { - SensorFusionImpl sensor_fusion_impl; - bool callback_called = false; - sensor_fusion_impl.RequestZoneTransitionUpdates( - {.on_callback_id_generated = [&callback_called](uint64_t callback_id) { - callback_called = true; - EXPECT_EQ(callback_id, 1); - }}); - sensor_fusion_impl.RemoveZoneTransitionUpdates(1); - EXPECT_EQ( - sensor_fusion_impl - .UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, kReachRssi, - /*elapsed_real_time_millis=*/0) - .code(), - absl::StatusCode::kInternal); -} - -TEST(SensorFusion, UpdateBleScanResult) { - SensorFusionImpl sensor_fusion_impl; - bool proximity_zone_changed_called = false; - sensor_fusion_impl.RequestZoneTransitionUpdates( - {.on_proximity_zone_changed = - [&proximity_zone_changed_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - proximity_zone_changed_called = true; - }}); - EXPECT_OK(sensor_fusion_impl.UpdateBleScanResult( - kDeviceId, /*txPower=*/std::nullopt, kReachRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_OK(sensor_fusion_impl.UpdateBleScanResult( - kDeviceId, /*txPower=*/std::nullopt, kReachRssi, - /*elapsed_real_time_millis=*/0)); - - EXPECT_TRUE(proximity_zone_changed_called); -} - -TEST(SensorFusion, GetRangingData) { - SensorFusionImpl sensor_fusion_impl; - bool proximity_zone_changed_called = false; - sensor_fusion_impl.RequestZoneTransitionUpdates( - {.on_proximity_zone_changed = - [&proximity_zone_changed_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - proximity_zone_changed_called = true; - }}); - EXPECT_OK(sensor_fusion_impl.UpdateBleScanResult( - kDeviceId, /*txPower=*/std::nullopt, kReachRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_OK(sensor_fusion_impl.UpdateBleScanResult( - kDeviceId, /*txPower=*/std::nullopt, kReachRssi, - /*elapsed_real_time_millis=*/0)); - - EXPECT_TRUE(proximity_zone_changed_called); - - EXPECT_EQ(sensor_fusion_impl.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); -} -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/BUILD b/presence/implementation/BUILD deleted file mode 100644 index 5afccce1..00000000 --- a/presence/implementation/BUILD +++ /dev/null @@ -1,493 +0,0 @@ -# Copyright 2020 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. - -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -licenses(["notice"]) - -filegroup( - name = "presence_internal_common_srcs", - srcs = [ - "action_factory.cc", - "advertisement_factory.cc", - "advertisement_filter.cc", - "base_broadcast_request.cc", - "broadcast_manager.cc", - "connection_authenticator_impl.cc", - "credential_manager_impl.cc", - "ldt.cc", - "scan_manager.cc", - "service_controller_impl.cc", - ], -) - -filegroup( - name = "presence_internal_common_hdrs", - srcs = [ - "action_factory.h", - "advertisement_decoder.h", - "advertisement_decoder_impl.h", - "advertisement_factory.h", - "advertisement_filter.h", - "base_broadcast_request.h", - "broadcast_manager.h", - "connection_authenticator.h", - "connection_authenticator_impl.h", - "credential_manager.h", - "credential_manager_impl.h", - "ldt.h", - "scan_manager.h", - "service_controller.h", - "service_controller_impl.h", - ], -) - -cc_library( - name = "internal", - srcs = [ - "advertisement_decoder_rust_impl.cc", - ":presence_internal_common_srcs", - ], - hdrs = [ - "advertisement_decoder_rust_impl.h", - ":presence_internal_common_hdrs", - ], - defines = ["USE_RUST_DECODER=1"], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - "//internal/crypto", - "//internal/crypto_cros", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:logging", - "//internal/platform:types", - "//internal/platform:uuid", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "//presence:types", - "//presence/implementation/mediums", - "@beto-core//:ldt_np_adv_ffi", - "@beto-core//:np_c_ffi_types", - "@beto-core//:np_cpp_ffi", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/container:flat_hash_set", - "@com_google_absl//absl/hash", - "@com_google_absl//absl/log:check", - "@com_google_absl//absl/log:die_if_null", - "@com_google_absl//absl/random", - "@com_google_absl//absl/random:distributions", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/strings:str_format", - "@com_google_absl//absl/synchronization", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:optional", - "@com_google_absl//absl/types:span", - "@com_google_absl//absl/types:variant", - ], -) - -cc_library( - name = "internal_deprecated", - srcs = [ - "advertisement_decoder_impl.cc", - ":presence_internal_common_srcs", - ], - hdrs = [ - "advertisement_decoder_impl.h", - ":presence_internal_common_hdrs", - ], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - "//devtools/rust:rust_okay_here", - "//internal/crypto", - "//internal/crypto_cros", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:logging", - "//internal/platform:types", - "//internal/platform:uuid", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "//presence:types", - "//presence/implementation/mediums", - "@beto-core//:ldt_np_adv_ffi", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/container:flat_hash_set", - "@com_google_absl//absl/hash", - "@com_google_absl//absl/log:check", - "@com_google_absl//absl/log:die_if_null", - "@com_google_absl//absl/random", - "@com_google_absl//absl/random:distributions", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/strings:str_format", - "@com_google_absl//absl/synchronization", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:optional", - "@com_google_absl//absl/types:span", - "@com_google_absl//absl/types:variant", - ], -) - -cc_library( - name = "sensor_fusion", - hdrs = ["sensor_fusion.h"], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - "//presence:types", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - ], -) - -cc_library( - name = "internal_test", - testonly = True, - srcs = [ - ], - hdrs = [ - "mock_connection_authenticator.h", - "mock_credential_manager.h", - "mock_service_controller.h", - ], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - ":internal", - "//internal/platform/implementation:comm", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings:string_view", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "advertisement_decoder_test", - size = "small", - srcs = ["advertisement_decoder_test.cc"], - deps = [ - ":internal_deprecated", - "//internal/platform:base", - "//internal/proto:credential_cc_proto", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "advertisement_decoder_new_format_test", - size = "small", - srcs = ["advertisement_decoder_new_format_test.cc"], - deps = [ - ":internal", - "//internal/platform:base", - "//internal/proto:credential_cc_proto", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "advertisement_filter_test", - size = "small", - srcs = ["advertisement_filter_test.cc"], - deps = [ - ":internal", - "//internal/platform:base", - "//internal/proto:credential_cc_proto", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "advertisement_factory_test", - size = "small", - srcs = ["advertisement_factory_test.cc"], - deps = [ - ":internal", - "//internal/platform:base", - "//internal/proto:credential_cc_proto", - "//presence:types", - "//presence/implementation/mediums", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "broadcast_manager_test", - size = "small", - srcs = ["broadcast_manager_test.cc"], - deps = [ - ":internal", - "//internal/platform:base", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/proto:credential_cc_proto", - "//presence/implementation/mediums", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "ldt_test", - size = "small", - srcs = ["ldt_test.cc"], - deps = [ - ":internal", - "//internal/platform:base", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "base_broadcast_request_test", - srcs = ["base_broadcast_request_test.cc"], - deps = [ - ":internal", - "//internal/proto:credential_cc_proto", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/types:variant", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "action_factory_test", - size = "small", - srcs = ["action_factory_test.cc"], - deps = [ - ":internal", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "connection_authenticator_impl_test", - size = "small", - srcs = ["connection_authenticator_impl_test.cc"], - deps = [ - ":internal", - "//internal/crypto", - "//internal/crypto_cros", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "//presence/proto:presence_frame_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "credential_manager_impl_test", - size = "small", - srcs = ["credential_manager_impl_test.cc"], - deps = [ - ":internal", - "//internal/platform:comm", - "//internal/platform:logging", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//net/proto2/contrib/parse_proto:testing", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "scan_manager_test", - size = "small", - srcs = ["scan_manager_test.cc"], - deps = [ - ":internal", - ":internal_test", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:logging", - "//internal/platform:mac_address", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//presence:types", - "//presence/implementation/mediums", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:variant", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "service_controller_impl_test", - size = "small", - srcs = ["service_controller_impl_test.cc"], - deps = [ - ":internal", - ":internal_test", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//net/proto2/contrib/parse_proto:testing", - "//presence/implementation/mediums", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) diff --git a/presence/implementation/action_factory.cc b/presence/implementation/action_factory.cc deleted file mode 100644 index fe4a6e45..00000000 --- a/presence/implementation/action_factory.cc +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/action_factory.h" - -#include -#include -#include - -#include "internal/platform/logging.h" -#include "presence/data_element.h" -#include "presence/implementation/base_broadcast_request.h" - -namespace nearby { -namespace presence { - -constexpr int kContentTimestampMask = 0x0F; -constexpr int kContentTimestampShift = 28; -constexpr int kEmptyMask = 0; -constexpr int kActionSizeInBits = 32; - -namespace { - -int GetActionMask(ActionBit action) { - int bit = static_cast(action); - if (bit < 0 || bit >= kActionSizeInBits) { - LOG(WARNING) << "Unsupported action " << static_cast(action); - return kEmptyMask; - } - return 1 << (kActionSizeInBits - 1 - bit); -} - -// The reverse of `GetActionMask()` -ActionBit GetActionFromBit(int bit) { - return ActionBit(kActionSizeInBits - 1 - bit); -} - -int GetMask(const DataElement& element) { - int type = element.GetType(); - switch (type) { - case DataElement::kContextTimestampFieldType: { - auto value = element.GetValue(); - if (!value.empty()) { - return (value[0] & kContentTimestampMask) << kContentTimestampShift; - } else { - LOG(WARNING) << "Context timestamp Data Element without value"; - return kEmptyMask; - } - } - case DataElement::kActionFieldType: { - if (element.GetValue().empty()) { - LOG(WARNING) << "Action Data Element without value"; - return kEmptyMask; - } - return GetActionMask(ActionBit(element.GetValue()[0])); - } - } - LOG(WARNING) << "Data Element " << type - << " not supported in base advertisement"; - return kEmptyMask; -} - -} // namespace - -Action ActionFactory::CreateAction( - const std::vector& data_elements) { - Action action = {.action = 0}; - std::for_each(data_elements.begin(), data_elements.end(), - [&](const auto& element) { - int mask = GetMask(element); - action.action |= mask; - }); - return action; -} - -void ActionFactory::DecodeAction(const Action& action, - std::vector& output) { - uint8_t context_timestamp = - (action.action >> kContentTimestampShift) & kContentTimestampMask; - if (context_timestamp) { - output.emplace_back(DataElement::kContextTimestampFieldType, - context_timestamp); - } - constexpr int kFirstUsedBit = - kActionSizeInBits - static_cast(ActionBit::kLastAction); - for (int i = kFirstUsedBit; i < kContentTimestampShift; i++) { - int bit_mask = 1 << i; - if (action.action & bit_mask) { - output.emplace_back(DataElement(GetActionFromBit(i))); - } - } -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/action_factory.h b/presence/implementation/action_factory.h deleted file mode 100644 index b2a43880..00000000 --- a/presence/implementation/action_factory.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2022 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_PRESENCE_IMPLEMENTATION_ACTION_FACTORY_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ACTION_FACTORY_H_ - -#include - -#include "presence/data_element.h" -#include "presence/implementation/base_broadcast_request.h" - -namespace nearby { -namespace presence { - -// Defines the mapping between Data Elements and Actions in the Base NP -// advertisement. -class ActionFactory { - public: - // Returns an Action for Base NP advertisement from a collection of Data - // Elements. Data Elements unsupported in the Base NP advertisement are - // ignored. - static Action CreateAction(const std::vector& data_elements); - - // Decodes a Base NP Action into a list of Data Elements. The Data Elements - // are appended to the `output` list. - // - // DecodeAction is effectively a reverse operation of CreateAction. - static void DecodeAction(const Action& action, - std::vector& output); -}; -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ACTION_FACTORY_H_ diff --git a/presence/implementation/action_factory_test.cc b/presence/implementation/action_factory_test.cc deleted file mode 100644 index 63db1990..00000000 --- a/presence/implementation/action_factory_test.cc +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/action_factory.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "presence/data_element.h" -#include "presence/implementation/base_broadcast_request.h" - -namespace nearby { -namespace presence { -namespace { - -using ::testing::ElementsAre; - -constexpr uint32_t kActiveUnlockBitMask = 1 << 23; -constexpr uint32_t kFastPairBitMask = 1 << 17; - -TEST(ActionFactory, CreateActiveUnlockAction) { - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - - Action action = ActionFactory::CreateAction(data_elements); - - EXPECT_EQ(action.action, kActiveUnlockBitMask); -} - -TEST(ActionFactory, CreateActiveIgnoresUnsupportedActions) { - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - // The action is 32 bit, so the valid range is [0-31] - data_elements.emplace_back(ActionBit(-1)); - data_elements.emplace_back(ActionBit(32)); - Action action = ActionFactory::CreateAction(data_elements); - - EXPECT_EQ(action.action, kActiveUnlockBitMask); -} - -TEST(ActionFactory, CreateContextTimestamp) { - const std::string kTimestamp = absl::HexStringToBytes("0B"); - - std::vector data_elements; - data_elements.emplace_back(DataElement::kContextTimestampFieldType, - kTimestamp); - - Action action = ActionFactory::CreateAction(data_elements); - - EXPECT_EQ(action.action, 0x0BU << 28); -} - -TEST(ActionFactory, CreateContextTimestampAndFastPair) { - const std::string kTimestamp = absl::HexStringToBytes("0B"); - - std::vector data_elements; - data_elements.emplace_back(DataElement::kContextTimestampFieldType, - kTimestamp); - data_elements.emplace_back(ActionBit::kFastPairSassAction); - - Action action = ActionFactory::CreateAction(data_elements); - - EXPECT_EQ(action.action, (0x0BU << 28) | kFastPairBitMask); -} - -TEST(ActionFactory, DecodeActiveUnlockAction) { - constexpr Action kAction = {.action = kActiveUnlockBitMask}; - std::vector data_elements; - - ActionFactory::DecodeAction(kAction, data_elements); - - EXPECT_THAT( - data_elements, - ElementsAre(DataElement(DataElement(ActionBit::kActiveUnlockAction)))); -} - -TEST(ActionFactory, DecodeContextTimestampAndFastPair) { - constexpr Action kAction = {.action = (0x0BU << 28) | kFastPairBitMask}; - std::vector data_elements; - - ActionFactory::DecodeAction(kAction, data_elements); - - EXPECT_THAT( - data_elements, - ElementsAre(DataElement(DataElement::kContextTimestampFieldType, - absl::HexStringToBytes("0B")), - DataElement(DataElement(ActionBit::kFastPairSassAction)))); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_decoder.h b/presence/implementation/advertisement_decoder.h deleted file mode 100644 index 3c5d444b..00000000 --- a/presence/implementation/advertisement_decoder.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2024 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_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_DECODER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_DECODER_H_ - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" - -namespace nearby { -namespace presence { - -// The structured decoded form of a detected Nearby Presence advertisement -struct Advertisement { - uint8_t version = 0; - std::vector data_elements; - absl::StatusOr public_credential = - absl::NotFoundError(""); - internal::IdentityType identity_type = internal::IDENTITY_TYPE_UNSPECIFIED; - std::string metadata_key; -}; - -// Interface for decoding Nearby Presence advertisements from a payload of raw -// bytes into a structured, decrypted, and decoded format -class AdvertisementDecoder { - public: - // Is needed otherwise deleting an instance via a pointer to a base class - // results in undefined behavior - virtual ~AdvertisementDecoder() = default; - - // Returns the structured and decoded contents of an advertisement given a - // payload of bytes as a string. Returns an error if the advertisement is - // misformatted or if it couldn't be decrypted. - virtual absl::StatusOr DecodeAdvertisement( - absl::string_view advertisement) = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_DECODER_H_ diff --git a/presence/implementation/advertisement_decoder_impl.cc b/presence/implementation/advertisement_decoder_impl.cc deleted file mode 100644 index fec04c85..00000000 --- a/presence/implementation/advertisement_decoder_impl.cc +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/advertisement_decoder_impl.h" - -#include -#include -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/escaping.h" -#include "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#include "internal/platform/logging.h" -#include "presence/data_element.h" -#include "presence/implementation/action_factory.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/ldt.h" - -namespace nearby { -namespace presence { - -namespace { - -constexpr uint8_t kDataTypeMask = - (1 << DataElement::kDataElementLengthShift) - 1; - -constexpr int kAdvertisementVersion = 0; - -constexpr int kEncryptedIdentityAdditionalLength = - kSaltSize + kBaseMetadataSize; -constexpr int kEddystoneAdditionalLength = 20; - -uint8_t GetDataElementType(uint8_t header) { return header & kDataTypeMask; } - -size_t GetDataElementLength(uint8_t header) { - return header >> DataElement::kDataElementLengthShift; -} - -// Verifies if the DE header describes a valid DE in v0 advertisement. -bool IsDataElementAllowed(uint8_t header) { - uint8_t data_type = GetDataElementType(header); - size_t length = GetDataElementLength(header); - switch (data_type) { - case DataElement::kSaltFieldType: - return length == 2; - case DataElement::kPublicIdentityFieldType: - return length == 0; - case DataElement::kPrivateGroupIdentityFieldType: - case DataElement::kContactsGroupIdentityFieldType: - return length >= 2 && length <= 6; - case DataElement::kTxPowerFieldType: - return length == 1; - case DataElement::kActionFieldType: - return length >= 1 && length <= 3; - case DataElement::kModelIdFieldType: - return length == 3; - case DataElement::kEddystoneIdFieldType: - return length == 0; - case DataElement::kAccountKeyDataFieldType: - return length <= 12; - case DataElement::kConnectionStatusFieldType: - return length <= 3; - case DataElement::kBatteryFieldType: - return length <= 3; - default: - return false; - } -} - -bool IsEncryptedIdentity(int data_type) { - return data_type == DataElement::kPrivateGroupIdentityFieldType || - data_type == DataElement::kContactsGroupIdentityFieldType; -} - -bool IsIdentity(int data_type) { - return data_type == DataElement::kPublicIdentityFieldType || - IsEncryptedIdentity(data_type); -} - -internal::IdentityType GetIdentityType(int data_type) { - switch (data_type) { - case DataElement::kPrivateGroupIdentityFieldType: - return internal::IDENTITY_TYPE_PRIVATE_GROUP; - case DataElement::kContactsGroupIdentityFieldType: - return internal::IDENTITY_TYPE_CONTACTS_GROUP; - case DataElement::kPublicIdentityFieldType: - return internal::IDENTITY_TYPE_PUBLIC; - } - return internal::IDENTITY_TYPE_UNSPECIFIED; -} - -// Returns the real length of a DE in v0 advertisement, which may be larger than -// the value in the header. -size_t GetDataElementTrueLength(uint8_t header) { - uint8_t data_type = GetDataElementType(header); - size_t length = GetDataElementLength(header); - if (IsEncryptedIdentity(data_type)) { - // The length of an encrypted DE is 16 bytes of overhead (salt + metadata - // key) + the actual payload, which is too long to fit in the 4-bit DE - // length field. - length += kEncryptedIdentityAdditionalLength; - } else if (data_type == DataElement::kEddystoneIdFieldType) { - // Length in the header is set to EID length minus 20, because EID is longer - // than 15 (the maximum length that can be stored in 4 bits. - length += kEddystoneAdditionalLength; - } - return length; -} - -absl::StatusOr ParseDataElement(const absl::string_view input, - size_t& index) { - if (index >= input.size()) { - return absl::OutOfRangeError(absl::StrFormat( - "Data element (%s) is %d bytes long. Expected more than %d", - absl::BytesToHexString(input), input.size(), index)); - } - uint8_t header = input[index]; - if (!IsDataElementAllowed(header)) { - return absl::InvalidArgumentError( - absl::StrFormat("Unsupported Data Element 0x%x", header)); - } - uint8_t data_type = GetDataElementType(header); - size_t length = GetDataElementTrueLength(header); - ++index; - size_t start = index; - index += length; - if (index > input.size()) { - return absl::OutOfRangeError(absl::StrFormat( - "Data element (%s) is %d bytes long. Expected at least %d", - absl::BytesToHexString(input), input.size(), index)); - } - VLOG(1) << "Type: " << static_cast(data_type) - << " length: " << static_cast(length) - << " DE: " << absl::BytesToHexString(input.substr(start, length)); - return DataElement(data_type, input.substr(start, length)); -} -} // namespace - -void DecodeBaseAction(absl::string_view serialized_action, - Advertisement& decoded_advertisement) { - if (serialized_action.empty() || serialized_action.size() > 3) { - LOG(WARNING) << "Base NP action \'" - << absl::BytesToHexString(serialized_action) - << "\' has wrong length " << serialized_action.size() - << " , expected size in range [1 - 3]"; - return; - } - // Action, 0-2 bytes in Big Endian order. - Action action = {.action = 0}; - for (int i = 0; i < serialized_action.size(); ++i) { - int offset = (sizeof(uint32_t) - 1 - i) * 8; - action.action |= serialized_action[i] << offset; - } - - ActionFactory::DecodeAction(action, decoded_advertisement.data_elements); -} - -absl::StatusOr DecryptLdt( - const std::vector& credentials, - absl::string_view salt, absl::string_view encrypted_contents, - Advertisement& decoded_advertisement) { - if (credentials.empty()) { - return absl::UnavailableError("No credentials"); - } - for (const auto& credential : credentials) { - absl::StatusOr encryptor = LdtEncryptor::Create( - credential.key_seed(), credential.metadata_encryption_key_tag_v0()); - if (encryptor.ok()) { - absl::StatusOr result = - encryptor->DecryptAndVerify(encrypted_contents, salt); - if (result.ok() && result->size() > kBaseMetadataSize) { - decoded_advertisement.public_credential = credential; - decoded_advertisement.metadata_key = - result->substr(0, kBaseMetadataSize); - return result->substr(kBaseMetadataSize); - } - } - } - return absl::UnavailableError( - "Couldn't decrypt the message with any credentials"); -} - -absl::Status DecryptDataElements( - const std::vector& credentials, - const DataElement& elem, Advertisement& decoded_advertisement) { - if (elem.GetValue().size() <= kEncryptedIdentityAdditionalLength) { - return absl::OutOfRangeError(absl::StrFormat( - "Encrypted identity data element is too short - %d bytes", - elem.GetValue().size())); - } - absl::string_view salt = elem.GetValue().substr(0, kSaltSize); - decoded_advertisement.data_elements.emplace_back(DataElement::kSaltFieldType, - salt); - absl::string_view encrypted = elem.GetValue().substr(kSaltSize); - absl::StatusOr decrypted = - DecryptLdt(credentials, salt, encrypted, decoded_advertisement); - if (!decrypted.ok()) { - LOG(WARNING) << "Failed to decrypt advertisement, status: " - << decrypted.status(); - return decrypted.status(); - } - size_t index = 0; - while (index < decrypted->size()) { - absl::StatusOr internal_elem = - ParseDataElement(*decrypted, index); - if (!internal_elem.ok()) { - LOG(WARNING) << "Failed to read data element, status: " - << internal_elem.status(); - return internal_elem.status(); - } - if (internal_elem->GetType() == DataElement::kActionFieldType) { - DecodeBaseAction(internal_elem->GetValue(), decoded_advertisement); - } else { - decoded_advertisement.data_elements.push_back(*std::move(internal_elem)); - } - } - return absl::OkStatus(); -} - -absl::StatusOr AdvertisementDecoderImpl::DecodeAdvertisement( - absl::string_view advertisement) { - Advertisement decoded_advertisement = Advertisement{}; - std::vector result; - LOG(INFO) << "Advertisement: " << absl::BytesToHexString(advertisement); - if (advertisement.empty()) { - return absl::OutOfRangeError("Empty advertisement"); - } - uint8_t version = advertisement[0]; - VLOG(1) << "Version: " << version; - if (version != kAdvertisementVersion) { - return absl::UnimplementedError(absl::StrFormat( - "Advertisement version (%d) is not supported", version)); - } - decoded_advertisement.version = version; - size_t index = 1; - absl::StatusOr decrypted; - while (index < advertisement.size()) { - absl::StatusOr elem = ParseDataElement(advertisement, index); - if (!elem.ok()) { - LOG(WARNING) << "Failed to read data element, status: " << elem.status(); - return elem.status(); - } - if (IsIdentity(elem->GetType())) { - decoded_advertisement.identity_type = GetIdentityType(elem->GetType()); - } - if (IsEncryptedIdentity(elem->GetType())) { - if (credentials_map_ == nullptr) { - return absl::FailedPreconditionError("Missing credentials"); - } - auto identity_type_specific_creds = - (*credentials_map_)[decoded_advertisement.identity_type]; - absl::Status status = DecryptDataElements(identity_type_specific_creds, - *elem, decoded_advertisement); - if (!status.ok()) { - return status; - } - } else { - if (elem->GetType() == DataElement::kActionFieldType) { - DecodeBaseAction(elem->GetValue(), decoded_advertisement); - } else { - decoded_advertisement.data_elements.push_back(*std::move(elem)); - } - } - } - - return std::move(decoded_advertisement); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_decoder_impl.h b/presence/implementation/advertisement_decoder_impl.h deleted file mode 100644 index c3e7e592..00000000 --- a/presence/implementation/advertisement_decoder_impl.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2022 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_PRESENCE_ADVERTISEMENT_DECODER_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_DECODER_IMPL_H_ - -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "presence/implementation/advertisement_decoder.h" - -namespace nearby { -namespace presence { - -// Implements the C++ backed parsing and decrypting of advertisement bytes -class AdvertisementDecoderImpl : public AdvertisementDecoder { - public: - AdvertisementDecoderImpl() = default; - explicit AdvertisementDecoderImpl( - absl::flat_hash_map>* - credentials_map) - : credentials_map_(credentials_map) {} - - absl::StatusOr DecodeAdvertisement( - absl::string_view advertisement) override; - - private: - absl::flat_hash_map>* - credentials_map_ = nullptr; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_DECODER_IMPL_H_ diff --git a/presence/implementation/advertisement_decoder_new_format_test.cc b/presence/implementation/advertisement_decoder_new_format_test.cc deleted file mode 100644 index ef78c828..00000000 --- a/presence/implementation/advertisement_decoder_new_format_test.cc +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2022 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. - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/implementation/advertisement_decoder_rust_impl.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::ByteArray; // NOLINT -using ::nearby::internal::IdentityType; // NOLINT -using ::nearby::internal::SharedCredential; // NOLINT -using ::testing::ElementsAre; -using ::testing::status::StatusIs; - -TEST(AdvertisementDecoderImpl, DecodePublicAdvertisement) { - std::string V0AdvPlaintextBytes = - "00" // Adv Header V0 unencrypted - "1503"; // length 1 Tx Power DE value 3 - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(V0AdvPlaintextBytes)); - ASSERT_OK(result); - EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PUBLIC); - EXPECT_EQ(result->version, 0); - EXPECT_THAT(result->data_elements, - ElementsAre(DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("03")))); -} - -TEST(AdvertisementDecoderImpl, DecodePublicAdvertisementMultiDe) { - std::string V0AdvPlaintextMultiDeBytes = - "00" // Adv Header V0 unencrypted - "1505" // length 1 Tx Power DE value 5 - "260040"; // length 2 actions de with NearbyShare bit set - - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - absl::StatusOr result = decoder.DecodeAdvertisement( - absl::HexStringToBytes(V0AdvPlaintextMultiDeBytes)); - ASSERT_OK(result); - EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PUBLIC); - EXPECT_EQ(result->version, 0); - EXPECT_THAT(result->data_elements, - ElementsAre(DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("05")), - DataElement(ActionBit::kNearbyShareAction))); -} - -// V0 encrypted advertisement data - ripped out of np_adv/tests/examples_v0.rs -TEST(AdvertisementDecoderImpl, DecodeEncryptedAdvertisement) { - std::string V0AdvEncryptedBytes = "042222D82212EF16DBF872F2A3A7C0FA5248EC"; - ByteArray seed({ - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - }); - ByteArray known_mac({0x09, 0xFE, 0x9E, 0x81, 0xB7, 0x3E, 0x5E, 0xCC, - 0x76, 0x59, 0x57, 0x71, 0xE0, 0x1F, 0xFB, 0x34, - 0x38, 0xE7, 0x5F, 0x24, 0xA7, 0x69, 0x56, 0xA0, - 0xB8, 0xEA, 0x67, 0xD1, 0x1C, 0x3E, 0x36, 0xFD}); - SharedCredential public_credential; - public_credential.set_key_seed(seed.AsStringView()); - public_credential.set_metadata_encryption_key_tag_v0( - known_mac.AsStringView()); - public_credential.set_id(12345678); - absl::flat_hash_map> - credentials; - credentials[IdentityType::IDENTITY_TYPE_PRIVATE_GROUP].push_back( - public_credential); - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(&credentials); - - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(V0AdvEncryptedBytes)); - ASSERT_OK(result); - EXPECT_EQ(result->public_credential.value().id(), public_credential.id()); - EXPECT_EQ(result->public_credential.value().key_seed(), - public_credential.key_seed()); - EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_EQ(result->version, 0); - EXPECT_THAT(result->data_elements, - ElementsAre(DataElement(DataElement::kSaltFieldType, - absl::HexStringToBytes("2222")), - DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("03")))); -} - -TEST(AdvertisementDecoderImpl, DecodeEncryptedAdvertisementNoCreds) { - std::string V0AdvEncryptedBytes = "042222D82212EF16DBF872F2A3A7C0FA5248EC"; - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(V0AdvEncryptedBytes)); - EXPECT_THAT(result, StatusIs(absl::StatusCode::kUnavailable)); -} - -TEST(AdvertisementDecoderImpl, V1AdvCurrentlyUnsupported) { - std::string V1Adv = - "20" // Version header V1 - "00" // format - "02" // section len - "1503"; // Tx power value 3 - - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(V1Adv)); - EXPECT_THAT(result, StatusIs(absl::StatusCode::kUnimplemented)); -} - -TEST(AdvertisementDecoderImpl, V0InvalidEmptyAdv) { - std::string V1Adv = "00"; - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(V1Adv)); - EXPECT_THAT(result, StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST(AdvertisementDecoderImpl, V0InvalidAdvContents) { - std::string invalid_v0_adv = - "00" // Adv Header V0 unencrypted - "3503"; // length 3 Tx Power DE with only 1 byte - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(invalid_v0_adv)); - EXPECT_THAT(result, StatusIs(absl::StatusCode::kInvalidArgument)); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_decoder_rust_impl.cc b/presence/implementation/advertisement_decoder_rust_impl.cc deleted file mode 100644 index 9ff10320..00000000 --- a/presence/implementation/advertisement_decoder_rust_impl.cc +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/advertisement_decoder_rust_impl.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#include "np_cpp_ffi_types.h" -#include "nearby_protocol.h" -#include "internal/platform/logging.h" -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder.h" - -namespace nearby { -namespace presence { -namespace { - -absl::StatusOr<::nearby_protocol::ActionType> MapAction( - const ActionBit action) { - return ::nearby_protocol::ActionType::TryBuildFromU8( - static_cast(action)); -} - -void AddActionsToAdvertisement(const nearby_protocol::V0Actions& parsed_actions, - Advertisement& advertisement) { - for (const auto action : kAllActionBits) { - auto action_type = MapAction(action); - if (!action_type.ok()) { - LOG(WARNING) << "Advertisement contains an unsupported action bit: " - << (int)action; - continue; - } - if (parsed_actions.HasAction(*action_type)) { - advertisement.data_elements.push_back(DataElement(action)); - } - } -} - -void ProcessDataElement(const nearby_protocol::V0DataElement& data_element, - Advertisement& advertisement) { - switch (data_element.GetKind()) { - case nearby_protocol::V0DataElementKind::TxPower: { - advertisement.data_elements.push_back(DataElement( - DataElement::kTxPowerFieldType, data_element.AsTxPower().GetAsI8())); - return; - } - case nearby_protocol::V0DataElementKind::Actions: { - AddActionsToAdvertisement(data_element.AsActions(), advertisement); - return; - } - default: { - LOG(WARNING) << "Unsupported data element type: " - << (int)data_element.GetKind(); - } - } -} - -internal::IdentityType GetIdentityType( - nearby_protocol::DeserializedV0IdentityKind identity) { - switch (identity) { - case np_ffi::internal::DeserializedV0IdentityKind::Plaintext: - return internal::IdentityType::IDENTITY_TYPE_PUBLIC; - case np_ffi::internal::DeserializedV0IdentityKind::Decrypted: - return internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; - } -} - -absl::StatusOr<::nearby::internal::SharedCredential> FindById( - std::vector<::nearby::internal::SharedCredential> private_credentials, - uint64_t id) { - auto cred = - std::find_if(private_credentials.begin(), private_credentials.end(), - [&id](const auto& x) { return x.id() == id; }); - if (cred == private_credentials.end()) { - return absl::NotFoundError("No credential found with id: " + - std::to_string(id)); - } - return *cred; -} - -absl::Status ProcessLegibleV0Adv( - nearby_protocol::LegibleDeserializedV0Advertisement legible_adv, - std::vector<::nearby::internal::SharedCredential> private_credentials, - Advertisement& advertisement) { - advertisement.identity_type = GetIdentityType(legible_adv.GetIdentityKind()); - - auto num_des = legible_adv.GetNumberOfDataElements(); - auto payload = legible_adv.IntoPayload(); - - // TODO(b/333126765): salt isn't a DE, we should restructure the - // Advertisement struct to reflect this - if (advertisement.identity_type == - internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP) { - auto cred_details = payload.TryGetIdentityDetails(); - if (!cred_details.ok()) { - return cred_details.status(); - } - - advertisement.public_credential = - FindById(private_credentials, cred_details->cred_id); - - // TODO(b/333126765): update salt to use unsigned char * to remove cast - std::string salt(reinterpret_cast(cred_details->salt), 2); - advertisement.data_elements.push_back(DataElement(0x00, salt)); - - std::string metadata_key( - reinterpret_cast(cred_details->identity_token), 14); - advertisement.metadata_key = std::move(metadata_key); - } - - for (int i = 0; i < num_des; i++) { - auto de_result = payload.TryGetDataElement(i); - if (!de_result.ok()) { - return de_result.status(); - } - ProcessDataElement(*de_result, advertisement); - } - return absl::OkStatus(); -} - -absl::Status ProcessV0Advertisement( - nearby_protocol::DeserializedV0Advertisement result, - std::vector<::nearby::internal::SharedCredential> private_credentials, - Advertisement& adv) { - switch (result.GetKind()) { - case nearby_protocol::DeserializedV0AdvertisementKind::Legible: - return ProcessLegibleV0Adv(result.IntoLegible(), private_credentials, - adv); - break; - case nearby_protocol::DeserializedV0AdvertisementKind:: - NoMatchingCredentials: { - return absl::UnavailableError( - "Couldn't decrypt the message with any credentials"); - } - } -} - -} // namespace - -absl::StatusOr AdvertisementDecoderImpl::DecodeAdvertisement( - absl::string_view advertisement) { - auto byte_buffer = nearby_protocol::ByteBuffer< - nearby_protocol::MAX_ADV_PAYLOAD_SIZE>::TryFromString(advertisement); - if (!byte_buffer.ok()) { - return absl::InvalidArgumentError("Invalid length advertisement"); - } - - Advertisement decoded_advertisement; - const nearby_protocol::RawAdvertisementPayload payload(byte_buffer.value()); - auto deserialize_result = - nearby_protocol::Deserializer::DeserializeAdvertisement(payload, - cred_book_); - - switch (deserialize_result.GetKind()) { - case np_ffi::internal::DeserializeAdvertisementResultKind::Error: { - return absl::InvalidArgumentError("Invalid advertisement format"); - } - case np_ffi::internal::DeserializeAdvertisementResultKind::V1: { - return absl::UnimplementedError( - absl::StrFormat("V1 Advertisement format is not supported")); - } - case np_ffi::internal::DeserializeAdvertisementResultKind::V0: { - decoded_advertisement.version = 0; - auto result = - ProcessV0Advertisement(deserialize_result.IntoV0(), - private_credentials_, decoded_advertisement); - if (!result.ok()) { - return result; - } - break; - } - } - - return decoded_advertisement; -} - -nearby_protocol::CredentialBook -AdvertisementDecoderImpl::InitializeCredentialBook( - absl::flat_hash_map>* - credentials_map) { - if (credentials_map == nullptr) { - nearby_protocol::CredentialSlab slab; - nearby_protocol::CredentialBook cred_book(slab); - return cred_book; - } - - nearby_protocol::CredentialSlab slab; - for (const auto& credential : (*credentials_map) - [internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP]) { - // Make sure the vector is not empty, as this is a prerequisite of the Rust - // code we call into. - std::vector metadata_bytes(1); - if (!credential.encrypted_metadata_bytes_v0().empty()) { - metadata_bytes = - std::vector(credential.encrypted_metadata_bytes_v0().begin(), - credential.encrypted_metadata_bytes_v0().end()); - } - nearby_protocol::MatchedCredentialData matched_cred(credential.id(), - metadata_bytes); - - auto key_seed = credential.key_seed(); - std::array key_seed_array; - std::copy(key_seed.begin(), key_seed.end(), key_seed_array.data()); - - auto tag = credential.metadata_encryption_key_tag_v0(); - std::array tag_array; - std::copy(tag.begin(), tag.end(), tag_array.data()); - - auto matchable_credential = nearby_protocol::V0MatchableCredential( - key_seed_array, tag_array, matched_cred); - slab.AddV0Credential(matchable_credential); - } - nearby_protocol::CredentialBook cred_book(slab); - return cred_book; -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_decoder_rust_impl.h b/presence/implementation/advertisement_decoder_rust_impl.h deleted file mode 100644 index b2444e7d..00000000 --- a/presence/implementation/advertisement_decoder_rust_impl.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2022 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_PRESENCE_ADVERTISEMENT_DECODER_RUST_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_DECODER_RUST_IMPL_H_ - -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "nearby_protocol.h" -#include "presence/implementation/advertisement_decoder.h" - -namespace nearby { -namespace presence { - -// Implements the Rust backed parsing and decrypting of advertisement bytes -class AdvertisementDecoderImpl : public AdvertisementDecoder { - public: - AdvertisementDecoderImpl() - : cred_book_(InitializeCredentialBook(nullptr)), - private_credentials_( - std::vector<::nearby::internal::SharedCredential>()) {} - - explicit AdvertisementDecoderImpl( - absl::flat_hash_map>* - credentials_map) - : cred_book_(InitializeCredentialBook(credentials_map)), - private_credentials_( - (*credentials_map) - [internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP]) {} - - absl::StatusOr DecodeAdvertisement( - absl::string_view advertisement) override; - - private: - nearby_protocol::CredentialBook InitializeCredentialBook( - absl::flat_hash_map>* - credentials_map); - nearby_protocol::CredentialBook cred_book_; - std::vector<::nearby::internal::SharedCredential> private_credentials_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_DECODER_IMPL_H_ diff --git a/presence/implementation/advertisement_decoder_test.cc b/presence/implementation/advertisement_decoder_test.cc deleted file mode 100644 index 5b2a70d4..00000000 --- a/presence/implementation/advertisement_decoder_test.cc +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/advertisement_decoder.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder_impl.h" -#include "presence/scan_request.h" -#include "presence/scan_request_builder.h" - -namespace nearby { -namespace presence { - -namespace { -using ::nearby::ByteArray; // NOLINT -using ::nearby::internal::IdentityType; // NOLINT -using ::nearby::internal::SharedCredential; // NOLINT -using ::testing::ElementsAre; -using ::testing::UnorderedElementsAre; -using ::testing::status::StatusIs; - -constexpr absl::string_view kAccountName = "test account"; - -ScanRequest GetScanRequest() { - return {.account_name = std::string(kAccountName), - .identity_types = { - IdentityType::IDENTITY_TYPE_PRIVATE_GROUP, - IdentityType::IDENTITY_TYPE_CONTACTS_GROUP, - IdentityType::IDENTITY_TYPE_PUBLIC, - }}; -} - -ScanRequest GetScanRequest(std::vector credentials) { - LegacyPresenceScanFilter scan_filter = {.remote_public_credentials = - credentials}; - return ScanRequestBuilder() - .SetAccountName(kAccountName) - .AddIdentityType(IdentityType::IDENTITY_TYPE_PRIVATE_GROUP) - .AddIdentityType(IdentityType::IDENTITY_TYPE_CONTACTS_GROUP) - .AddIdentityType(IdentityType::IDENTITY_TYPE_PUBLIC) - .Build(); -} - -SharedCredential GetPublicCredential() { - // Values copied from LDT tests - ByteArray seed({204, 219, 36, 137, 233, 252, 172, 66, 179, 147, 72, - 184, 148, 30, 209, 154, 29, 54, 14, 117, 224, 152, - 200, 193, 94, 107, 28, 194, 182, 32, 205, 57}); - ByteArray known_mac({0xB4, 0xC5, 0x9F, 0xA5, 0x99, 0x24, 0x1B, 0x81, - 0x75, 0x8D, 0x97, 0x6B, 0x5A, 0x62, 0x1C, 0x05, - 0x23, 0x2F, 0xE1, 0xBF, 0x89, 0xAE, 0x59, 0x87, - 0xCA, 0x25, 0x4C, 0x35, 0x54, 0xDC, 0xE5, 0x0E}); - SharedCredential public_credential; - public_credential.set_key_seed(seed.AsStringView()); - public_credential.set_metadata_encryption_key_tag_v0( - known_mac.AsStringView()); - return public_credential; -} - -TEST(AdvertisementDecoderImpl, - DecodeBaseNpV0PublicIdentityWithTxAndActionFields) { - AdvertisementDecoderImpl decoder; - // v0 public identity, power and action, action value 8 for active unlock. - // These values all come from - // //third_party/nearby/presence/implementation/advertisement_factory_test.cc - auto result = - decoder.DecodeAdvertisement(absl::HexStringToBytes("000315FF260080")); - - ASSERT_OK(result); - EXPECT_THAT(result->data_elements, - UnorderedElementsAre( - DataElement(DataElement::kPublicIdentityFieldType, ""), - DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("ff")), - DataElement(DataElement(ActionBit::kActiveUnlockAction)))); -} - -TEST(AdvertisementDecoderImpl, DecodeBaseNpPublicAdvertisement) { - const std::string salt = "AB"; - AdvertisementDecoderImpl decoder; - - const absl::StatusOr result = decoder.DecodeAdvertisement( - absl::HexStringToBytes("002041420337C1C2C31BEE")); - - ASSERT_OK(result); - EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PUBLIC); - EXPECT_EQ(result->version, 0); - EXPECT_THAT( - result->data_elements, - ElementsAre(DataElement(DataElement::kSaltFieldType, salt), - DataElement(DataElement::kPublicIdentityFieldType, ""), - DataElement(DataElement::kModelIdFieldType, - absl::HexStringToBytes("C1C2C3")), - DataElement(DataElement::kBatteryFieldType, - absl::HexStringToBytes("EE")))); -} - -TEST(AdvertisementDecoderImpl, DecodeBaseNpWithTxAndActionFields) { - std::string salt = "AB"; - AdvertisementDecoderImpl decoder; - - auto result = decoder.DecodeAdvertisement( - absl::HexStringToBytes("0020414203155036B04180")); - - ASSERT_OK(result); - EXPECT_THAT(result->data_elements, - UnorderedElementsAre( - DataElement(DataElement::kSaltFieldType, salt), - DataElement(DataElement::kPublicIdentityFieldType, ""), - DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("50")), - DataElement(DataElement::kContextTimestampFieldType, - absl::HexStringToBytes("0B")), - DataElement(DataElement(ActionBit::kTapToTransferAction)), - DataElement(DataElement(ActionBit::kNearbyShareAction)))); -} - -TEST(AdvertisementDecoderImpl, DecodeBaseNpPrivateAdvertisement) { - std::string salt = "AB"; - ByteArray metadata_key( - {205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174}); - absl::flat_hash_map> - credentials; - credentials[IdentityType::IDENTITY_TYPE_PRIVATE_GROUP].push_back( - GetPublicCredential()); - AdvertisementDecoderImpl decoder(&credentials); - - absl::StatusOr result = decoder.DecodeAdvertisement( - absl::HexStringToBytes("00514142b8412efb0bc657ba514baf4d1b50ddc842cd1c")); - ASSERT_OK(result); - EXPECT_EQ(result->metadata_key, metadata_key.AsStringView()); - EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_THAT(result->data_elements, - ElementsAre(DataElement(DataElement::kSaltFieldType, salt), - DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("05")), - DataElement(DataElement::kActionFieldType, - absl::HexStringToBytes("08")))); -} - -TEST(AdvertisementDecoderImpl, InvalidEncryptedContent) { - std::string salt = "AB"; - ByteArray metadata_key( - {205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174}); - absl::flat_hash_map> - credentials; - credentials[IdentityType::IDENTITY_TYPE_PRIVATE_GROUP].push_back( - GetPublicCredential()); - AdvertisementDecoderImpl decoder(&credentials); - - EXPECT_THAT(decoder.DecodeAdvertisement(absl::HexStringToBytes( - "00414142f085d661ac8cb110e792e7faeb736294")), - StatusIs(absl::StatusCode::kOutOfRange)); -} - -TEST(AdvertisementDecoderImpl, UnsupportedDataElement) { - std::string valid_header_and_salt = absl::HexStringToBytes("00204142"); - AdvertisementDecoderImpl decoder; - - EXPECT_THAT(decoder.DecodeAdvertisement(valid_header_and_salt + - absl::HexStringToBytes("0D")), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST(AdvertisementDecoderImpl, InvalidAdvertisementFieldTooShort) { - AdvertisementDecoderImpl decoder; - - // 0x59 header means 5 bytes long Account Key Data but only 4 bytes follow. - EXPECT_THAT( - decoder.DecodeAdvertisement(absl::HexStringToBytes("0059A0A1A2A3")), - StatusIs(absl::StatusCode::kOutOfRange)); -} - -TEST(AdvertisementDecoderImpl, ZeroLengthPayload) { - AdvertisementDecoderImpl decoder; - - // A action with type 0xA and no payload - const absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes("000A")); - - ASSERT_OK(result); - EXPECT_THAT(result->data_elements, ElementsAre(DataElement(0xA, ""))); -} - -TEST(AdvertisementDecoderImpl, EmptyAdvertisement) { - AdvertisementDecoderImpl decoder; - - EXPECT_THAT(decoder.DecodeAdvertisement(""), - StatusIs(absl::StatusCode::kOutOfRange)); -} - -TEST(AdvertisementDecoderImpl, UnsupportedAdvertisementVersion) { - AdvertisementDecoderImpl decoder; - - EXPECT_THAT(decoder.DecodeAdvertisement( - absl::HexStringToBytes("012041420318CD29EEFF")), - StatusIs(absl::StatusCode::kUnimplemented)); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_factory.cc b/presence/implementation/advertisement_factory.cc deleted file mode 100644 index 87c74183..00000000 --- a/presence/implementation/advertisement_factory.cc +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/advertisement_factory.h" - -#include -#include -#include -#include -#include - -#include "absl/base/attributes.h" -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "absl/types/variant.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/logging.h" -#include "internal/platform/uuid.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/ldt.h" -#include "presence/implementation/mediums/advertisement_data.h" - -namespace nearby { -namespace presence { - -namespace { -using ::nearby::internal::IdentityType; -constexpr uint8_t kBaseVersion = 0; -constexpr size_t kMaxBaseNpAdvSize = 26; - -absl::StatusOr CreateDataElementHeader(size_t length, - unsigned data_type) { - if (length > DataElement::kMaxDataElementLength) { - return absl::InvalidArgumentError( - absl::StrFormat("Unsupported Data Element length: %d", length)); - } - if (data_type > DataElement::kMaxDataElementType) { - return absl::InvalidArgumentError( - absl::StrFormat("Unsupported Data Element type: %d", data_type)); - } - return (length << DataElement::kDataElementLengthShift) | data_type; -} - -absl::Status AppendDataElement(unsigned data_type, - absl::string_view data_element, - std::string& output) { - auto header = CreateDataElementHeader(data_element.size(), data_type); - if (!header.ok()) { - LOG(WARNING) << "Can't add Data element type: " << data_type - << ", length: " << data_element.size(); - return header.status(); - } - output.push_back(*header); - output.insert(output.end(), data_element.begin(), data_element.end()); - return absl::OkStatus(); -} - -uint8_t GetIdentityFieldType(IdentityType type) { - switch (type) { - case IdentityType::IDENTITY_TYPE_PRIVATE_GROUP: - return DataElement::kPrivateGroupIdentityFieldType; - case IdentityType::IDENTITY_TYPE_CONTACTS_GROUP: - return DataElement::kContactsGroupIdentityFieldType; - case IdentityType::IDENTITY_TYPE_PUBLIC: - ABSL_FALLTHROUGH_INTENDED; - default: - return DataElement::kPublicIdentityFieldType; - } -} - -std::string SerializeAction(const Action& action) { - std::string output; - uint32_t input = action.action; - for (int i = 3; i >= 0; --i) { - if (input == 0) { - return output; - } - int shift = 8 * i; - output.push_back(static_cast((input >> shift) & 0xFF)); - input &= (1 << shift) - 1; - } - return output; -} - -bool RequiresCredentials(IdentityType identity_type) { - return identity_type == IdentityType::IDENTITY_TYPE_PRIVATE_GROUP || - identity_type == IdentityType::IDENTITY_TYPE_CONTACTS_GROUP; -} -} // namespace - -absl::StatusOr AdvertisementFactory::CreateAdvertisement( - const BaseBroadcastRequest& request, - absl::optional credential) const { - AdvertisementData advert = {}; - if (absl::holds_alternative( - request.variant)) { - return CreateBaseNpAdvertisement(request, std::move(credential)); - } - return advert; -} - -absl::StatusOr -AdvertisementFactory::CreateBaseNpAdvertisement( - const BaseBroadcastRequest& request, - absl::optional credential) const { - const auto& presence = - absl::get(request.variant); - std::string payload; - payload.reserve(kMaxBaseNpAdvSize); - payload.push_back(kBaseVersion); - absl::Status result; - std::string tx_power = {static_cast(request.tx_power)}; - std::string action = SerializeAction(presence.action); - uint8_t identity_type = - GetIdentityFieldType(presence.credential_selector.identity_type); - bool needs_encryption = - identity_type != DataElement::kPublicIdentityFieldType; - if (needs_encryption) { - if (request.salt.size() != kSaltSize) { - return absl::InvalidArgumentError( - absl::StrFormat("Unsupported salt size %d", request.salt.size())); - } - if (!credential) { - return absl::FailedPreconditionError("Missing credentials"); - } - std::string unencrypted; - result = AppendDataElement(DataElement::kTxPowerFieldType, tx_power, - unencrypted); - if (!result.ok()) { - return result; - } - result = - AppendDataElement(DataElement::kActionFieldType, action, unencrypted); - if (!result.ok()) { - return result; - } - VLOG(1) << "Unencrypted advertisement payload " - << absl::BytesToHexString(unencrypted); - absl::StatusOr encrypted = - EncryptDataElements(*credential, request.salt, unencrypted); - if (!encrypted.ok()) { - return encrypted.status(); - } - if (encrypted->size() <= kBaseMetadataSize) { - return absl::OutOfRangeError( - absl::StrFormat("Encrypted identity DE is too short - %d bytes. " - "Expected more than %d", - encrypted->size(), kBaseMetadataSize)); - } - - // The Identity DE header does not include the length of salt nor metadata. - absl::StatusOr identity_header = CreateDataElementHeader( - encrypted->size() - kBaseMetadataSize, identity_type); - if (!identity_header.ok()) { - return identity_header.status(); - } - payload.push_back(*identity_header); - // In the encrypted format, salt is not a DE (thus no header) - payload.append(request.salt); - payload.append(*encrypted); - } else { - result = AppendDataElement(identity_type, "", payload); - if (!result.ok()) { - return result; - } - if (!request.salt.empty()) { - result = - AppendDataElement(DataElement::kSaltFieldType, request.salt, payload); - if (!result.ok()) { - return result; - } - } - result = - AppendDataElement(DataElement::kTxPowerFieldType, tx_power, payload); - if (!result.ok()) { - return result; - } - result = AppendDataElement(DataElement::kActionFieldType, action, payload); - if (!result.ok()) { - return result; - } - } - return AdvertisementData{.is_extended_advertisement = false, - .content = payload}; -} -absl::StatusOr AdvertisementFactory::EncryptDataElements( - const LocalCredential& credential, absl::string_view salt, - absl::string_view data_elements) const { - if (credential.metadata_encryption_key_v0().size() != kBaseMetadataSize) { - return absl::FailedPreconditionError(absl::StrFormat( - "Metadata key size %d, expected %d", - credential.metadata_encryption_key_v0().size(), kBaseMetadataSize)); - } - - // HMAC is not used during encryption, so we can pass an empty value. - absl::StatusOr encryptor = - LdtEncryptor::Create(credential.key_seed(), /*known_hmac=*/""); - if (!encryptor.ok()) { - return encryptor.status(); - } - std::string plaintext = - absl::StrCat(credential.metadata_encryption_key_v0(), data_elements); - return encryptor->Encrypt(plaintext, salt); -} - -absl::StatusOr AdvertisementFactory::GetCredentialSelector( - const BaseBroadcastRequest& request) { - if (absl::holds_alternative( - request.variant)) { - const auto& presence = - absl::get(request.variant); - if (RequiresCredentials(presence.credential_selector.identity_type)) { - return presence.credential_selector; - } - } - return absl::NotFoundError("credentials not required"); -} -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_factory.h b/presence/implementation/advertisement_factory.h deleted file mode 100644 index 54211944..00000000 --- a/presence/implementation/advertisement_factory.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2022 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_PRESENCE_ADVERTISEMENT_FACTORY_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_FACTORY_H_ - -#include - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/mediums/advertisement_data.h" - -namespace nearby { -namespace presence { - -// Builds BLE advertisements from broadcast requests. -class AdvertisementFactory { - public: - using LocalCredential = internal::LocalCredential; - - // Returns a `CredentialSelector` if credentials are required to create an - // advertisement from the `request`. - static absl::StatusOr GetCredentialSelector( - const BaseBroadcastRequest& request); - - // Returns a BLE advertisement for given `request. - absl::StatusOr CreateAdvertisement( - const BaseBroadcastRequest& request, - absl::optional credential) const; // NOLINT - - absl::StatusOr CreateAdvertisement( - const BaseBroadcastRequest& request) const { - return CreateAdvertisement(request, - absl::optional()); // NOLINT - } - - private: - absl::StatusOr CreateBaseNpAdvertisement( - const BaseBroadcastRequest& request, - absl::optional credential) const; // NOLINT - absl::StatusOr EncryptDataElements( - const LocalCredential& credential, absl::string_view salt, - absl::string_view data_elements) const; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_FACTORY_H_ diff --git a/presence/implementation/advertisement_factory_test.cc b/presence/implementation/advertisement_factory_test.cc deleted file mode 100644 index 8c2897f8..00000000 --- a/presence/implementation/advertisement_factory_test.cc +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/advertisement_factory.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "internal/platform/byte_array.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/implementation/action_factory.h" -#include "presence/implementation/mediums/advertisement_data.h" - -namespace nearby { -namespace presence { - -namespace { - -using ::nearby::ByteArray; // NOLINT -using ::nearby::internal::IdentityType; -using ::nearby::internal::LocalCredential; // NOLINT -using ::testing::NiceMock; -using ::testing::Return; -using ::testing::status::StatusIs; - -LocalCredential CreateLocalCredential(IdentityType identity_type) { - // Values copied from LDT tests - ByteArray seed({204, 219, 36, 137, 233, 252, 172, 66, 179, 147, 72, - 184, 148, 30, 209, 154, 29, 54, 14, 117, 224, 152, - 200, 193, 94, 107, 28, 194, 182, 32, 205, 57}); - ByteArray metadata_key( - {205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174}); - - LocalCredential private_credential; - private_credential.set_identity_type(identity_type); - private_credential.set_key_seed(seed.AsStringView()); - private_credential.set_metadata_encryption_key_v0( - metadata_key.AsStringView()); - return private_credential; -} - -TEST(AdvertisementFactory, CreateAdvertisementFromPrivateIdentity) { - std::string account_name = "Test account"; - std::string salt = "AB"; - constexpr IdentityType kIdentity = IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - Action action = ActionFactory::CreateAction(data_elements); - BaseBroadcastRequest request = - BaseBroadcastRequest(BasePresenceRequestBuilder(kIdentity) - .SetAccountName(account_name) - .SetSalt(salt) - .SetTxPower(5) - .SetAction(action)); - - absl::StatusOr result = - AdvertisementFactory().CreateAdvertisement( - request, CreateLocalCredential(kIdentity)); - - ASSERT_OK(result); - EXPECT_FALSE(result->is_extended_advertisement); - EXPECT_EQ(absl::BytesToHexString(result->content), - "00514142b8412efb0bc657ba514baf4d1b50ddc842cd1c"); -} - -TEST(AdvertisementFactory, CreateAdvertisementFromTrustedIdentity) { - std::string account_name = "Test account"; - std::string salt = "AB"; - constexpr IdentityType kIdentity = IdentityType::IDENTITY_TYPE_CONTACTS_GROUP; - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - data_elements.emplace_back(ActionBit::kPresenceManagerAction); - Action action = ActionFactory::CreateAction(data_elements); - BaseBroadcastRequest request = - BaseBroadcastRequest(BasePresenceRequestBuilder(kIdentity) - .SetAccountName(account_name) - .SetSalt(salt) - .SetTxPower(5) - .SetAction(action)); - - absl::StatusOr result = - AdvertisementFactory().CreateAdvertisement( - request, CreateLocalCredential(kIdentity)); - - ASSERT_OK(result); - EXPECT_FALSE(result->is_extended_advertisement); - EXPECT_EQ(absl::BytesToHexString(result->content), - "0052414257a35c020f1c547d7e169303196d75da7118ba"); -} - -TEST(AdvertisementFactory, CreateAdvertisementFromPublicIdentity) { - std::string salt = "AB"; - constexpr IdentityType kIdentity = IdentityType::IDENTITY_TYPE_PUBLIC; - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - Action action = ActionFactory::CreateAction(data_elements); - BaseBroadcastRequest request = - BaseBroadcastRequest(BasePresenceRequestBuilder(kIdentity) - .SetSalt(salt) - .SetTxPower(5) - .SetAction(action)); - - absl::StatusOr result = - AdvertisementFactory().CreateAdvertisement(request); - - ASSERT_OK(result); - EXPECT_FALSE(result->is_extended_advertisement); - EXPECT_EQ(absl::BytesToHexString(result->content), "00032041421505260080"); -} - -TEST(AdvertisementFactory, CreateAdvertisementFailsWhenSaltIsTooShort) { - std::string salt = "AB"; - constexpr IdentityType kIdentity = internal::IDENTITY_TYPE_PRIVATE_GROUP; - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - Action action = ActionFactory::CreateAction(data_elements); - BaseBroadcastRequest request = - BaseBroadcastRequest(BasePresenceRequestBuilder(kIdentity) - .SetSalt(salt) - .SetTxPower(5) - .SetAction(action)); - // Override the salt with invalid value - request.salt = "C"; - - EXPECT_THAT(AdvertisementFactory().CreateAdvertisement(request), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_filter.cc b/presence/implementation/advertisement_filter.cc deleted file mode 100644 index e3b5bb37..00000000 --- a/presence/implementation/advertisement_filter.cc +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2024 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. - -#include "presence/implementation/advertisement_filter.h" - -#include -#include - -#include "absl/types/variant.h" -#include "internal/platform/logging.h" -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -bool Contains(const std::vector& data_elements, - const DataElement& data_element) { - return std::find(data_elements.begin(), data_elements.end(), data_element) != - data_elements.end(); -} - -bool ContainsAll(const std::vector& data_elements, - const std::vector& extended_properties) { - for (const auto& filter_element : extended_properties) { - if (!Contains(data_elements, filter_element)) { - return false; - } - } - return true; -} - -bool ContainsAny(const std::vector& data_elements, - const std::vector& actions) { - if (actions.empty()) { - return true; - } - for (int action : actions) { - if (Contains(data_elements, DataElement(ActionBit(action)))) { - return true; - } - } - return false; -} - -bool AdvertisementFilter::MatchesScanFilter( - const Advertisement& advertisement) { - // Verify the identity is one requested in the scan_request. - // Per the Public API of scan_request, if identity_types provided in the - // scan_request is empty then decode advertisements of every identity type - auto requested_identity_types = scan_request_.identity_types; - if (!requested_identity_types.empty() && - !(std::find( - requested_identity_types.begin(), requested_identity_types.end(), - advertisement.identity_type) != requested_identity_types.end())) { - LOG(INFO) << "Skipping advertisement with identity type: " - << advertisement.identity_type - << " because that identity type was not requested in the scan " - "request"; - return false; - } - - // The advertisement matches the scan request when it matches at least - // one of the filters in the request. - if (scan_request_.scan_filters.empty()) { - return true; - } - - // NOLINT is used to suppress google3-legacy-absl-backport lints because the - // the suggestion is not compatible with Chrome - for (const auto& filter : scan_request_.scan_filters) { - if (absl::holds_alternative(filter)) { // NOLINT - if (MatchesScanFilter(advertisement.data_elements, - absl::get(filter))) { // NOLINT - return true; - } - } else if (absl::holds_alternative( // NOLINT - filter)) { - if (MatchesScanFilter( - advertisement.data_elements, - absl::get(filter))) { // NOLINT - return true; - } - } - } - return false; -} - -bool AdvertisementFilter::MatchesScanFilter( - const std::vector& data_elements, - const PresenceScanFilter& filter) { - // The advertisement must contain all Data Elements in scan request. - return ContainsAll(data_elements, filter.extended_properties); -} - -bool AdvertisementFilter::MatchesScanFilter( - const std::vector& data_elements, - const LegacyPresenceScanFilter& filter) { - // The advertisement must: - // * contain any Action from scan request, - // * contain all Data Elements in scan request. - return ContainsAny(data_elements, filter.actions) && - ContainsAll(data_elements, filter.extended_properties); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_filter.h b/presence/implementation/advertisement_filter.h deleted file mode 100644 index 2e2db1e4..00000000 --- a/presence/implementation/advertisement_filter.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2024 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_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_FILTER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_FILTER_H_ - -#include - -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { -class AdvertisementFilter { - public: - explicit AdvertisementFilter(ScanRequest scan_request) - : scan_request_(scan_request) {} - - // Returns true if the decoded advertisement in `data_elements` matches the - // filters in `scan_request`. - bool MatchesScanFilter(const Advertisement& adv); - - private: - bool MatchesScanFilter(const std::vector& data_elements, - const PresenceScanFilter& filter); - bool MatchesScanFilter(const std::vector& data_elements, - const LegacyPresenceScanFilter& filter); - ScanRequest scan_request_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_FILTER_H_ diff --git a/presence/implementation/advertisement_filter_test.cc b/presence/implementation/advertisement_filter_test.cc deleted file mode 100644 index ff3a1dfd..00000000 --- a/presence/implementation/advertisement_filter_test.cc +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2024 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. - -#include "presence/implementation/advertisement_filter.h" - -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/scan_request.h" -#include "presence/scan_request_builder.h" - -namespace nearby { -namespace presence { -namespace { - -TEST(AdvertisementFilter, MatchesScanFilterNoFilterPasses) { - std::vector adv = { - DataElement(DataElement::kPrivateGroupIdentityFieldType, "payload")}; - ScanRequest empty_scan_request = {}; - AdvertisementFilter adv_filter(empty_scan_request); - - // A scan request without scan filters matches any advertisement - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.data_elements = {DataElement( - DataElement::kPrivateGroupIdentityFieldType, "payload")}})); - EXPECT_TRUE(adv_filter.MatchesScanFilter({})); -} - -TEST(AdvertisementFilter, MatchesPresenceScanFilter) { - std::vector adv = { - DataElement(DataElement::kPrivateGroupIdentityFieldType, "payload")}; - DataElement model_id = - DataElement(DataElement::kModelIdFieldType, "model id"); - DataElement salt = DataElement(DataElement::kSaltFieldType, "salt"); - DataElement salt2 = DataElement(DataElement::kSaltFieldType, "salt 2"); - PresenceScanFilter filter = {.extended_properties = {model_id, salt}}; - - AdvertisementFilter adv_filter( - ScanRequestBuilder().AddScanFilter(filter).Build()); - - EXPECT_FALSE(adv_filter.MatchesScanFilter({})); - EXPECT_FALSE(adv_filter.MatchesScanFilter({.data_elements = {salt}})); - EXPECT_TRUE( - adv_filter.MatchesScanFilter({.data_elements = {salt, model_id}})); - EXPECT_TRUE( - adv_filter.MatchesScanFilter({.data_elements = {salt, salt2, model_id}})); - EXPECT_FALSE( - adv_filter.MatchesScanFilter({.data_elements = {salt2, model_id}})); -} - -TEST(AdvertisementFilter, MatchesLegacyPresenceScanFilter) { - std::vector adv = { - DataElement(DataElement::kPrivateGroupIdentityFieldType, "payload")}; - DataElement model_id = - DataElement(DataElement::kModelIdFieldType, "model id"); - DataElement salt = DataElement(DataElement::kSaltFieldType, "salt"); - DataElement salt2 = DataElement(DataElement::kSaltFieldType, "salt 2"); - LegacyPresenceScanFilter filter = {.extended_properties = {model_id, salt}}; - - AdvertisementFilter adv_filter( - ScanRequestBuilder().AddScanFilter(filter).Build()); - - EXPECT_FALSE(adv_filter.MatchesScanFilter(Advertisement{})); - EXPECT_FALSE(adv_filter.MatchesScanFilter({.data_elements = {salt}})); - EXPECT_TRUE( - adv_filter.MatchesScanFilter({.data_elements = {salt, model_id}})); - EXPECT_TRUE( - adv_filter.MatchesScanFilter({.data_elements = {salt, salt2, model_id}})); - EXPECT_FALSE(adv_filter.MatchesScanFilter( - Advertisement{.data_elements = {salt2, model_id}})); -} - -TEST(AdvertisementFilter, - EncryptedIdentityFilterIgnoresPublicIdentityAdvertisement) { - AdvertisementFilter adv_filter( - {.identity_types = { - internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP, - internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP}}); - - EXPECT_FALSE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PUBLIC})); - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP})); -} - -TEST(AdvertisementFilter, PublicIdentityFilterMatchesPublicIdentityAdv) { - AdvertisementFilter adv_filter( - {.identity_types = {internal::IdentityType::IDENTITY_TYPE_PUBLIC}}); - - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PUBLIC})); - EXPECT_FALSE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP})); -} - -TEST(AdvertisementFilter, EmptyIdentityFilterMatchesAllAdvIdentityTypes) { - AdvertisementFilter adv_filter({}); - - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PUBLIC})); - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP})); -} - -TEST(AdvertisementFilter, MatchesLegacyPresenceScanFilterWithActions) { - std::vector adv = { - DataElement(DataElement::kPrivateGroupIdentityFieldType, "payload")}; - DataElement model_id = - DataElement(DataElement::kModelIdFieldType, "model id"); - DataElement salt = DataElement(DataElement::kSaltFieldType, "salt"); - DataElement ttt_action = DataElement(ActionBit::kTapToTransferAction); - LegacyPresenceScanFilter filter = { - .actions = {static_cast(ActionBit::kActiveUnlockAction), - static_cast(ActionBit::kTapToTransferAction)}, - .extended_properties = {model_id, salt}}; - - AdvertisementFilter adv_filter( - ScanRequestBuilder().AddScanFilter(filter).Build()); - - EXPECT_FALSE( - adv_filter.MatchesScanFilter({.data_elements = {salt, model_id}})); - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.data_elements = {salt, ttt_action, model_id}})); -} - -TEST(AdvertisementFilter, MatchesMultipleFilters) { - std::vector adv = { - DataElement(DataElement::kPrivateGroupIdentityFieldType, "payload")}; - DataElement model_id = - DataElement(DataElement::kModelIdFieldType, "model id"); - DataElement salt = DataElement(DataElement::kSaltFieldType, "salt"); - DataElement ttt_action = DataElement(ActionBit::kTapToTransferAction); - PresenceScanFilter presence_filter = {.extended_properties = {model_id}}; - LegacyPresenceScanFilter legacy_filter = { - .actions = {static_cast(ActionBit::kActiveUnlockAction), - static_cast(ActionBit::kTapToTransferAction)}, - .extended_properties = {salt}}; - - AdvertisementFilter adv_filter(ScanRequestBuilder() - .AddScanFilter(presence_filter) - .AddScanFilter(legacy_filter) - .Build()); - - EXPECT_TRUE(adv_filter.MatchesScanFilter({.data_elements = {model_id}})); - EXPECT_TRUE( - adv_filter.MatchesScanFilter({.data_elements = {salt, ttt_action}})); - EXPECT_FALSE(adv_filter.MatchesScanFilter({.data_elements = {ttt_action}})); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/base_broadcast_request.cc b/presence/implementation/base_broadcast_request.cc deleted file mode 100644 index 30dda102..00000000 --- a/presence/implementation/base_broadcast_request.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/base_broadcast_request.h" - -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/crypto.h" -#include "internal/platform/logging.h" -#include "presence/broadcast_request.h" -#include "presence/implementation/action_factory.h" - -namespace nearby { -namespace presence { - -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetSalt( - absl::string_view salt) { - if (salt.size() != kSaltSize) { - LOG(WARNING) << "Unsupported salt length: " << salt.size(); - } else { - salt_ = std::string(salt); - } - return *this; -} -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetTxPower( - int8_t tx_power) { - tx_power_ = tx_power; - return *this; -} - -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetAction( - const Action& action) { - action_ = action; - return *this; -} - -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetPowerMode( - PowerMode power_mode) { - power_mode_ = power_mode; - return *this; -} - -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetAccountName( - absl::string_view account_name) { - account_name_ = std::string(account_name); - return *this; -} - -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetManagerAppId( - absl::string_view manager_app_id) { - manager_app_id_ = std::string(manager_app_id); - return *this; -} - -BasePresenceRequestBuilder::operator BaseBroadcastRequest() const { - BaseBroadcastRequest::BasePresence presence{ - .credential_selector = {.manager_app_id = manager_app_id_, - .account_name = account_name_, - .identity_type = identity_}, - .action = action_}; - - std::string bytes(kSaltSize, 0); - RandBytes(const_cast(bytes.data()), bytes.size()); - - BaseBroadcastRequest broadcast_request{ - .variant = presence, - .salt = salt_.size() == kSaltSize ? salt_ : bytes, - .tx_power = tx_power_, - .power_mode = power_mode_}; - return broadcast_request; -} - -absl::StatusOr BaseBroadcastRequest::Create( - const BroadcastRequest& request) { - if (absl::holds_alternative(request.variant)) { - const auto& presence_request = - absl::get(request.variant); - if (presence_request.sections.empty()) { - return absl::InvalidArgumentError("Missing broadcast sections"); - } - if (presence_request.sections.size() > 1) { - LOG(WARNING) << "Only first section is used in BLE 4.2 advertisement"; - } - const PresenceBroadcast::BroadcastSection& section = - presence_request.sections.front(); - return BaseBroadcastRequest( - BasePresenceRequestBuilder(section.identity) - .SetTxPower(request.tx_power) - .SetAction(ActionFactory::CreateAction(section.extended_properties)) - .SetPowerMode(request.power_mode) - .SetManagerAppId(section.manager_app_id) - .SetAccountName(section.account_name)); - } - return absl::UnimplementedError("Request not supported"); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/base_broadcast_request.h b/presence/implementation/base_broadcast_request.h deleted file mode 100644 index 36821ccc..00000000 --- a/presence/implementation/base_broadcast_request.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2022 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_PRESENCE_IMPLEMENTATION_BASE_BROADCAST_REQUEST_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_BASE_BROADCAST_REQUEST_H_ - -#include - -#include -#include - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "absl/types/variant.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "presence/broadcast_request.h" -#include "presence/power_mode.h" - -namespace nearby { -namespace presence { - -constexpr int8_t kUnspecifiedTxPower = -128; -constexpr size_t kSaltSize = 2; -// The identity metadata size in the base advertisement -constexpr size_t kBaseMetadataSize = 14; - -/** Defines the action (intended actions) of base NP advertisement */ -struct Action { - uint32_t action; -}; - -/** Defines a Nearby Presence broadcast request */ -struct BaseBroadcastRequest { - // Creates `BaseBroadcastRequest` from the public API request in - // `BroadcastRequest`. - static absl::StatusOr Create( - const BroadcastRequest& request); - - struct BasePresence { - CredentialSelector credential_selector; - Action action; - }; - struct BaseFastPair { - struct Discoverable { - std::string model_id; - }; - struct Nondiscoverable { - std::string account_key_data; - std::string battery_info; - }; - absl::variant advertisement; - }; - struct BaseEddystone { - std::string ephemeral_id; - }; - absl::variant variant; - std::string salt; - int8_t tx_power; - unsigned int interval_ms; - PowerMode power_mode; -}; - -/** Builds a brodacast request variant with NP identity for BLE 4.2 */ -class BasePresenceRequestBuilder { - public: - explicit BasePresenceRequestBuilder( - const nearby::internal::IdentityType& identity) - : identity_(identity) {} - BasePresenceRequestBuilder& SetSalt(absl::string_view salt); - BasePresenceRequestBuilder& SetTxPower(int8_t tx_power); - BasePresenceRequestBuilder& SetAction(const Action& action); - BasePresenceRequestBuilder& SetPowerMode(PowerMode power_mode); - BasePresenceRequestBuilder& SetAccountName(absl::string_view account_name); - BasePresenceRequestBuilder& SetManagerAppId(absl::string_view manager_app_id); - - explicit operator BaseBroadcastRequest() const; - - private: - nearby::internal::IdentityType identity_; - std::string salt_; - int8_t tx_power_ = kUnspecifiedTxPower; - Action action_; - PowerMode power_mode_ = PowerMode::kNoPower; - std::string account_name_; - std::string manager_app_id_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_BASE_BROADCAST_REQUEST_H_ diff --git a/presence/implementation/base_broadcast_request_test.cc b/presence/implementation/base_broadcast_request_test.cc deleted file mode 100644 index b27040b3..00000000 --- a/presence/implementation/base_broadcast_request_test.cc +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/base_broadcast_request.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/types/variant.h" -#include "internal/proto/credential.pb.h" -#include "presence/broadcast_request.h" -#include "presence/data_element.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::internal::IdentityType; -using ::testing::status::StatusIs; - -TEST(BroadcastRequestTest, CreateBasePresenceRequest) { - nearby::internal::IdentityType identity; - constexpr int8_t kTxPower = -13; - - BaseBroadcastRequest request = BaseBroadcastRequest( - BasePresenceRequestBuilder(identity).SetTxPower(kTxPower).SetPowerMode( - PowerMode::kBalanced)); - - EXPECT_TRUE(absl::holds_alternative( - request.variant)); - EXPECT_EQ(request.salt.size(), 2); - EXPECT_EQ(request.tx_power, kTxPower); - EXPECT_EQ(request.power_mode, PowerMode::kBalanced); -} - -TEST(BroadcastRequestTest, CreateFromPresenceRequest) { - constexpr int8_t kTxPower = 30; - constexpr uint32_t kExpectedAction = - (1 << 23); // encoded kActiveUnlockAction - std::string account_name = "Test account"; - std::string manager_app_id = "Manager app id"; - PresenceBroadcast::BroadcastSection section = { - .identity = internal::IDENTITY_TYPE_PUBLIC, - .extended_properties = {DataElement( - DataElement(ActionBit::kActiveUnlockAction))}, - .account_name = account_name, - .manager_app_id = manager_app_id}; - PresenceBroadcast presence_request = {.sections = {section}}; - BroadcastRequest input = {.tx_power = kTxPower, .variant = presence_request}; - - absl::StatusOr request = - BaseBroadcastRequest::Create(input); - - ASSERT_OK(request); - EXPECT_THAT(request->tx_power, kTxPower); - EXPECT_THAT(absl::get(request->variant) - .credential_selector.identity_type, - IdentityType::IDENTITY_TYPE_PUBLIC); - EXPECT_THAT(absl::get(request->variant) - .action.action, - kExpectedAction); - EXPECT_THAT(absl::get(request->variant) - .credential_selector.account_name, - account_name); - EXPECT_THAT(absl::get(request->variant) - .credential_selector.manager_app_id, - manager_app_id); -} - -TEST(BroadcastRequestTest, CreateFromEmptyPresenceRequestFails) { - BroadcastRequest empty = { - .variant = PresenceBroadcast(), - }; - - EXPECT_THAT(BaseBroadcastRequest::Create(empty), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/broadcast_manager.cc b/presence/implementation/broadcast_manager.cc deleted file mode 100644 index 088083b3..00000000 --- a/presence/implementation/broadcast_manager.cc +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/broadcast_manager.h" - -#include -#include -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/status/status.h" -#include "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/implementation/crypto.h" -#include "internal/platform/logging.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/implementation/advertisement_factory.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/mediums/advertisement_data.h" - -namespace nearby { -namespace presence { -namespace { - -using AdvertisingCallback = ::nearby::api::ble::BleMedium::AdvertisingCallback; -using AdvertisingSession = ::nearby::api::ble::BleMedium::AdvertisingSession; -using LocalCredential = internal::LocalCredential; - -uint16_t SaltToInt(absl::string_view salt) { - if (salt.length() < 2) return 0; - uint16_t b0 = salt[0]; - uint16_t b1 = salt[1]; - return b0 << 8 | b1; -} -std::string SaltFromInt(uint16_t x) { - std::string salt; - salt.resize(2); - salt[0] = x >> 8 & 0xFF; - salt[1] = x & 0xFF; - return salt; -} - -// Selects a salt that has not been used yet. The salt is added to -// `credential.consumed_salts`. -// We may fail to find an unused salt. In this unlikely event, an already -// consumed salt is returned. -std::string SelectSalt(LocalCredential& credential, - absl::string_view preferred_salt) { - // NP certificate guidelines say that we should try to get an unused salt 128 - // times. - constexpr int kMaxSaltSelectRetries = 128; - - uint16_t s = SaltToInt(preferred_salt); - for (int i = 0; i < kMaxSaltSelectRetries; i++) { - if (!credential.consumed_salts().contains(s)) { - break; - } - s = nearby::RandData(); - } - credential.mutable_consumed_salts()->insert({s, true}); - return SaltFromInt(s); -} - -} // namespace - -absl::StatusOr BroadcastManager::StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) { - absl::StatusOr request = - BaseBroadcastRequest::Create(broadcast_request); - if (!request.ok()) { - LOG(WARNING) << "Invalid broadcast request, reason: " << request.status(); - callback.start_broadcast_cb(request.status()); - return request.status(); - } - BroadcastSessionId id = GenerateBroadcastSessionId(); - RunOnServiceControllerThread( - "start-broadcast", - [this, id, power_mode = broadcast_request.power_mode, request = *request, - broadcast_callback = std::move( - callback)]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) mutable { - sessions_.insert({id, BroadcastSessionState( - std::move(broadcast_callback), power_mode)}); - FetchCredentials(id, std::move(request)); - }); - return id; -} - -void BroadcastManager::FetchCredentials( - BroadcastSessionId id, BaseBroadcastRequest broadcast_request) { - absl::StatusOr credential_selector = - AdvertisementFactory::GetCredentialSelector(broadcast_request); - if (!credential_selector.ok()) { - // Public advertisement, we don't need credential to advertise. - Advertise(id, broadcast_request, /*credentials=*/{}); - return; - } - credential_manager_->GetLocalCredentials( - *credential_selector, - GetLocalCredentialsResultCallback{ - .credentials_fetched_cb = - [this, id, broadcast_request = std::move(broadcast_request), - selector = *credential_selector]( - absl::StatusOr< - std::vector<::nearby::internal::LocalCredential>> - credentials) { - if (!credentials.ok()) { - LOG(WARNING) << "Failed to fetch credentials, status: " - << credentials.status(); - NotifyStartCallbackStatus(id, credentials.status()); - return; - } - RunOnServiceControllerThread( - "advertise-non-public", - [this, id, broadcast_request = std::move(broadcast_request), - credentials = std::move(*credentials), - selector = std::move(selector)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) mutable { - absl::optional credential = - Advertise(id, broadcast_request, credentials); - if (credential) { - credential_manager_->UpdateLocalCredential( - selector, std::move(*credential), - {[](absl::Status status) { - if (!status.ok()) { - LOG(WARNING) << "Failed to update private " - "credential, status: " - << status; - } - }}); - } - }); - }}); -} - -absl::optional BroadcastManager::SelectCredential( // NOLINT - BaseBroadcastRequest& broadcast_request, - std::vector credentials) { - if (credentials.empty()) { - return absl::optional(); // NOLINT - } - auto credential = - std::min_element(credentials.begin(), credentials.end(), - [](const LocalCredential& a, const LocalCredential& b) { - return a.start_time_millis() < b.start_time_millis(); - }); - if (credential == credentials.end()) { - LOG(WARNING) << "No active credentials"; - return absl::optional(); // NOLINT - } - std::string salt = SelectSalt(*credential, broadcast_request.salt); - if (salt != broadcast_request.salt) { - VLOG(1) << "Changed salt"; - broadcast_request.salt = salt; - } - return *credential; -} - -absl::optional BroadcastManager::Advertise( // NOLINT - BroadcastSessionId id, BaseBroadcastRequest broadcast_request, - std::vector credentials) { - auto it = sessions_.find(id); - if (it == sessions_.end()) { - LOG(INFO) << "Broadcast session terminated, id: " << id; - return absl::optional(); // NOLINT - } - absl::optional credential = // NOLINT - SelectCredential(broadcast_request, std::move(credentials)); - absl::StatusOr advertisement = - AdvertisementFactory().CreateAdvertisement(broadcast_request, credential); - if (!advertisement.ok()) { - LOG(WARNING) << "Can't create advertisement, reason: " - << advertisement.status(); - NotifyStartCallbackStatus(id, advertisement.status()); - return absl::optional(); // NOLINT - } - std::unique_ptr session = - mediums_->GetBle().StartAdvertising( - *advertisement, it->second.GetPowerMode(), - AdvertisingCallback{ - .start_advertising_result = [this, id](absl::Status status) { - NotifyStartCallbackStatus(id, status); - }}); - if (!session) { - NotifyStartCallbackStatus(id, - absl::InternalError("Can't start advertising")); - return absl::optional(); // NOLINT - } - it->second.SetAdvertisingSession(std::move(session)); - return credential; -} - -void BroadcastManager::NotifyStartCallbackStatus(BroadcastSessionId id, - absl::Status status) { - RunOnServiceControllerThread("started-broadcast-cb", - [this, id, status]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) { - auto it = sessions_.find(id); - if (it == sessions_.end()) { - return; - } - it->second.CallStartedCallback(status); - if (!status.ok()) { - // Delete failed session. - sessions_.erase(it); - } - }); -} - -void BroadcastManager::StopBroadcast(BroadcastSessionId id) { - RunOnServiceControllerThread( - "stop-broadcast", [this, id]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) { - auto it = sessions_.find(id); - if (it == sessions_.end()) { - VLOG(1) << absl::StrFormat("BroadcastSession(0x%x) not found", id); - return; - } - it->second.StopAdvertising(); - sessions_.erase(it); - }); -} - -BroadcastSessionId BroadcastManager::GenerateBroadcastSessionId() { - return nearby::RandData(); -} - -void BroadcastManager::BroadcastSessionState::SetAdvertisingSession( - std::unique_ptr session) { - advertising_session_ = std::move(session); -} - -void BroadcastManager::BroadcastSessionState::CallStartedCallback( - absl::Status status) { - BroadcastCallback callback = std::move(broadcast_callback_); - if (callback.start_broadcast_cb) { - callback.start_broadcast_cb(status); - } -} - -void BroadcastManager::BroadcastSessionState::StopAdvertising() { - std::unique_ptr advertising_session = - std::move(advertising_session_); - if (advertising_session) { - absl::Status status = advertising_session->stop_advertising(); - if (!status.ok()) { - LOG(WARNING) << "StopAdvertising error: " << status; - } - } -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/broadcast_manager.h b/presence/implementation/broadcast_manager.h deleted file mode 100644 index aedf2fec..00000000 --- a/presence/implementation/broadcast_manager.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2020 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_PRESENCE_IMPLEMENTATION_BROADCAST_MANAGER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_BROADCAST_MANAGER_H_ - -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/runnable.h" -#include "internal/platform/single_thread_executor.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/credential_manager.h" -#include "presence/implementation/mediums/mediums.h" -#include "presence/power_mode.h" - -namespace nearby { -namespace presence { - -// The instance of BroadcastManager is owned by {@code ServiceControllerImpl}. -// Helping service controller to manage broadcast requests and callbacks. - -class BroadcastManager { - public: - using SingleThreadExecutor = ::nearby::SingleThreadExecutor; - using AdvertisingSession = ::nearby::api::ble::BleMedium::AdvertisingSession; - using Runnable = ::nearby::Runnable; - using LocalCredential = internal::LocalCredential; - BroadcastManager(Mediums& mediums, CredentialManager& credential_manager, - SingleThreadExecutor& executor) { - mediums_ = &mediums, credential_manager_ = &credential_manager, - executor_ = &executor; - } - ~BroadcastManager() = default; - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback); - void StopBroadcast(BroadcastSessionId); - - private: - Mediums* mediums_; - CredentialManager* credential_manager_; - SingleThreadExecutor* executor_; - class BroadcastSessionState { - public: - explicit BroadcastSessionState(BroadcastCallback broadcast_callback, - PowerMode power_mode) - : broadcast_callback_(std::move(broadcast_callback)), - power_mode_(power_mode) {} - - void SetAdvertisingSession(std::unique_ptr session); - void CallStartedCallback(absl::Status status); - void StopAdvertising(); - - PowerMode GetPowerMode() { return power_mode_; } - - private: - BroadcastCallback broadcast_callback_; - PowerMode power_mode_; - std::unique_ptr advertising_session_; - }; - BroadcastSessionId GenerateBroadcastSessionId(); - void NotifyStartCallbackStatus(BroadcastSessionId id, absl::Status status); - void RunOnServiceControllerThread(absl::string_view name, Runnable runnable) { - executor_->Execute(std::string(name), std::move(runnable)); - } - void FetchCredentials(BroadcastSessionId id, - BaseBroadcastRequest broadcast_request) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - absl::optional SelectCredential( // NOLINT - BaseBroadcastRequest& broadcast_request, - std::vector credentials); - - // Returns the private credential, if any, selected to generate the - // advertisement. A salt used in the advertisement is added to the returned - // private credential. The caller must save it in the storage. - absl::optional Advertise( // NOLINT - BroadcastSessionId id, BaseBroadcastRequest broadcast_request, - std::vector credentials) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - absl::flat_hash_map sessions_ - ABSL_GUARDED_BY(*executor_); -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_BROADCAST_MANAGER_H_ diff --git a/presence/implementation/broadcast_manager_test.cc b/presence/implementation/broadcast_manager_test.cc deleted file mode 100644 index 32effaf9..00000000 --- a/presence/implementation/broadcast_manager_test.cc +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/broadcast_manager.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/future.h" -#include "internal/platform/medium_environment.h" -#include "internal/proto/credential.pb.h" -#include "presence/implementation/credential_manager_impl.h" -#include "presence/implementation/mediums/mediums.h" - -namespace nearby { -namespace presence { -namespace { - -using FeatureFlags = ::nearby::FeatureFlags::Flags; -using internal::IdentityType; -using ::nearby::CountDownLatch; -using ::nearby::MediumEnvironment; -using ::testing::status::StatusIs; - -constexpr FeatureFlags kTestCases[] = { - FeatureFlags{}, -}; - -constexpr absl::string_view kAccountName = "Test account"; -constexpr int8_t kTxPower = 30; - -BroadcastRequest CreateBroadcastRequest(IdentityType identity) { - PresenceBroadcast::BroadcastSection section = { - .identity = identity, - .extended_properties = {DataElement( - DataElement(ActionBit::kActiveUnlockAction))}, - .account_name = std::string(kAccountName)}; - PresenceBroadcast presence_request = {.sections = {section}}; - BroadcastRequest request = {.tx_power = kTxPower, - .variant = presence_request}; - return request; -} - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -class BroadcastManagerTest : public testing::TestWithParam { - protected: - void TearDown() override { - MediumEnvironment::Instance().Sync(); - // Finish pending tasks before destroying BroadcastManager - executor_.Shutdown(); - } - bool IsAdvertising() { - WaitForServiceControllerTasks(); - MediumEnvironment::Instance().Sync(); - return MediumEnvironment::Instance() - .GetBleMediumStatus(*mediums_.GetBle().GetImpl()) - ->is_advertising; - } - BroadcastCallback CreateBroadcastCallback() { - return BroadcastCallback{.start_broadcast_cb = [this](absl::Status status) { - start_broadcast_status_.Set(status); - }}; - } - - void WaitForServiceControllerTasks() { - CountDownLatch latch(1); - executor_.Execute([&]() { latch.CountDown(); }); - latch.Await(); - } - - // The medium environment must be initialized (started) before the service - // controller. - MediumEnvironmentStarter env_; - nearby::Future start_broadcast_status_; - BroadcastCallback broadcast_callback_{ - .start_broadcast_cb = [this](absl::Status status) { - start_broadcast_status_.Set(status); - }}; - Mediums mediums_; - SingleThreadExecutor executor_; - CredentialManagerImpl credential_manager_{&executor_}; - BroadcastManager broadcast_manager_{mediums_, credential_manager_, executor_}; -}; - -INSTANTIATE_TEST_SUITE_P(ParametrisedBroadcastManagerTest, BroadcastManagerTest, - testing::ValuesIn(kTestCases)); - -TEST_P(BroadcastManagerTest, StartBroadcastPublicIdentity) { - absl::StatusOr session = - broadcast_manager_.StartBroadcast( - CreateBroadcastRequest(internal::IDENTITY_TYPE_PUBLIC), - CreateBroadcastCallback()); - - EXPECT_OK(session); - EXPECT_TRUE(start_broadcast_status_.Get().ok()); - EXPECT_OK(start_broadcast_status_.Get().GetResult()); - EXPECT_TRUE(IsAdvertising()); -} - -TEST_P(BroadcastManagerTest, StartAndStopBroadcast) { - absl::StatusOr session = - broadcast_manager_.StartBroadcast( - CreateBroadcastRequest(internal::IDENTITY_TYPE_PUBLIC), - CreateBroadcastCallback()); - ASSERT_OK(session); - EXPECT_TRUE(IsAdvertising()); - - broadcast_manager_.StopBroadcast(*session); - EXPECT_FALSE(IsAdvertising()); -} - -TEST_P(BroadcastManagerTest, StopBroadcastTwiceNoSideEffects) { - absl::StatusOr session = - broadcast_manager_.StartBroadcast( - CreateBroadcastRequest(internal::IDENTITY_TYPE_PUBLIC), - CreateBroadcastCallback()); - ASSERT_OK(session); - EXPECT_TRUE(IsAdvertising()); - - broadcast_manager_.StopBroadcast(*session); - broadcast_manager_.StopBroadcast(*session); -} - -TEST_P(BroadcastManagerTest, StopBroadcastInvalidSessionNoSideEffects) { - broadcast_manager_.StopBroadcast(123456); -} - -TEST_P(BroadcastManagerTest, StartBroadcastInvalidRequestFails) { - absl::StatusOr session = - broadcast_manager_.StartBroadcast(BroadcastRequest{}, - CreateBroadcastCallback()); - - EXPECT_THAT(session, StatusIs(absl::StatusCode::kInvalidArgument)); - EXPECT_TRUE(start_broadcast_status_.Get().ok()); - EXPECT_THAT(start_broadcast_status_.Get().GetResult(), - StatusIs(absl::StatusCode::kInvalidArgument)); - EXPECT_FALSE(IsAdvertising()); -} - -TEST_P(BroadcastManagerTest, StartBroadcastPrivateIdentityFails) { - // TODO(b/256249404): Support private identity. - absl::StatusOr session = - broadcast_manager_.StartBroadcast( - CreateBroadcastRequest(internal::IDENTITY_TYPE_PRIVATE_GROUP), - CreateBroadcastCallback()); - - ASSERT_OK(session); - EXPECT_TRUE(start_broadcast_status_.Get().ok()); - EXPECT_THAT(start_broadcast_status_.Get().GetResult(), - StatusIs(absl::StatusCode::kNotFound)); - EXPECT_FALSE(IsAdvertising()); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/connection_authenticator.h b/presence/implementation/connection_authenticator.h deleted file mode 100644 index 7a9b2cb8..00000000 --- a/presence/implementation/connection_authenticator.h +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2023 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_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_H_ - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" - -namespace nearby { -namespace presence { - -class ConnectionAuthenticator { - public: - struct OneWayInitiatorData { - std::string shared_credential_hash; - }; - - struct TwoWayInitiatorData { - std::string shared_credential_hash; - std::string private_key_signature; - }; - - struct ResponderData { - std::string private_key_signature; - }; - - using InitiatorData = absl::variant; - - virtual ~ConnectionAuthenticator() = default; - - // Builds a signed message to be returned to Nearby Connections for - // authentication on the other side of the connection. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // local_credential - The local credential used to sign the derived - // information. If this is std::nullopt, then we will be - // performing one-way authentication. - // shared_credential - The shared credential used to decrypt the advertisement - // from the remote device. - virtual absl::StatusOr BuildSignedMessageAsInitiator( - absl::string_view ukey2_secret, - std::optional local_credential, - const internal::SharedCredential& shared_credential) const = 0; - - // Builds a signed message to be returned to Nearby Connections for - // authentication on the other side of the connection. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // local_credential - The local credential used to sign the derived - // information so the initiator can verify against our - // shared credential. - virtual absl::StatusOr BuildSignedMessageAsResponder( - absl::string_view ukey2_secret, - const internal::LocalCredential& local_credential) const = 0; - - // Verifies a signed message received from the responder (broadcaster) of the - // Nearby Presence advertisement. - // authentication_data - the data required to verify the connection, received - // from the responder. - // ukey2_secret - the shared secret derived from the ukey2 handshake in NC. - // shared_credentials - the set of shared credentials that can be used to - // verify the responder data. - virtual absl::Status VerifyMessageAsInitiator( - ResponderData authentication_data, absl::string_view ukey2_secret, - const std::vector& shared_credentials) - const = 0; - - // Verifies a signed message received from the Nearby Connections peer. - // Returns the matched local credential if the verification was successful. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // received_frame - The received frame from Nearby Connections. - // local_credentials - The set of local credentials that may contain the - // required keyseed hash. - // shared_credentials - The set of shared credentials that can be used to - // verify the signed contents of the frame. - virtual absl::StatusOr VerifyMessageAsResponder( - absl::string_view ukey2_secret, InitiatorData initiator_data, - const std::vector& local_credentials, - const std::vector& shared_credentials) - const = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_H_ diff --git a/presence/implementation/connection_authenticator_impl.cc b/presence/implementation/connection_authenticator_impl.cc deleted file mode 100644 index cbe68aa2..00000000 --- a/presence/implementation/connection_authenticator_impl.cc +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2023 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. - -#include "presence/implementation/connection_authenticator_impl.h" - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "absl/types/variant.h" -#include "internal/crypto/ed25519.h" -#include "internal/crypto_cros/hkdf.h" -#include "internal/crypto_cros/secure_util.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" - -namespace nearby { -namespace presence { - -namespace { -constexpr int kPresenceAuthenticatorVersion = 1; -constexpr int kPresenceAuthenticatorHkdfKeySize = 32; -constexpr char kBroadcasterMessageHeader[] = - "Nearby Presence Broadcaster Signature"; -constexpr char kDiscovererMessageHeader[] = - "Nearby Presence Discoverer Signature"; -constexpr char kHkdfSalt[] = "Google Nearby"; -constexpr char kBroadcasterHkdfInfo[] = - "Nearby Presence Broadcaster Credential Hash"; -constexpr char kDiscovererHkdfInfo[] = - "Nearby Presence Discoverer Credential Hash"; -} // namespace - -absl::StatusOr -ConnectionAuthenticatorImpl::BuildSignedMessageAsInitiator( - absl::string_view ukey2_secret, - std::optional local_credential, - const internal::SharedCredential& shared_credential) const { - auto shared_credential_hash = crypto::HkdfSha256( - absl::StrCat(ukey2_secret, shared_credential.key_seed()), kHkdfSalt, - kDiscovererHkdfInfo, kPresenceAuthenticatorHkdfKeySize); - if (local_credential.has_value()) { - // two-way authentication, private identity. - auto signer = crypto::Ed25519Signer::Create( - (*local_credential).connection_signing_key().key()); - if (!signer.ok()) { - return signer.status(); - } - auto pkey_signature = - signer->Sign(absl::StrCat(kDiscovererMessageHeader, ukey2_secret)); - if (!pkey_signature.has_value()) { - return absl::InternalError("Signing using private key failed."); - } - return ConnectionAuthenticator::TwoWayInitiatorData{ - .shared_credential_hash = shared_credential_hash, - .private_key_signature = *pkey_signature, - }; - } - // one-way authentication, trusted identity. - return ConnectionAuthenticator::OneWayInitiatorData{ - .shared_credential_hash = shared_credential_hash, - }; -} - -absl::StatusOr -ConnectionAuthenticatorImpl::BuildSignedMessageAsResponder( - absl::string_view ukey2_secret, - const internal::LocalCredential& local_credential) const { - auto signer = crypto::Ed25519Signer::Create( - local_credential.connection_signing_key().key()); - if (!signer.ok()) { - return signer.status(); - } - auto pkey_signature = - signer->Sign(absl::StrCat(kBroadcasterMessageHeader, ukey2_secret)); - if (!pkey_signature.has_value()) { - return absl::InternalError("Signing using private key failed."); - } - return ConnectionAuthenticator::ResponderData{.private_key_signature = - *pkey_signature}; -} - -absl::Status ConnectionAuthenticatorImpl::VerifyMessageAsInitiator( - ResponderData authentication_data, absl::string_view ukey2_secret, - const std::vector& shared_credentials) const { - if (authentication_data.private_key_signature.empty()) { - return absl::InvalidArgumentError("Empty private key signature."); - } - for (const auto& shared_credential : shared_credentials) { - auto verifier = crypto::Ed25519Verifier::Create( - shared_credential.connection_signature_verification_key()); - if (!verifier.ok()) { - continue; - } - // Verify ED25519 signature, returning true if verification succeeded. - if (verifier - ->Verify(absl::StrCat(kBroadcasterMessageHeader, ukey2_secret), - authentication_data.private_key_signature) - .ok()) { - return absl::OkStatus(); - } - } - return absl::InternalError("Unable to verify responder's private key sig."); -} - -absl::StatusOr -ConnectionAuthenticatorImpl::VerifyMessageAsResponder( - absl::string_view ukey2_secret, InitiatorData initiator_data, - const std::vector& local_credentials, - const std::vector& shared_credentials) const { - std::string shared_credential_hash; - std::optional matched_local_credential; - if (absl::holds_alternative(initiator_data)) { - // one-way. we only need to verify if the hash matches one of our - // local credentials. - auto auth_data = absl::get(initiator_data); - if (auth_data.shared_credential_hash.size() != - kPresenceAuthenticatorHkdfKeySize) { - return absl::InvalidArgumentError("Invalid shared credential hash size."); - } - for (const auto& local_credential : local_credentials) { - // Verify Credential ID hash. - auto cid_hash = crypto::HkdfSha256( - absl::StrCat(ukey2_secret, local_credential.key_seed()), kHkdfSalt, - kDiscovererHkdfInfo, kPresenceAuthenticatorHkdfKeySize); - if (crypto::SecureMemEqual(cid_hash.c_str(), - auth_data.shared_credential_hash.c_str(), - kPresenceAuthenticatorHkdfKeySize)) { - matched_local_credential = local_credential; - } - } - } else { - // two-way. we need to verify if the hash matches one of our local - // credentials _and_ make sure it matches one of our shared credentials. - // We want to check each shared credential to verify using its public key. - - // Match the local credential. - auto auth_data = absl::get(initiator_data); - if (auth_data.shared_credential_hash.size() != - kPresenceAuthenticatorHkdfKeySize) { - return absl::InvalidArgumentError("Invalid shared credential hash size."); - } - if (auth_data.private_key_signature.empty()) { - return absl::InvalidArgumentError("Empty private key signature."); - } - for (const auto& local_credential : local_credentials) { - // Verify Credential ID hash. - auto cid_hash = crypto::HkdfSha256( - absl::StrCat(ukey2_secret, local_credential.key_seed()), kHkdfSalt, - kDiscovererHkdfInfo, kPresenceAuthenticatorHkdfKeySize); - if (crypto::SecureMemEqual(cid_hash.c_str(), - auth_data.shared_credential_hash.c_str(), - kPresenceAuthenticatorHkdfKeySize)) { - matched_local_credential = local_credential; - } - } - // Now, match our shared credential. - std::optional matched_shared_credential; - for (const auto& shared_credential : shared_credentials) { - auto verifier = crypto::Ed25519Verifier::Create( - shared_credential.connection_signature_verification_key()); - if (!verifier.ok() || - verifier - ->Verify(absl::StrCat(kDiscovererMessageHeader, ukey2_secret), - auth_data.private_key_signature) - .ok()) { - matched_shared_credential = shared_credential; - break; - } - } - if (!matched_shared_credential.has_value()) { - return absl::InternalError("Unable to verify shared credential."); - } - } - if (matched_local_credential.has_value()) { - return *matched_local_credential; - } - return absl::InternalError("Unable to verify local credential."); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/connection_authenticator_impl.h b/presence/implementation/connection_authenticator_impl.h deleted file mode 100644 index 25f42ddc..00000000 --- a/presence/implementation/connection_authenticator_impl.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2023 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_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_IMPL_H_ - -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" -#include "presence/implementation/connection_authenticator.h" - -namespace nearby { -namespace presence { - -class ConnectionAuthenticatorImpl : public ConnectionAuthenticator { - public: - // Builds a signed message to be returned to Nearby Connections for - // authentication on the other side of the connection. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // local_credential - The local credential used to sign the derived - // information. If this is std::nullopt, then we will be - // performing one-way authentication. - // shared_credential - The shared credential used to decrypt the advertisement - // from the remote device. - absl::StatusOr BuildSignedMessageAsInitiator( - absl::string_view ukey2_secret, - std::optional local_credential, - const internal::SharedCredential& shared_credential) const override; - - // Builds a signed message to be returned to Nearby Connections for - // authentication on the other side of the connection. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // local_credential - The local credential used to sign the derived - // information so the initiator can verify against our - // shared credential. - absl::StatusOr BuildSignedMessageAsResponder( - absl::string_view ukey2_secret, - const internal::LocalCredential& local_credential) const override; - - // Verifies a signed message received from the responder (broadcaster) of the - // Nearby Presence advertisement. - // authentication_data - the data required to verify the connection, received - // from the responder. - // ukey2_secret - the shared secret derived from the ukey2 handshake in NC. - // shared_credentials - the set of shared credentials that can be used to - // verify the responder data. - absl::Status VerifyMessageAsInitiator( - ResponderData authentication_data, absl::string_view ukey2_secret, - const std::vector& shared_credentials) - const override; - - // Verifies a signed message received from the Nearby Connections peer. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // received_frame - The received frame from Nearby Connections. - // local_credentials - The set of local credentials that may contain the - // required keyseed hash. - // shared_credentials - The set of shared credentials that can be used to - // verify the signed contents of the frame. - absl::StatusOr VerifyMessageAsResponder( - absl::string_view ukey2_secret, InitiatorData initiator_data, - const std::vector& local_credentials, - const std::vector& shared_credentials) - const override; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_IMPL_H_ diff --git a/presence/implementation/connection_authenticator_impl_test.cc b/presence/implementation/connection_authenticator_impl_test.cc deleted file mode 100644 index e28eb477..00000000 --- a/presence/implementation/connection_authenticator_impl_test.cc +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright 2023 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. - -#include "presence/implementation/connection_authenticator_impl.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "internal/crypto/ed25519.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" - -namespace nearby { -namespace presence { -namespace { - -using ::protobuf_matchers::EqualsProto; -using ::testing::status::StatusIs; - -constexpr char kUkey2Secret[] = {0x34, 0x56, 0x78, 0x90}; -constexpr char kKeySeed1[] = {1, 2, 3, 4, 5, 6, 7, 8}; -constexpr char kKeySeed2[] = {8, 7, 6, 5, 4, 3, 2, 1}; - -internal::LocalCredential BuildLocalCredential( - const crypto::Ed25519KeyPair& key_pair, absl::string_view key_seed) { - internal::LocalCredential local_credential; - local_credential.mutable_connection_signing_key()->set_key( - absl::StrCat(key_pair.private_key, key_pair.public_key)); - local_credential.set_key_seed(key_seed); - return local_credential; -} - -internal::SharedCredential BuildSharedCredential( - const crypto::Ed25519KeyPair& key_pair, absl::string_view key_seed) { - internal::SharedCredential shared_credential; - shared_credential.set_connection_signature_verification_key( - key_pair.public_key); - shared_credential.set_key_seed(key_seed); - return shared_credential; -} - -class PresenceAuthenticatorTest : public ::testing::Test { - protected: - void SetUp() override { - auto key_pair_or_status = crypto::Ed25519Signer::CreateNewKeyPair(); - ASSERT_OK_AND_ASSIGN(auto key_pair1, key_pair_or_status); - auto key_pair2_or_status = crypto::Ed25519Signer::CreateNewKeyPair(); - ASSERT_OK_AND_ASSIGN(auto key_pair2, key_pair2_or_status); - initiator_local_credential_ = BuildLocalCredential(key_pair1, kKeySeed1); - initiator_shared_credential_ = BuildSharedCredential(key_pair1, kKeySeed1); - initiator_shared_credential_wrong_key_ = - BuildSharedCredential(key_pair2, kKeySeed1); - responder_local_credential_ = BuildLocalCredential(key_pair2, kKeySeed2); - responder_shared_credential_ = BuildSharedCredential(key_pair2, kKeySeed2); - responder_shared_credential_wrong_key_ = - BuildSharedCredential(key_pair1, kKeySeed2); - } - - internal::LocalCredential initiator_local_credential_; - internal::LocalCredential responder_local_credential_; - internal::SharedCredential initiator_shared_credential_; - internal::SharedCredential initiator_shared_credential_wrong_key_; - internal::SharedCredential responder_shared_credential_; - internal::SharedCredential responder_shared_credential_wrong_key_; -}; - -TEST_F(PresenceAuthenticatorTest, TestTwoWayInitiatorSignResponderVerify) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - auto local_credential = responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_}); - ASSERT_TRUE(local_credential.ok()); - EXPECT_THAT(*local_credential, EqualsProto(responder_local_credential_)); -} - -TEST_F(PresenceAuthenticatorTest, TestOneWayInitiatorSignResponderVerify) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN( - ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, std::nullopt, responder_shared_credential_)); - auto local_credential = responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_}); - ASSERT_TRUE(local_credential.ok()); - EXPECT_THAT(*local_credential, EqualsProto(responder_local_credential_)); -} - -TEST_F(PresenceAuthenticatorTest, TestResponderSignInitiatorVerify) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::ResponderData auth_data, - responder_authenticator.BuildSignedMessageAsResponder( - kUkey2Secret, responder_local_credential_)); - EXPECT_OK(initiator_authenticator.VerifyMessageAsInitiator( - auth_data, kUkey2Secret, {responder_shared_credential_})); -} - -TEST_F(PresenceAuthenticatorTest, - TestTwoWayInitiatorSignResponderVerifyNoSharedCredentialMatchFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {}, {initiator_shared_credential_}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestOneWayInitiatorSignResponderVerifyNoMatchCredentialFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN( - ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, std::nullopt, responder_shared_credential_)); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {}, {initiator_shared_credential_}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestOneWayInitiatorSignResponderVerifyNoCredentialFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN( - ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, std::nullopt, responder_shared_credential_)); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {}, {}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestTwoWayInitiatorSignResponderVerifyNoMatchCredentialFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {}, {initiator_shared_credential_}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestTwoWayInitiatorSignResponderVerifyWrongKeyFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_wrong_key_}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestResponderSignInitiatorVerifyNoMatchCredentialFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::ResponderData auth_data, - responder_authenticator.BuildSignedMessageAsResponder( - kUkey2Secret, responder_local_credential_)); - EXPECT_THAT(initiator_authenticator.VerifyMessageAsInitiator( - auth_data, kUkey2Secret, {}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestResponderSignInitiatorVerifyWrongKeyFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::ResponderData auth_data, - responder_authenticator.BuildSignedMessageAsResponder( - kUkey2Secret, responder_local_credential_)); - EXPECT_THAT( - initiator_authenticator.VerifyMessageAsInitiator( - auth_data, kUkey2Secret, {responder_shared_credential_wrong_key_}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestTwoWayInitiatorSignResponderVerifyNoCidHashFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - std::get(auth_data) - .shared_credential_hash.clear(); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_wrong_key_}), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST_F(PresenceAuthenticatorTest, - TestTwoWayInitiatorSignResponderVerifyNoPkeySigFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - std::get(auth_data) - .private_key_signature.clear(); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_wrong_key_}), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST_F(PresenceAuthenticatorTest, - TestOneWayInitiatorSignResponderVerifyNoCidHashFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN( - ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, std::nullopt, responder_shared_credential_)); - std::get(auth_data) - .shared_credential_hash.clear(); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_}), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST_F(PresenceAuthenticatorTest, - TestResponderSignInitiatorVerifyNoPkeySigFail) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::ResponderData auth_data, - responder_authenticator.BuildSignedMessageAsResponder( - kUkey2Secret, responder_local_credential_)); - auth_data.private_key_signature.clear(); - EXPECT_THAT(initiator_authenticator.VerifyMessageAsInitiator( - auth_data, kUkey2Secret, {responder_shared_credential_}), - StatusIs(absl::StatusCode::kInvalidArgument)); -} -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/credential_manager.h b/presence/implementation/credential_manager.h deleted file mode 100644 index 2d4e088b..00000000 --- a/presence/implementation/credential_manager.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2020 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_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_H_ - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/metadata.pb.h" - -namespace nearby { -namespace presence { - -using SubscriberId = uint64_t; - -/* - * The instance of CredentialManager is owned by {@code ServiceControllerImpl}. - * Helping service controller to manage local credentials and coordinate with - * downloaded remote credentials. - */ -class CredentialManager { - public: - CredentialManager() = default; - virtual ~CredentialManager() = default; - - // Used to (re)generate user’s private and public credentials. - // The generated private credentials will be saved to creds storage. - // The generated public credentials will be returned inside the - // credentials_generated_cb for manager app to upload to web. - // The user’s own public credentials won’t be saved on local credential - // storage. - virtual void GenerateCredentials( - const nearby::internal::DeviceIdentityMetaData& device_identity_metadata, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) = 0; - - // Update remote public credentials. - virtual void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) = 0; - - virtual void UpdateLocalCredential( - const CredentialSelector& credential_selector, - nearby::internal::LocalCredential credential, - SaveCredentialsResultCallback result_callback) = 0; - - // Used to fetch private creds when broadcasting. - virtual void GetLocalCredentials( - const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) = 0; - - // Used to fetch local/remote public creds based on the value - // of public_credential_type. - virtual void GetPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) = 0; - - // Subscribes for public credentials updates. The `callback` is triggered when - // the public credentials are fetched initially, and then every time the - // credentials change. - virtual SubscriberId SubscribeForPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) = 0; - - // Unsubscribes from public credentials updates. No new callbacks will be - // triggered after this function returns. If there is a callback already - // running, that callback may continue after - // `UnsubscribeFromPublicCredentials()` return. - virtual void UnsubscribeFromPublicCredentials(SubscriberId id) = 0; - - // Decrypts the device identity metadata from a public credential. - // Returns an empty string if decryption fails. - virtual std::string DecryptDeviceIdentityMetaData( - absl::string_view metadata_encryption_key, absl::string_view key_seed, - absl::string_view metadata_string) = 0; - - // If `regen_credentials` is set to true, regenerating credentials. - virtual void SetDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) = 0; - - virtual ::nearby::internal::DeviceIdentityMetaData - GetDeviceIdentityMetaData() = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_H_ diff --git a/presence/implementation/credential_manager_impl.cc b/presence/implementation/credential_manager_impl.cc deleted file mode 100644 index d49d2f56..00000000 --- a/presence/implementation/credential_manager_impl.cc +++ /dev/null @@ -1,834 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/credential_manager_impl.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "absl/types/span.h" -#include "absl/types/variant.h" -#include "internal/crypto_cros/aead.h" -#include "internal/crypto_cros/ec_private_key.h" -#include "internal/crypto_cros/hkdf.h" -#include "internal/platform/base64_utils.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/crypto.h" -#include "internal/platform/future.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/implementation/crypto.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/logging.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" -#include "presence/data_types.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/ldt.h" - -namespace nearby { -namespace presence { -namespace { -using ::nearby::Base64Utils; -using ::nearby::Crypto; -using ::nearby::Exception; -using ::nearby::ExceptionOr; -using ::nearby::Future; -using ::nearby::internal::IdentityType; -using ::nearby::internal::LocalCredential; -using ::nearby::internal::SharedCredential; - -// Key to retrieve local device's Private/Public Key Credentials from key store. -constexpr char kPairedKeyAliasPrefix[] = "nearby_presence_paired_key_alias_"; - -// Use an empty string because Chromium only supports 1 account. -// Windows & Apple will have their own Identity Provider. -constexpr absl::string_view kEmptyAccountName = ""; - -// The expected number of valid local credentials to be stored on local device. -constexpr int kExpectedValidLocalCredtialSize = 6; -// The expiration time in days for a credential. -constexpr int kCredentialLifeCycleDays = 5; -// The minimum size of bytes to generate credential id. -constexpr int kExpectedByteSizeOfCredentialId = 8; - -// Returns a random duration in [0, max_duration] range. -absl::Duration RandomDuration(absl::Duration max_duration) { - uint32_t random = nearby::RandData(); - return max_duration * random / std::numeric_limits::max(); -} - -std::string CustomizeBytesSize(absl::string_view bytes, size_t len) { - return crypto::HkdfSha256( - /*ikm=*/std::string(bytes), // NOLINT - /*salt=*/std::string(CredentialManagerImpl::kAuthenticityKeyByteSize, 0), - /*info=*/"", /*derived_key_size=*/len); -} - -} // namespace - -// Returns a positive long value extracted from a byte array. -int64_t GenerateIdFromByteArray(const ByteArray& input) { - size_t inputLength = input.size(); - - ByteArray processed_bytes(kExpectedByteSizeOfCredentialId); - // Only use first 8 bytes if the input is longer than 8 bytes. - if (inputLength > kExpectedByteSizeOfCredentialId) { - processed_bytes.CopyAt(0, input); - } else { - // Extend the input with zeros if it's shorter than 8 bytes - processed_bytes.CopyAt(kExpectedByteSizeOfCredentialId - inputLength, - input); - } - - int64_t id = 0; - for (int i = 0; i < kExpectedByteSizeOfCredentialId; ++i) { - id |= (static_cast(processed_bytes.data()[i]) << (8 * i)); - } - if (id == std::numeric_limits::min()) - return std::numeric_limits::max(); - return std::abs(id); -} - -void CredentialManagerImpl::GenerateCredentials( - const DeviceIdentityMetaData& device_identity_metadata, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) { - std::vector public_credentials; - std::vector private_credentials; - - for (auto identity_type : identity_types) { - absl::Time start_time = SystemClock::ElapsedRealtime(); - absl::Duration gap = credential_life_cycle_days * absl::Hours(24); - for (int index = 0; index < contiguous_copy_of_credentials; index++) { - auto public_private_credentials = - CreateLocalCredential(device_identity_metadata, identity_type, - start_time, start_time + gap); - if (public_private_credentials.second.identity_type() != - IdentityType::IDENTITY_TYPE_UNSPECIFIED) { - private_credentials.push_back(public_private_credentials.first); - public_credentials.push_back(public_private_credentials.second); - } - start_time += gap; - } - } - - // Create credential_storage object and invoke SaveCredentials. - credential_storage_ptr_->SaveCredentials( - manager_app_id, kEmptyAccountName, private_credentials, - public_credentials, PublicCredentialType::kLocalPublicCredential, - SaveCredentialsResultCallback{ - .credentials_saved_cb = - [this, manager_app_id = std::string(manager_app_id), - account_name = kEmptyAccountName, - callback = std::move(credentials_generated_cb), - public_credentials](absl::Status status) mutable { - if (!status.ok()) { - LOG(WARNING) << "Save credentials failed with: " << status; - std::move(callback.credentials_generated_cb)(status); - return; - } - std::move(callback.credentials_generated_cb)( - std::move(public_credentials)); - RunOnServiceControllerThread( - "local-creds-changed", - [this, manager_app_id = std::string(manager_app_id), - account_name = std::string(account_name)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - OnCredentialsChanged( - manager_app_id, account_name, - PublicCredentialType::kLocalPublicCredential); - }); - }}); -} - -void CredentialManagerImpl::UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) { - credential_storage_ptr_->SaveCredentials( - manager_app_id, account_name, /* private_credentials */ {}, - remote_public_creds, PublicCredentialType::kRemotePublicCredential, - SaveCredentialsResultCallback{ - .credentials_saved_cb = - [this, manager_app_id = std::string(manager_app_id), - account_name = std::string(account_name), - callback = std::move(credentials_updated_cb)]( - absl::Status status) mutable { - if (!status.ok()) { - LOG(WARNING) - << "Update remote credentials failed with: " << status; - } else { - RunOnServiceControllerThread( - "remote-creds-changed", - [this, manager_app_id = std::string(manager_app_id), - account_name = std::string(account_name)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - OnCredentialsChanged( - manager_app_id, account_name, - PublicCredentialType::kRemotePublicCredential); - }); - } - std::move(callback.credentials_updated_cb)(status); - }}); -} - -std::pair -CredentialManagerImpl::CreateLocalCredential( - const DeviceIdentityMetaData& device_identity_metadata, - IdentityType identity_type, absl::Time start_time, absl::Time end_time) { - LocalCredential private_credential; - private_credential.set_start_time_millis(absl::ToUnixMillis(start_time)); - private_credential.set_end_time_millis(absl::ToUnixMillis(end_time)); - private_credential.set_identity_type(identity_type); - - // Creates an AES key to encrypt the whole broadcast. - std::string secret_key(kAuthenticityKeyByteSize, 0); - RandBytes(const_cast(secret_key.data()), - secret_key.size()); - private_credential.set_key_seed(secret_key); - - // Uses SHA-256 algorithm to generate the credential ID from the - // authenticity key - auto secret_id = Crypto::Sha256(secret_key); - // Does not expect to fail here since Crypto::Sha256 should not return - // empty ByteArray. - CHECK(!secret_id.Empty()) << "Crypto::Sha256 failed!"; - - private_credential.set_id(GenerateIdFromByteArray(secret_id)); - - std::string alias = Base64Utils::Encode(secret_id); - auto prefixedAlias = kPairedKeyAliasPrefix + alias; - - // Generate key pair. Store the private key in private credential. - auto key_pair = crypto::ECPrivateKey::Create(); - std::vector private_key; - key_pair->ExportPrivateKey(&private_key); - private_credential.mutable_connection_signing_key()->set_key( - std::string(private_key.begin(), private_key.end())); - // Create an AES key to encrypt the device identity metadata. - std::string metadata_key(kBaseMetadataSize, 0); - RandBytes(const_cast(metadata_key.data()), - metadata_key.size()); - private_credential.set_metadata_encryption_key_v0(metadata_key); - - // Generate the public credential - std::vector public_key; - key_pair->ExportPublicKey(&public_key); - - return std::pair( - private_credential, - CreatePublicCredential(private_credential, device_identity_metadata, - public_key)); -} - -SharedCredential CredentialManagerImpl::CreatePublicCredential( - const LocalCredential& private_credential, - const DeviceIdentityMetaData& device_identity_metadata, - const std::vector& public_key) { - // The start time in the public credential should be decreased by a random - // value in 0 - 3 hours range. - // The end time should be increased by a random value in 0 - 3 hours range. - // This improves privacy by making it harder to correlate certificates. - absl::Time start_time = - absl::FromUnixMillis(private_credential.start_time_millis()) - - RandomDuration(absl::Hours(3)); - absl::Time end_time = - absl::FromUnixMillis(private_credential.end_time_millis()) + - RandomDuration(absl::Hours(3)); - SharedCredential public_credential; - public_credential.set_identity_type(private_credential.identity_type()); - public_credential.set_id(private_credential.id()); - public_credential.set_key_seed(private_credential.key_seed()); - public_credential.set_start_time_millis(absl::ToUnixMillis(start_time)); - public_credential.set_end_time_millis(absl::ToUnixMillis(end_time)); - // Set up the public key. Note, we are setting the "connection" key but we are - // not setting the "advertisement" key because the latter is not used yet. - public_credential.set_connection_signature_verification_key( - std::string(public_key.begin(), public_key.end())); - - auto metadata_encryption_key_tag = - Crypto::Sha256(private_credential.metadata_encryption_key_v0()); - public_credential.set_metadata_encryption_key_tag_v0( - std::string(metadata_encryption_key_tag.AsStringView())); - - auto encrypted_meta_data = EncryptDeviceIdentityMetaData( - private_credential.metadata_encryption_key_v0(), - private_credential.key_seed(), - device_identity_metadata.SerializeAsString()); - - if (encrypted_meta_data.empty()) { - LOG(ERROR) << "Fails to encrypt the device identity metadata."; - public_credential.set_identity_type( - IdentityType::IDENTITY_TYPE_UNSPECIFIED); - return public_credential; - } - - public_credential.set_encrypted_metadata_bytes_v0(encrypted_meta_data); - return public_credential; -} - -std::string CredentialManagerImpl::DecryptDeviceIdentityMetaData( - absl::string_view metadata_encryption_key, absl::string_view key_seed, - absl::string_view metadata_string) { - crypto::Aead aead(crypto::Aead::AeadAlgorithm::AES_256_GCM); - - std::vector derived_key = - ExtendMetadataEncryptionKey(metadata_encryption_key); - aead.Init(derived_key); - - auto iv = CustomizeBytesSize(key_seed, CredentialManagerImpl::kAesGcmIVSize); - std::vector iv_bytes(iv.begin(), iv.end()); - std::vector encrypted_metadata_bytes(metadata_string.begin(), - metadata_string.end()); - - auto result = aead.Open(encrypted_metadata_bytes, - /*nonce=*/ - iv_bytes, - /*additional_data=*/absl::Span()); - - return std::string(result.value().begin(), result.value().end()); -} - -std::string CredentialManagerImpl::EncryptDeviceIdentityMetaData( - absl::string_view metadata_encryption_key, absl::string_view key_seed, - absl::string_view metadata_string) { - crypto::Aead aead(crypto::Aead::AeadAlgorithm::AES_256_GCM); - - std::vector derived_key = - ExtendMetadataEncryptionKey(metadata_encryption_key); - - aead.Init(derived_key); - - auto iv = CustomizeBytesSize(key_seed, kAesGcmIVSize); - std::vector iv_bytes(iv.begin(), iv.end()); - - std::vector metadata_bytes(metadata_string.begin(), - metadata_string.end()); - metadata_bytes.resize(metadata_string.size()); - - auto encrypted = aead.Seal(metadata_bytes, - /*nonce=*/ - iv_bytes, - /*additional_data=*/absl::Span()); - - return std::string(encrypted.begin(), encrypted.end()); -} - -std::vector CredentialManagerImpl::ExtendMetadataEncryptionKey( - absl::string_view metadata_encryption_key) { - return crypto::HkdfSha256( - std::vector(metadata_encryption_key.begin(), - metadata_encryption_key.end()), - /*salt=*/absl::Span(), - /*info=*/absl::Span(), kNearbyPresenceNumBytesAesGcmKeySize); -} - -void CredentialManagerImpl::GetLocalCredentials( - const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - credential_storage_ptr_->GetLocalCredentials( - credential_selector, - GetLocalCredentialsResultCallback{ - .credentials_fetched_cb = - [this, credential_selector, callback = std::move(callback)]( - absl::StatusOr> - get_local_credentials_result) mutable { - if (!get_local_credentials_result.ok()) { - callback.credentials_fetched_cb( - get_local_credentials_result.status()); - return; - } - - CheckCredentialsAndRefillIfNeeded( - credential_selector, - /* credentials_list_variant */ - &get_local_credentials_result.value(), - /* callback_for_local_credentials */ - std::move(callback), - /* callback_for_shared_credentials */ - std::nullopt); - }, - }); -} - -void CredentialManagerImpl::GetPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) { - // Not going to refill for remote SharedCredentials. - if (public_credential_type == PublicCredentialType::kRemotePublicCredential) { - credential_storage_ptr_->GetPublicCredentials( - credential_selector, public_credential_type, std::move(callback)); - return; - } - - credential_storage_ptr_->GetPublicCredentials( - credential_selector, public_credential_type, - GetPublicCredentialsResultCallback{ - .credentials_fetched_cb = - [this, credential_selector, callback = std::move(callback)]( - absl::StatusOr> - get_shared_credentials_result) mutable { - if (!get_shared_credentials_result.ok()) { - callback.credentials_fetched_cb( - get_shared_credentials_result.status()); - return; - } - - CheckCredentialsAndRefillIfNeeded( - credential_selector, - /* credentials_list_variant */ - &get_shared_credentials_result.value(), - /* callback_for_local_credentials */ std::nullopt, - /* callback_for_shared_credentials */ - std::move(callback)); - }, - }); -} - -ExceptionOr> -CredentialManagerImpl::GetLocalCredentialsSync( - const CredentialSelector& credential_selector, absl::Duration timeout) { - Future> result; - GetLocalCredentials(credential_selector, - {.credentials_fetched_cb = - [result](absl::StatusOr> - credentials) mutable { - if (!credentials.ok()) { - result.SetException({Exception::kFailed}); - } else { - result.Set(std::move(*credentials)); - } - }}); - return result.Get(timeout); -} - -ExceptionOr> -CredentialManagerImpl::GetPublicCredentialsSync( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, absl::Duration timeout) { - Future> result; - GetPublicCredentials( - credential_selector, public_credential_type, - {.credentials_fetched_cb = - [result](absl::StatusOr> - credentials) mutable { - if (!credentials.ok()) { - result.SetException({Exception::kFailed}); - } else { - result.Set(std::move(*credentials)); - } - }}); - return result.Get(timeout); -} - -// TODO(b/326063431): The intent of this method is likely for -// GetPublicCredentials() to be called after the AddSubscriber() calls, but -// it's unlikely that this is happening on a real device. Manually verify. -SubscriberId CredentialManagerImpl::SubscribeForPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) { - SubscriberId id = nearby::RandData(); - RunOnServiceControllerThread( - "add-subscriber", - [this, key = SubscriberKey{credential_selector, public_credential_type}, - id, callback = std::move(callback)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) mutable { - AddSubscriber(key, id, std::move(callback)); - }); - GetPublicCredentials(credential_selector, public_credential_type, - CreateNotifySubscribersCallback( - {credential_selector, public_credential_type})); - return id; -} - -void CredentialManagerImpl::UnsubscribeFromPublicCredentials(SubscriberId id) { - RunOnServiceControllerThread("remove-subscriber", - [this, id]() ABSL_EXCLUSIVE_LOCKS_REQUIRED( - *executor_) { RemoveSubscriber(id); }); -} - -void CredentialManagerImpl::AddSubscriber( - SubscriberKey key, SubscriberId id, - GetPublicCredentialsResultCallback callback) { - subscribers_[key].push_back(Subscriber(id, std::move(callback))); -} - -void CredentialManagerImpl::RemoveSubscriber(SubscriberId id) { - for (auto& entry : subscribers_) { - auto it = std::find_if( - entry.second.begin(), entry.second.end(), - [&](Subscriber& subscriber) { return subscriber.GetId() == id; }); - if (it != entry.second.end()) { - entry.second.erase(it); - if (subscribers_[entry.first].empty()) { - subscribers_.erase(entry.first); - } - return; - } - } -} - -absl::flat_hash_set -CredentialManagerImpl::GetSubscribedIdentities( - absl::string_view manager_app_id, absl::string_view account_name, - PublicCredentialType credential_type) const { - absl::flat_hash_set identities; - for (auto& entry : subscribers_) { - const SubscriberKey& key = entry.first; - if (key.public_credential_type == credential_type && - key.credential_selector.manager_app_id == manager_app_id && - key.credential_selector.account_name == account_name) { - identities.insert(key.credential_selector.identity_type); - } - } - return identities; -} - -void CredentialManagerImpl::OnCredentialsChanged( - absl::string_view manager_app_id, absl::string_view account_name, - PublicCredentialType credential_type) { - LOG(INFO) << "OnCredentialsChanged for app " << manager_app_id << ", account " - << account_name; - for (IdentityType identity_type : - GetSubscribedIdentities(manager_app_id, account_name, credential_type)) { - CredentialSelector credential_selector = { - .manager_app_id = std::string(manager_app_id), - .account_name = std::string(account_name), - .identity_type = identity_type}; - GetPublicCredentials(credential_selector, credential_type, - CreateNotifySubscribersCallback( - {credential_selector, credential_type})); - } -} - -GetPublicCredentialsResultCallback -CredentialManagerImpl::CreateNotifySubscribersCallback(SubscriberKey key) { - return GetPublicCredentialsResultCallback{ - .credentials_fetched_cb = - [this, - key](absl::StatusOr> credentials) { - if (!credentials.ok()) { - LOG(WARNING) << "Failed to get public credentials: error code: " - << credentials.status(); - return; - } - RunOnServiceControllerThread( - "notify-subscribers", - [this, key, credentials = std::move(*credentials)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - NotifySubscribers(key, credentials); - }); - }}; -} - -void CredentialManagerImpl::NotifySubscribers( - const SubscriberKey& key, std::vector credentials) { - // We are on `executor_` thread, so we can iterate over `subscribers_` - // without locking. - auto it = subscribers_.find(key); - if (it == subscribers_.end()) { - LOG(WARNING) << "No subscribers for (app: " - << key.credential_selector.manager_app_id - << ", account: " << key.credential_selector.account_name - << ", identity type: " - << static_cast(key.credential_selector.identity_type) - << ", credential type: " - << static_cast(key.public_credential_type) << ")"; - return; - } - for (auto& subscriber : it->second) { - subscriber.NotifyCredentialsFetched(credentials); - } -} - -void CredentialManagerImpl::Subscriber::NotifyCredentialsFetched( - std::vector& credentials) { - callback_.credentials_fetched_cb(credentials); -} - -void CredentialManagerImpl::UpdateLocalCredential( - const CredentialSelector& credential_selector, - nearby::internal::LocalCredential credential, - SaveCredentialsResultCallback result_callback) { - credential_storage_ptr_->UpdateLocalCredential( - credential_selector.manager_app_id, credential_selector.account_name, - std::move(credential), std::move(result_callback)); -} - -void CredentialManagerImpl::CheckCredentialsAndRefillIfNeeded( - const CredentialSelector& credential_selector, - absl::variant*, - std::vector*> - credential_list_variant, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials) { - bool invoked_for_local = false; - int valid_credentials_count = 0; - int64_t current_time_millis = - absl::ToUnixMillis(SystemClock::ElapsedRealtime()); - int64_t last_valid_end_time_millis = current_time_millis; - - std::vector valid_local_credentials; - std::vector valid_shared_credentials; - if (absl::holds_alternative*>( - credential_list_variant) && - callback_for_local_credentials.has_value()) { - invoked_for_local = true; - for (auto& credential : - *absl::get*>( - credential_list_variant)) { - if (credential.end_time_millis() < current_time_millis) { - continue; - } - valid_credentials_count++; - if (last_valid_end_time_millis < credential.end_time_millis()) { - last_valid_end_time_millis = credential.end_time_millis(); - } - valid_local_credentials.push_back(credential); - } - } else if (absl::holds_alternative< - std::vector*>( - credential_list_variant) && - callback_for_shared_credentials.has_value()) { - for (auto& credential : - *absl::get*>( - credential_list_variant)) { - if (credential.end_time_millis() < current_time_millis) { - continue; - } - valid_credentials_count++; - if (last_valid_end_time_millis < credential.end_time_millis()) { - last_valid_end_time_millis = credential.end_time_millis(); - } - valid_shared_credentials.push_back(credential); - } - } else { - LOG(ERROR) << "Bad parameters for CheckCredentialsAndRefillIfNeeded"; - return; - } - - // Most invokes are expected to return early here as it already got enough - // valid credentials, no need to refill. - // Otherwise, the long process of refill (another read, merge, then save) - // would start. - if (valid_credentials_count >= kExpectedValidLocalCredtialSize) { - if (invoked_for_local) { - callback_for_local_credentials.value().credentials_fetched_cb( - valid_local_credentials); - } else { - callback_for_shared_credentials.value().credentials_fetched_cb( - valid_shared_credentials); - } - return; - } - - // Already got the valid credential list for either local or shared. - // Now get the other credentials list from storage, prune them, and begin - // the process of appending new credentials onto them. - if (invoked_for_local) { - credential_storage_ptr_->GetPublicCredentials( - credential_selector, PublicCredentialType::kLocalPublicCredential, - GetPublicCredentialsResultCallback{ - .credentials_fetched_cb = - [this, current_time_millis, last_valid_end_time_millis, - credential_selector, - valid_local_credentials = std::move(valid_local_credentials), - valid_shared_credentials = std::move(valid_shared_credentials), - callback_for_local_credentials = - std::move(callback_for_local_credentials), - callback_for_shared_credentials = - std::move(callback_for_shared_credentials)]( - absl::StatusOr< - std::vector> - result) mutable { - if (!result.ok()) { - callback_for_local_credentials.value() - .credentials_fetched_cb(result.status()); - return; - } - for (const auto& credential : result.value()) { - if (credential.end_time_millis() >= current_time_millis) { - valid_shared_credentials.push_back(credential); - } - } - - RefillRemainingValidCredentialsWithNewCredentials( - credential_selector, valid_local_credentials, - valid_shared_credentials, - /*start_time_to_generate_new_credentials_millis=*/ - last_valid_end_time_millis, - std::move(callback_for_local_credentials), - std::move(callback_for_shared_credentials)); - }, - }); - } else { - credential_storage_ptr_->GetLocalCredentials( - credential_selector, - GetLocalCredentialsResultCallback{ - .credentials_fetched_cb = - [this, current_time_millis, last_valid_end_time_millis, - credential_selector, - valid_local_credentials = std::move(valid_local_credentials), - valid_shared_credentials = std::move(valid_shared_credentials), - callback_for_local_credentials = - std::move(callback_for_local_credentials), - callback_for_shared_credentials = - std::move(callback_for_shared_credentials)]( - absl::StatusOr< - std::vector> - result) mutable { - if (!result.ok()) { - callback_for_local_credentials.value() - .credentials_fetched_cb(result.status()); - return; - } - for (const auto& credential : result.value()) { - if (credential.end_time_millis() >= current_time_millis) { - valid_local_credentials.push_back( - credential); // RESTORE TODO - } - } - - RefillRemainingValidCredentialsWithNewCredentials( - credential_selector, valid_local_credentials, - valid_shared_credentials, - /*start_time_to_generate_new_credentials_millis=*/ - last_valid_end_time_millis, - std::move(callback_for_local_credentials), - std::move(callback_for_shared_credentials)); - }, - }); - } -} - -void CredentialManagerImpl::RefillRemainingValidCredentialsWithNewCredentials( - const CredentialSelector& credential_selector, - std::vector valid_local_credentials, - std::vector valid_shared_credentials, - int64_t start_time_to_generate_new_credentials_millis, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials) { - // The number of valid credentials has already been determined by pruning - // valid_local_credentials and valid_shared_credentials. They must match - // in size. - int valid_credentials_count = valid_local_credentials.size(); - CHECK_EQ(valid_credentials_count, valid_shared_credentials.size()); - - std::vector newly_generated_local_credentials; - std::vector newly_generated_shared_credentials; - - // Generate more credential pairs to refill the expired ones. - auto start_time = - absl::FromUnixMillis(start_time_to_generate_new_credentials_millis); - auto gap = kCredentialLifeCycleDays * absl::Hours(24); - for (int i = 0; i < kExpectedValidLocalCredtialSize - valid_credentials_count; - i++) { - auto pair = CreateLocalCredential(device_identity_metadata_, - credential_selector.identity_type, - start_time, start_time + gap); - newly_generated_local_credentials.push_back(std::move(pair.first)); - newly_generated_shared_credentials.push_back(std::move(pair.second)); - start_time += gap; - } - - // Now merge newly generated credentials to already existing valid ones. - valid_local_credentials.insert(valid_local_credentials.end(), - newly_generated_local_credentials.begin(), - newly_generated_local_credentials.end()); - valid_shared_credentials.insert(valid_shared_credentials.end(), - newly_generated_shared_credentials.begin(), - newly_generated_shared_credentials.end()); - - // Save merged local and shared credential lists to storage - credential_storage_ptr_->SaveCredentials( - credential_selector.manager_app_id, credential_selector.account_name, - valid_local_credentials, valid_shared_credentials, - PublicCredentialType::kLocalPublicCredential, - SaveCredentialsResultCallback{ - .credentials_saved_cb = - [this, valid_local_credentials, valid_shared_credentials, - callback_for_local_credentials = - std::move(callback_for_local_credentials), - callback_for_shared_credentials = - std::move(callback_for_shared_credentials)]( - absl::Status status) mutable { - OnCredentialRefillComplete( - std::move(status), valid_local_credentials, - valid_shared_credentials, - std::move(callback_for_local_credentials), - std::move(callback_for_shared_credentials)); - }, - }); -} - -void CredentialManagerImpl::OnCredentialRefillComplete( - absl::Status save_credentials_status, - std::vector valid_local_credentials, - std::vector valid_shared_credentials, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials) { - if (!save_credentials_status.ok()) { - LOG(ERROR) << "Save credentials failed with: " << save_credentials_status; - if (callback_for_local_credentials.has_value()) { - callback_for_local_credentials.value().credentials_fetched_cb( - save_credentials_status); - } else { - callback_for_shared_credentials.value().credentials_fetched_cb( - save_credentials_status); - } - return; - } - - if (callback_for_local_credentials.has_value()) { - callback_for_local_credentials.value().credentials_fetched_cb( - valid_local_credentials); - } else { - callback_for_shared_credentials.value().credentials_fetched_cb( - valid_shared_credentials); - } -} - -bool CredentialManagerImpl::WaitForLatch(absl::string_view method_name, - CountDownLatch* latch) { - Exception await_exception = latch->Await(); - if (!await_exception.Ok()) { - LOG(ERROR) << "Blocked in " << method_name - << " with exeception code: " << await_exception.value; - return false; - } - return true; -} -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/credential_manager_impl.h b/presence/implementation/credential_manager_impl.h deleted file mode 100644 index 9cd2c99e..00000000 --- a/presence/implementation/credential_manager_impl.h +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright 2022 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_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_IMPL_H_ - -#include -#include -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/container/flat_hash_map.h" -#include "absl/log/die_if_null.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "absl/types/variant.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/credential_storage_impl.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/runnable.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/implementation/credential_manager.h" - -namespace nearby { -namespace presence { - -class CredentialManagerImpl : public CredentialManager { - public: - using IdentityType = ::nearby::internal::IdentityType; - using DeviceIdentityMetaData = ::nearby::internal::DeviceIdentityMetaData; - - explicit CredentialManagerImpl(SingleThreadExecutor* executor) - : executor_(ABSL_DIE_IF_NULL(executor)) { - credential_storage_ptr_ = std::make_unique(); - } - - // Test purpose only. - CredentialManagerImpl( - SingleThreadExecutor* executor, - std::unique_ptr credential_storage_ptr) - : executor_(ABSL_DIE_IF_NULL(executor)), - credential_storage_ptr_(std::move(credential_storage_ptr)) {} - - // AES only supports key sizes of 16, 24 or 32 bytes. - static constexpr int kAuthenticityKeyByteSize = 32; - - // Length of key in bytes required by AES-GCM encryption. - static constexpr size_t kNearbyPresenceNumBytesAesGcmKeySize = 32; - - // Modify this to 12 after use real AES. - static constexpr int kAesGcmIVSize = 12; - - void GenerateCredentials( - const DeviceIdentityMetaData& device_identity_metadata, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override; - - void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) override; - - void UpdateLocalCredential( - const CredentialSelector& credential_selector, - nearby::internal::LocalCredential credential, - SaveCredentialsResultCallback result_callback) override; - - void GetLocalCredentials(const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) override; - - // Blocking version of `GetLocalCredentials` - nearby::ExceptionOr> - GetLocalCredentialsSync(const CredentialSelector& credential_selector, - absl::Duration timeout); - - // Used to fetch local/remote public creds based on the value of - // public_credential_type. - void GetPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) override; - - // Blocking version of `GetPublicCredentials`. - ::nearby::ExceptionOr> - GetPublicCredentialsSync(const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - absl::Duration timeout); - - SubscriberId SubscribeForPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) override; - - void UnsubscribeFromPublicCredentials(SubscriberId id) override; - - std::string DecryptDeviceIdentityMetaData( - absl::string_view metadata_encryption_key, absl::string_view key_seed, - absl::string_view metadata_string) override; - - std::pair - CreateLocalCredential(const DeviceIdentityMetaData& device_identity_metadata, - IdentityType identity_type, absl::Time start_time, - absl::Time end_time); - - nearby::internal::SharedCredential CreatePublicCredential( - const nearby::internal::LocalCredential& private_credential, - const DeviceIdentityMetaData& device_identity_metadata, - const std::vector& public_key); - - virtual std::string EncryptDeviceIdentityMetaData( - absl::string_view metadata_encryption_key, absl::string_view key_seed, - absl::string_view metadata_string); - - // Extend the key from 16 bytes to 32 bytes. - std::vector ExtendMetadataEncryptionKey( - absl::string_view metadata_encryption_key); - - void SetDeviceIdentityMetaData( - const DeviceIdentityMetaData& device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override { - device_identity_metadata_ = device_identity_metadata; - if (regen_credentials) { - GenerateCredentials(device_identity_metadata, manager_app_id, - identity_types, credential_life_cycle_days, - contiguous_copy_of_credentials, - std::move(credentials_generated_cb)); - } - } - - ::nearby::internal::DeviceIdentityMetaData GetDeviceIdentityMetaData() - override { - return device_identity_metadata_; - } - - private: - struct SubscriberKey { - CredentialSelector credential_selector; - PublicCredentialType public_credential_type; - template - friend H AbslHashValue(H h, const SubscriberKey& key) { - return H::combine(std::move(h), key.credential_selector, - key.public_credential_type); - } - friend bool operator==(const SubscriberKey& a, const SubscriberKey& b) { - return a.public_credential_type == b.public_credential_type && - a.credential_selector == b.credential_selector; - } - }; - class Subscriber { - public: - Subscriber(SubscriberId id, GetPublicCredentialsResultCallback callback) - : callback_(std::move(callback)), id_(id) {} - - SubscriberId GetId() const { return id_; } - - // Notifies the subscriber about fetched credentials. - void NotifyCredentialsFetched( - std::vector<::nearby::internal::SharedCredential>& credentials); - - private: - GetPublicCredentialsResultCallback callback_; - SubscriberId id_; - }; - - void RunOnServiceControllerThread(absl::string_view name, - Runnable&& runnable) { - executor_->Execute(std::string(name), std::move(runnable)); - } - - bool WaitForLatch(absl::string_view method_name, CountDownLatch* latch); - - // The similar flow to check-expired-then-refill-if-needed is needed in both - // GetLocalCredentials() and GetPublicCredentials(). The high level flow is: - // check if there're expired creds from the result credentials list from - // GetLocal/GetPublic, if some creds expired, prune the expired, merge with - // newly generated ones. Then get the corresponding(local/shared) creds list - // from the storage, also prune expired, merge with newly - // generated. Then finally, save the newly merged two lists (local & shared) - // to storage. For re-use purpose, this private function is made to be able - // to take in different parameters from both GetLocalCredentials() and - // GetPublicCredentials(). - void CheckCredentialsAndRefillIfNeeded( - const CredentialSelector& credential_selector, - absl::variant*, - std::vector*> - credential_list_variant, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials); - void RefillRemainingValidCredentialsWithNewCredentials( - const CredentialSelector& credential_selector, - std::vector valid_local_credentials, - std::vector valid_shared_credentials, - int64_t start_time_to_generate_new_credentials_millis, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials); - void OnCredentialRefillComplete( - absl::Status save_credentials_status, - std::vector valid_local_credentials, - std::vector valid_shared_credentials, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials); - - void OnCredentialsChanged(absl::string_view manager_app_id, - absl::string_view account_name, - PublicCredentialType credential_type) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void NotifySubscribers( - const SubscriberKey& key, - std::vector<::nearby::internal::SharedCredential> credentials) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void AddSubscriber(SubscriberKey key, SubscriberId id, - GetPublicCredentialsResultCallback callback) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void RemoveSubscriber(SubscriberId id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - absl::flat_hash_set GetSubscribedIdentities( - absl::string_view manager_app_id, absl::string_view account_name, - PublicCredentialType credential_type) const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - GetPublicCredentialsResultCallback CreateNotifySubscribersCallback( - SubscriberKey key); - - absl::flat_hash_map> subscribers_ - ABSL_GUARDED_BY(*executor_); - SingleThreadExecutor* executor_; - std::unique_ptr credential_storage_ptr_; - DeviceIdentityMetaData device_identity_metadata_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_IMPL_H_ diff --git a/presence/implementation/credential_manager_impl_test.cc b/presence/implementation/credential_manager_impl_test.cc deleted file mode 100644 index 44d37659..00000000 --- a/presence/implementation/credential_manager_impl_test.cc +++ /dev/null @@ -1,721 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/credential_manager_impl.h" - -#include -#include -#include -#include -#include - -#include "net/proto2/contrib/parse_proto/testing.h" -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/credential_storage_impl.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/implementation/crypto.h" -#include "internal/platform/logging.h" -#include "internal/platform/medium_environment.h" -#include "internal/proto/credential.pb.h" -#include "presence/implementation/base_broadcast_request.h" - -namespace nearby { -namespace presence { -namespace { -using ::nearby::CountDownLatch; -using ::nearby::Crypto; -using ::nearby::MediumEnvironment; -using ::nearby::internal::IdentityType; -using ::nearby::internal::LocalCredential; - -using ::nearby::internal::DeviceIdentityMetaData; -using ::nearby::internal::SharedCredential; -using ::nearby::internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP; -using ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; -using ::protobuf_matchers::EqualsProto; -using ::testing::UnorderedPointwise; -using ::testing::status::StatusIs; - -constexpr absl::string_view kManagerAppId = "TEST_MANAGER_APP"; -constexpr absl::string_view kAccountName = ""; -constexpr int kExpectedPresenceCredentialListSize = 6; -constexpr int kExpectedPresenceCredentialValidDays = 5; - -DeviceIdentityMetaData CreateTestDeviceIdentityMetaData() { - DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_device_type( - internal::DeviceType::DEVICE_TYPE_PHONE); - device_identity_metadata.set_device_name("NP test device"); - device_identity_metadata.set_bluetooth_mac_address("FF:FF:FF:FF:FF:FF"); - device_identity_metadata.set_device_id("\x12\xab\xcd"); - return device_identity_metadata; -} - -CredentialSelector BuildDefaultCredentialSelector() { - CredentialSelector credential_selector; - credential_selector.manager_app_id = std::string(kManagerAppId); - credential_selector.account_name = std::string(kAccountName); - credential_selector.identity_type = IDENTITY_TYPE_PRIVATE_GROUP; - return credential_selector; -} - -class CredentialManagerImplTest : public ::testing::Test { - public: - class MockCredentialStorage : public nearby::CredentialStorageImpl { - public: - MOCK_METHOD(void, SaveCredentials, - (absl::string_view manager_app_id, - absl::string_view account_name, - const std::vector& private_credentials, - const std::vector& public_credentials, - PublicCredentialType public_credential_type, - SaveCredentialsResultCallback callback), - (override)); - MOCK_METHOD( - void, GetPublicCredentials, - (const ::nearby::presence::CredentialSelector& credential_selector, - ::nearby::presence::PublicCredentialType public_credential_type, - ::nearby::presence::GetPublicCredentialsResultCallback callback), - (override)); - }; - - class FakeCredentialStorage : public nearby::CredentialStorageImpl { - public: - // nearby::CredentialStorageImpl: - void SaveCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& private_credentials, - const std::vector& public_credentials, - PublicCredentialType public_credential_type, - SaveCredentialsResultCallback callback) override { - // Capture the credentials before actually saving them, so that they - // can be manipulated later on. - private_credentials_ = private_credentials; - public_credentials_ = public_credentials; - - nearby::CredentialStorageImpl::SaveCredentials( - manager_app_id, account_name, private_credentials, public_credentials, - public_credential_type, std::move(callback)); - } - void GetLocalCredentials( - const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) override { - if (private_credentials_.has_value()) { - callback.credentials_fetched_cb(private_credentials_.value()); - } else { - nearby::CredentialStorageImpl::GetLocalCredentials(credential_selector, - std::move(callback)); - } - } - void GetPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) override { - if (public_credentials_.has_value()) { - callback.credentials_fetched_cb(public_credentials_.value()); - } else { - nearby::CredentialStorageImpl::GetPublicCredentials( - credential_selector, public_credential_type, std::move(callback)); - } - } - - std::optional> - public_credentials_; - std::optional> - private_credentials_; - }; - - class MockCredentialManager : public CredentialManagerImpl { - public: - explicit MockCredentialManager(SingleThreadExecutor* executor) - : CredentialManagerImpl(executor) {} - MOCK_METHOD(std::string, EncryptDeviceIdentityMetaData, - (absl::string_view metadata_encryption_key, - absl::string_view key_seed, absl::string_view metadata_string), - (override)); - }; - - ~CredentialManagerImplTest() override { executor_.Shutdown(); } - - // Waits for active tasks in the background thread to complete. - void Fence() { - // A runnable on medium environment thread can add a task on "our" executor, - // and vice-versa. We need to wait for tasks on both threads in a loop a few - // times to make sure that all tasks have finished. - for (int i = 0; i < 3; i++) { - MediumEnvironment::Instance().Sync(); - CountDownLatch latch(1); - executor_.Execute([&]() { latch.CountDown(); }); - latch.Await(); - } - } - - void AddLocalIdentity(absl::string_view manager_app_id, - absl::string_view account_name, - IdentityType identity_type) { - auto public_credentials = GenerateCredentialsSync( - CreateTestDeviceIdentityMetaData(), manager_app_id, {identity_type}, - /*credential_life_cycle_days=*/kExpectedPresenceCredentialValidDays, - /*contiguous_copy_of_credentials=*/1); - EXPECT_OK(public_credentials); - } - - absl::StatusOr> GenerateCredentialsSync( - const DeviceIdentityMetaData& device_identity_metadata, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials) { - absl::StatusOr> public_credentials; - - CountDownLatch latch(1); - credential_manager_.GenerateCredentials( - device_identity_metadata, manager_app_id, identity_types, - credential_life_cycle_days, contiguous_copy_of_credentials, - {.credentials_generated_cb = - [&](absl::StatusOr> credentials) { - public_credentials = credentials; - latch.CountDown(); - }}); - EXPECT_TRUE(latch.Await().Ok()); - - return public_credentials; - } - - std::vector GetLocalCredentialsSync( - CredentialSelector credential_selector) { - auto private_credentials = credential_manager_.GetLocalCredentialsSync( - credential_selector, absl::Seconds(1)); - EXPECT_TRUE(private_credentials.ok()); - return private_credentials.GetResult(); - } - - std::vector GetPublicCredentialsSync( - CredentialSelector credential_selector, - PublicCredentialType public_credential_type) { - auto public_credentials = credential_manager_.GetPublicCredentialsSync( - credential_selector, public_credential_type, absl::Seconds(1)); - EXPECT_TRUE(public_credentials.ok()); - return public_credentials.GetResult(); - } - - protected: - SingleThreadExecutor executor_; - CredentialManagerImpl credential_manager_{&executor_}; - MockCredentialManager mock_credential_manager_{&executor_}; -}; - -TEST_F(CredentialManagerImplTest, CreateOneCredentialSuccessfully) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - constexpr absl::Time kStartTime = absl::FromUnixSeconds(100000); - constexpr absl::Time kEndTime = absl::FromUnixSeconds(200000); - - auto credentials = credential_manager_.CreateLocalCredential( - device_identity_metadata, IDENTITY_TYPE_PRIVATE_GROUP, kStartTime, - kEndTime); - - LocalCredential private_credential = credentials.first; - // Verify the private credential. - EXPECT_EQ(private_credential.identity_type(), IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_NE(private_credential.id(), 0); - EXPECT_EQ(private_credential.start_time_millis(), - absl::ToUnixMillis(kStartTime)); - EXPECT_EQ(private_credential.end_time_millis(), absl::ToUnixMillis(kEndTime)); - EXPECT_EQ(private_credential.key_seed().size(), - CredentialManagerImpl::kAuthenticityKeyByteSize); - EXPECT_FALSE(private_credential.connection_signing_key().key().empty()); - EXPECT_EQ(private_credential.metadata_encryption_key_v0().size(), - kBaseMetadataSize); - - SharedCredential public_credential = credentials.second; - // Verify the public credential. - EXPECT_EQ(public_credential.identity_type(), IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_NE(public_credential.id(), 0); - EXPECT_EQ(private_credential.id(), public_credential.id()); - EXPECT_EQ(private_credential.key_seed(), public_credential.key_seed()); - EXPECT_LE(public_credential.start_time_millis(), - absl::ToUnixMillis(kStartTime)); - EXPECT_GE(public_credential.start_time_millis(), - absl::ToUnixMillis(kStartTime - absl::Hours(3))); - EXPECT_GE(public_credential.end_time_millis(), absl::ToUnixMillis(kEndTime)); - EXPECT_LE(public_credential.end_time_millis(), - absl::ToUnixMillis(kEndTime + absl::Hours(3))); - EXPECT_EQ(Crypto::Sha256(private_credential.metadata_encryption_key_v0()) - .AsStringView(), - public_credential.metadata_encryption_key_tag_v0()); - EXPECT_FALSE( - public_credential.connection_signature_verification_key().empty()); - EXPECT_FALSE(public_credential.encrypted_metadata_bytes_v0().empty()); - - auto decrypted_metadata = credential_manager_.DecryptDeviceIdentityMetaData( - private_credential.metadata_encryption_key_v0(), - public_credential.key_seed(), - public_credential.encrypted_metadata_bytes_v0()); - - EXPECT_EQ(device_identity_metadata.SerializeAsString(), decrypted_metadata); -} - -TEST_F(CredentialManagerImplTest, GenerateCredentialsSuccessfully) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identityTypes{IDENTITY_TYPE_PRIVATE_GROUP}; - absl::Time previous_start_time; - absl::Time previous_end_time; - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identityTypes, - kExpectedPresenceCredentialValidDays, - kExpectedPresenceCredentialListSize); - EXPECT_OK(public_credentials); - EXPECT_EQ(public_credentials->size(), kExpectedPresenceCredentialListSize); - - for (int i = 0; i < kExpectedPresenceCredentialListSize; i++) { - SharedCredential& public_credential = public_credentials->at(i); - EXPECT_EQ(public_credential.identity_type(), IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_NE(public_credential.id(), 0); - absl::Time start_time_millis = - absl::FromUnixMillis(public_credential.start_time_millis()); - absl::Time end_time_millis = - absl::FromUnixMillis(public_credential.end_time_millis()); - if (i > 0) { - EXPECT_GT(start_time_millis, previous_start_time); - EXPECT_GE(previous_end_time, start_time_millis); - EXPECT_GT(end_time_millis, previous_end_time); - } - EXPECT_LT(start_time_millis + - absl::Hours(24) * kExpectedPresenceCredentialValidDays, - end_time_millis); - EXPECT_FALSE(public_credential.encrypted_metadata_bytes_v0().empty()); - previous_start_time = start_time_millis; - previous_end_time = end_time_millis; - } -} - -TEST_F(CredentialManagerImplTest, - SubscribeCallsCallbackWithExistingCredentials) { - absl::StatusOr> public_credentials1; - absl::StatusOr> public_credentials2; - AddLocalIdentity(kManagerAppId, kAccountName, IDENTITY_TYPE_PRIVATE_GROUP); - - SubscriberId id1 = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{.manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = IDENTITY_TYPE_PRIVATE_GROUP}, - PublicCredentialType::kLocalPublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - public_credentials1 = std::move(credentials); - }}); - SubscriberId id2 = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{.manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = IDENTITY_TYPE_PRIVATE_GROUP}, - PublicCredentialType::kLocalPublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - public_credentials2 = std::move(credentials); - }}); - - Fence(); - EXPECT_OK(public_credentials1); - EXPECT_OK(public_credentials2); - EXPECT_EQ(public_credentials1->size(), kExpectedPresenceCredentialListSize); - EXPECT_EQ(public_credentials2->size(), kExpectedPresenceCredentialListSize); - // Cleanup - credential_manager_.UnsubscribeFromPublicCredentials(id1); - credential_manager_.UnsubscribeFromPublicCredentials(id2); - Fence(); -} - -TEST_F(CredentialManagerImplTest, - SubscribeCallsCallbackWithUpdatedCredentials) { - absl::StatusOr> public_credentials; - - SubscriberId id = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{.manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = IDENTITY_TYPE_PRIVATE_GROUP}, - PublicCredentialType::kLocalPublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - public_credentials = std::move(credentials); - }}); - Fence(); - EXPECT_THAT(public_credentials, StatusIs(absl::StatusCode::kUnknown)); - - AddLocalIdentity(kManagerAppId, kAccountName, IDENTITY_TYPE_PRIVATE_GROUP); - - Fence(); - ASSERT_OK(public_credentials); - EXPECT_EQ(public_credentials->size(), kExpectedPresenceCredentialListSize); - // Cleanup - credential_manager_.UnsubscribeFromPublicCredentials(id); - Fence(); -} - -TEST_F(CredentialManagerImplTest, NoCallbacksAfterUnsubscribe) { - absl::StatusOr> public_credentials; - SubscriberId id = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{.manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = IDENTITY_TYPE_PRIVATE_GROUP}, - PublicCredentialType::kLocalPublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - public_credentials = std::move(credentials); - }}); - - credential_manager_.UnsubscribeFromPublicCredentials(id); - AddLocalIdentity(kManagerAppId, kAccountName, IDENTITY_TYPE_PRIVATE_GROUP); - - Fence(); - EXPECT_THAT(public_credentials, StatusIs(absl::StatusCode::kUnknown)); -} - -TEST_F(CredentialManagerImplTest, - GenerateCredentialsSuccessfullyButStoreFailed) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - auto credential_storage_ptr = - std::make_unique(); - EXPECT_CALL(*credential_storage_ptr, SaveCredentials) - .WillOnce(::testing::Invoke( - [](absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& private_credentials, - const std::vector& public_credentials, - PublicCredentialType public_credential_type, - SaveCredentialsResultCallback callback) { - callback.credentials_saved_cb( - absl::FailedPreconditionError("Expected failure")); - })); - credential_manager_ = - CredentialManagerImpl(&executor_, std::move(credential_storage_ptr)); - std::vector identityTypes{IDENTITY_TYPE_PRIVATE_GROUP}; - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identityTypes, - kExpectedPresenceCredentialValidDays, - kExpectedPresenceCredentialListSize); - EXPECT_THAT(public_credentials, - StatusIs(absl::StatusCode::kFailedPrecondition)); -} - -TEST_F(CredentialManagerImplTest, UpdateRemotePublicCredentialsSuccessfully) { - SharedCredential public_credential_for_test; - public_credential_for_test.set_identity_type( - IdentityType::IDENTITY_TYPE_CONTACTS_GROUP); - std::vector public_credentials{ - {public_credential_for_test}}; - - nearby::CountDownLatch updated_latch(1); - UpdateRemotePublicCredentialsCallback update_credentials_cb{ - .credentials_updated_cb = - [&updated_latch](absl::Status status) { - if (status.ok()) { - updated_latch.CountDown(); - } - }, - }; - - credential_manager_.UpdateRemotePublicCredentials( - kManagerAppId, kAccountName, public_credentials, - std::move(update_credentials_cb)); - - EXPECT_TRUE(updated_latch.Await().Ok()); -} - -TEST_F(CredentialManagerImplTest, - UpdateRemotePublicCredentialsNotifiesSubscribers) { - absl::StatusOr> subscribed_credentials; - SharedCredential public_credential_for_test; - public_credential_for_test.set_identity_type( - IdentityType::IDENTITY_TYPE_PRIVATE_GROUP); - std::vector public_credentials{ - {public_credential_for_test}}; - nearby::CountDownLatch updated_latch(1); - UpdateRemotePublicCredentialsCallback update_credentials_cb{ - .credentials_updated_cb = - [&updated_latch](absl::Status status) { - if (status.ok()) { - updated_latch.CountDown(); - } - }, - }; - SubscriberId id1 = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{ - .manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = internal::IDENTITY_TYPE_PRIVATE_GROUP}, - PublicCredentialType::kRemotePublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - subscribed_credentials = std::move(credentials); - }}); - SubscriberId id2 = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{ - .manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = internal::IDENTITY_TYPE_CONTACTS_GROUP}, - PublicCredentialType::kRemotePublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - // This callback should not be called because there are no Trusted - // credentials in this test. - GTEST_FAIL(); - }}); - - credential_manager_.UpdateRemotePublicCredentials( - kManagerAppId, kAccountName, public_credentials, - std::move(update_credentials_cb)); - - EXPECT_TRUE(updated_latch.Await().Ok()); - Fence(); - EXPECT_OK(subscribed_credentials); - EXPECT_EQ(subscribed_credentials->size(), 1); - credential_manager_.UnsubscribeFromPublicCredentials(id1); - credential_manager_.UnsubscribeFromPublicCredentials(id2); -} - -TEST_F(CredentialManagerImplTest, GetLocalCredentialsFailed) { - absl::StatusOr> private_credentials; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - credential_manager_.GetLocalCredentials( - credential_selector, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - private_credentials = std::move(credentials); - }}); - - EXPECT_THAT(private_credentials, StatusIs(absl::StatusCode::kNotFound)); -} - -TEST_F(CredentialManagerImplTest, GetPublicCredentialsFailed) { - absl::StatusOr> public_credentials; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - CountDownLatch latch(1); - credential_manager_.GetPublicCredentials( - credential_selector, PublicCredentialType::kLocalPublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - public_credentials = std::move(credentials); - latch.CountDown(); - }}); - EXPECT_TRUE(latch.Await().Ok()); - - EXPECT_THAT(public_credentials, StatusIs(absl::StatusCode::kNotFound)); -} - -TEST_F(CredentialManagerImplTest, GetCredentialsSuccessfully) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP}; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, - kExpectedPresenceCredentialListSize); - EXPECT_OK(public_credentials); - EXPECT_EQ(public_credentials->size(), kExpectedPresenceCredentialListSize); - - auto private_credentials = GetLocalCredentialsSync(credential_selector); - EXPECT_FALSE(private_credentials.empty()); -} - -TEST_F(CredentialManagerImplTest, PublicCredentialsFailEncryption) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - absl::StatusOr> public_credentials; - auto credential_manager_ptr = - std::make_unique( - &executor_); - EXPECT_CALL(*credential_manager_ptr, EncryptDeviceIdentityMetaData) - .WillOnce(::testing::Invoke( - [](absl::string_view metadata_encryption_key, - absl::string_view key_seed, - absl::string_view metadata_string) { return ""; })); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP}; - - CountDownLatch latch(1); - credential_manager_ptr->GenerateCredentials( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, 1, - {.credentials_generated_cb = - [&](absl::StatusOr> credentials) { - public_credentials = std::move(credentials); - latch.CountDown(); - }}); - EXPECT_TRUE(latch.Await().Ok()); - - EXPECT_THAT(public_credentials, StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST_F(CredentialManagerImplTest, UpdateLocalCredential) { - constexpr int kSelectedCredentialId = 2; - constexpr uint16_t kSalt = 1000; - absl::Status update_status = absl::UnknownError(""); - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP, - IDENTITY_TYPE_CONTACTS_GROUP}; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, - kExpectedPresenceCredentialListSize); - - auto private_credentials = GetLocalCredentialsSync(credential_selector); - EXPECT_EQ(kExpectedPresenceCredentialListSize, private_credentials.size()); - - ASSERT_OK(public_credentials); - - // Modify a private credential - auto credential = private_credentials.at(kSelectedCredentialId); - EXPECT_TRUE( - private_credentials.at(kSelectedCredentialId).consumed_salts().empty()); - credential.mutable_consumed_salts()->insert({kSalt, true}); - - credential_manager_.UpdateLocalCredential( - credential_selector, credential, - {[&](absl::Status status) { update_status = status; }}); - - EXPECT_OK(update_status); - - // Verify that the modified credential has the new field in the new - // retrieved list of credentials. - auto modified_private_credentials = - GetLocalCredentialsSync(credential_selector); - EXPECT_TRUE(modified_private_credentials.at(kSelectedCredentialId) - .consumed_salts() - .at(kSalt)); -} - -TEST_F(CredentialManagerImplTest, EncryptAndDecryptDeviceIdentityMetaData) { - constexpr absl::string_view kMetadataEncryptionKeyBase16 = - "6331578C6E244074111B2ED0BBDB"; - constexpr absl::string_view kSeed = "123456"; - - auto encrypted_meta_data = credential_manager_.EncryptDeviceIdentityMetaData( - kMetadataEncryptionKeyBase16, kSeed, - CreateTestDeviceIdentityMetaData().SerializeAsString()); - - auto decrypted_meta_data = credential_manager_.DecryptDeviceIdentityMetaData( - kMetadataEncryptionKeyBase16, kSeed, encrypted_meta_data); - - DeviceIdentityMetaData device_identity_metadata; - ASSERT_TRUE(device_identity_metadata.ParseFromString(decrypted_meta_data)); - EXPECT_EQ(device_identity_metadata.device_id(), "\x12\xab\xcd"); - EXPECT_EQ(device_identity_metadata.device_type(), - internal::DeviceType::DEVICE_TYPE_PHONE); - EXPECT_EQ(device_identity_metadata.device_name(), "NP test device"); - EXPECT_EQ(device_identity_metadata.bluetooth_mac_address(), - "FF:FF:FF:FF:FF:FF"); -} - -TEST_F(CredentialManagerImplTest, RefillCredentialsInGetLocalCredentials) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP}; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, 1); - - EXPECT_OK(public_credentials); - EXPECT_EQ(1, public_credentials->size()); - - // only generate 1 creds, expecting GetLocal would trigger refill to - // kExpectedPresenceCredentialListSize. - auto private_credentials = GetLocalCredentialsSync(credential_selector); - EXPECT_EQ(kExpectedPresenceCredentialListSize, private_credentials.size()); -} - -TEST_F(CredentialManagerImplTest, RefillCredentialsInGetSharedCredentials) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP}; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, 1); - EXPECT_OK(public_credentials); - EXPECT_EQ(1, public_credentials->size()); - - // Only generated 1 creds, expecting GetPublicCredentials for - // kLocalPublicCredential type would trigger refill to - // kExpectedPresenceCredentialListSize. - auto refilled_public_credentials = GetPublicCredentialsSync( - credential_selector, PublicCredentialType::kLocalPublicCredential); - EXPECT_EQ(kExpectedPresenceCredentialListSize, - refilled_public_credentials.size()); -} - -TEST_F(CredentialManagerImplTest, RefillExpiredCredsInGetLocal) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP}; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - auto credential_storage = - std::make_unique(); - auto* credential_storage_ptr = credential_storage.get(); - credential_manager_ = - CredentialManagerImpl(&executor_, std::move(credential_storage)); - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, - kExpectedPresenceCredentialListSize); - - ASSERT_OK(public_credentials); - EXPECT_EQ(public_credentials->size(), kExpectedPresenceCredentialListSize); - - // Now that we have generated kExpectedPresenceCredentialListSize valid creds, - // tweak the first credential's end time, in both credential lists, to - // make them expired. - auto expiry_time = absl::ToUnixMillis(absl::Now() - absl::Hours(1)); - credential_storage_ptr->private_credentials_.value() - .at(0) - .set_end_time_millis(expiry_time); - credential_storage_ptr->public_credentials_.value().at(0).set_end_time_millis( - expiry_time); - - auto old_private_credentials = - credential_storage_ptr->private_credentials_.value(); - - auto refilled_private_credentials = - GetLocalCredentialsSync(credential_selector); - EXPECT_EQ(kExpectedPresenceCredentialListSize, - refilled_private_credentials.size()); - - // Verifying the expired one private_credentials->at(0) is pruned in the new - // list. - EXPECT_EQ(old_private_credentials.at(1).secret_id(), - refilled_private_credentials.at(0).secret_id()); - // Verifying the new generated cred's start time is the same as previously - // existing list's last cred's end time. - EXPECT_EQ( - old_private_credentials.at(5).end_time_millis(), - refilled_private_credentials.at(kExpectedPresenceCredentialListSize - 1) - .start_time_millis()); -} - -} // namespace - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/ldt.cc b/presence/implementation/ldt.cc deleted file mode 100644 index 28eac763..00000000 --- a/presence/implementation/ldt.cc +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/ldt.h" - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#ifdef NEARBY_CHROMIUM -#include "third_party/nearby/src/presence/implementation/np_ldt.h" -#else -#include "np_ldt.h" -#endif - -namespace nearby { -namespace presence { - -namespace { -// NP LDT library says that 0 is returned when `NpLdtCreate()` fails. -constexpr uint64_t kInvalidLdtHandle = 0; - -template -T FromStringView(absl::string_view data) { - T result{ - .bytes = {0}, - }; - memcpy(result.bytes, data.data(), - std::min(sizeof(result.bytes), data.size())); - return result; -} -} // namespace - -LdtEncryptor::LdtEncryptor(LdtEncryptor&& other) - : ldt_encrypt_handle_(other.ldt_encrypt_handle_), - ldt_decrypt_handle_(other.ldt_decrypt_handle_) { - other.ldt_encrypt_handle_.handle = kInvalidLdtHandle; - other.ldt_decrypt_handle_.handle = kInvalidLdtHandle; -} - -LdtEncryptor::~LdtEncryptor() { - if (ldt_encrypt_handle_.handle != kInvalidLdtHandle) { - NpLdtEncryptClose(ldt_encrypt_handle_); - } - if (ldt_decrypt_handle_.handle != kInvalidLdtHandle) { - NpLdtDecryptClose(ldt_decrypt_handle_); - } -} - -absl::StatusOr LdtEncryptor::Create( - absl::string_view key_seed, absl::string_view known_hmac) { - NpLdtEncryptHandle encrypt_handle = - NpLdtEncryptCreate(FromStringView(key_seed)); - NpLdtDecryptHandle decrypt_handle = - NpLdtDecryptCreate(FromStringView(key_seed), - FromStringView(known_hmac)); - if (encrypt_handle.handle == kInvalidLdtHandle) { - return absl::UnavailableError("Failed to create LDT encryptor"); - } - if (decrypt_handle.handle == kInvalidLdtHandle) { - return absl::UnavailableError("Failed to create LDT decrypter"); - } - - return LdtEncryptor(encrypt_handle, decrypt_handle); -} - -absl::StatusOr LdtEncryptor::Encrypt(absl::string_view data, - absl::string_view salt) { - std::string encrypted = std::string(data); - NP_LDT_RESULT result = NpLdtEncrypt( - ldt_encrypt_handle_, reinterpret_cast(encrypted.data()), - encrypted.size(), FromStringView(salt)); - if (result == NP_LDT_SUCCESS) { - return encrypted; - } - return absl::InternalError( - absl::StrFormat("LDT encryption failed, errorcode %d", result)); -} - -absl::StatusOr LdtEncryptor::DecryptAndVerify( - absl::string_view data, absl::string_view salt) { - std::string encrypted = std::string(data); - NP_LDT_RESULT result = NpLdtDecryptAndVerify( - ldt_decrypt_handle_, reinterpret_cast(encrypted.data()), - encrypted.size(), FromStringView(salt)); - if (result == NP_LDT_SUCCESS) { - return encrypted; - } - return absl::InternalError( - absl::StrFormat("LDT encryption failed, errorcode %d", result)); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/ldt.h b/presence/implementation/ldt.h deleted file mode 100644 index d86ecc10..00000000 --- a/presence/implementation/ldt.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2022 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_PRESENCE_IMPLEMENTATION_LDT_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_LDT_H_ - -#include -#include - -#ifdef NEARBY_CHROMIUM -#include "third_party/nearby/src/presence/implementation/np_ldt.h" -#else -#include "np_ldt.h" -#endif - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" - -namespace nearby { -namespace presence { - -// C++ abstraction on top of LDT C API. -class LdtEncryptor { - public: - LdtEncryptor(const LdtEncryptor&) = delete; - LdtEncryptor(LdtEncryptor&& other); - LdtEncryptor& operator=(const LdtEncryptor&) = delete; - LdtEncryptor& operator=(LdtEncryptor&& other) { - std::swap(ldt_encrypt_handle_, other.ldt_encrypt_handle_); - std::swap(ldt_decrypt_handle_, other.ldt_decrypt_handle_); - return *this; - } - ~LdtEncryptor(); - - // Creates an instance of `LdtEncryptor`. - // `key_seed` is used to generate LDT encryption and decryption keys. - // `known_hmac` is used during decryption to verify if the message was - // encrypted with the expected key. - static absl::StatusOr Create(absl::string_view key_seed, - absl::string_view known_hmac); - - // Encrypts `data`, which must be 16 - 31 bytes long. - absl::StatusOr Encrypt(absl::string_view data, - absl::string_view salt); - - // Decrypts `data` and verifies if it was encrypted with a key generated from - // `key_seed`. - absl::StatusOr DecryptAndVerify(absl::string_view data, - absl::string_view salt); - - private: - explicit LdtEncryptor(NpLdtEncryptHandle ldt_encrypt_handle, - NpLdtDecryptHandle ldt_decrypt_handle) - : ldt_encrypt_handle_(ldt_encrypt_handle), - ldt_decrypt_handle_(ldt_decrypt_handle) {} - // An opaque handle to the underlying LDT implementation. It can be null iff - // this object has already been destroyed. - NpLdtEncryptHandle ldt_encrypt_handle_; - NpLdtDecryptHandle ldt_decrypt_handle_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_LDT_H_ diff --git a/presence/implementation/ldt_stub.c b/presence/implementation/ldt_stub.c deleted file mode 100644 index cc930bd5..00000000 --- a/presence/implementation/ldt_stub.c +++ /dev/null @@ -1,47 +0,0 @@ -// 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. - -#include "presence/implementation/np_ldt.h" - -// Placeholder, empty implementations of LDT utilities. They will be replaced -// with implementations in Rust. - -NpLdtEncryptHandle NpLdtEncryptCreate(NpLdtKeySeed key_seed) { - NpLdtEncryptHandle handle = {0}; - return handle; -} - -NpLdtDecryptHandle NpLdtDecryptCreate(NpLdtKeySeed key_seed, - NpMetadataKeyHmac hmac_tag) { - NpLdtDecryptHandle handle = {0}; - return handle; -} - -NP_LDT_RESULT NpLdtEncryptClose(NpLdtEncryptHandle handle) { - return NP_LDT_SUCCESS; -} - -NP_LDT_RESULT NpLdtDecryptClose(NpLdtDecryptHandle handle) { - return NP_LDT_SUCCESS; -} - -NP_LDT_RESULT NpLdtEncrypt(NpLdtEncryptHandle handle, uint8_t* buffer, - size_t buffer_len, NpLdtSalt salt) { - return NP_LDT_SUCCESS; -} - -NP_LDT_RESULT NpLdtDecryptAndVerify(NpLdtDecryptHandle handle, uint8_t* buffer, - size_t buffer_len, NpLdtSalt salt) { - return NP_LDT_SUCCESS; -} \ No newline at end of file diff --git a/presence/implementation/ldt_test.cc b/presence/implementation/ldt_test.cc deleted file mode 100644 index b574cc7d..00000000 --- a/presence/implementation/ldt_test.cc +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2022 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. -#include "presence/implementation/ldt.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/statusor.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" - -namespace nearby { -namespace presence { - -namespace { -using ::nearby::ByteArray; - -// Test data from Android tests. -constexpr absl::string_view kKeySeedBase16 = - "CCDB2489E9FCAC42B39348B8941ED19A1D360E75E098C8C15E6B1CC2B620CD39"; -constexpr absl::string_view kKnownMacBase16 = - "B4C59FA599241B81758D976B5A621C05232FE1BF89AE5987CA254C3554DCE50E"; -constexpr absl::string_view kPlainTextBase16 = - "CD683FE1A1D1F846543D0A13D4AEA40040C8D67B"; -constexpr absl::string_view kCipherTextBase16 = - "61E481C12F4DE24F2D4AB22D8908F80D3A3F9B40"; -constexpr absl::string_view kSaltBase16 = "0C0F"; - -TEST(Ldt, EncryptAndDecrypt) { - // Test data copied from NP LDT tests - ByteArray seed({204, 219, 36, 137, 233, 252, 172, 66, 179, 147, 72, - 184, 148, 30, 209, 154, 29, 54, 14, 117, 224, 152, - 200, 193, 94, 107, 28, 194, 182, 32, 205, 57}); - ByteArray known_mac({0xB4, 0xC5, 0x9F, 0xA5, 0x99, 0x24, 0x1B, 0x81, - 0x75, 0x8D, 0x97, 0x6B, 0x5A, 0x62, 0x1C, 0x05, - 0x23, 0x2F, 0xE1, 0xBF, 0x89, 0xAE, 0x59, 0x87, - 0xCA, 0x25, 0x4C, 0x35, 0x54, 0xDC, 0xE5, 0x0E}); - ByteArray test_data({205, 104, 63, 225, 161, 209, 248, 70, 84, 61, - 10, 19, 212, 174, 164, 0, 64, 200, 214, 123}); - ByteArray salt({12, 15}); - - absl::StatusOr encryptor = - LdtEncryptor::Create(seed.AsStringView(), known_mac.AsStringView()); - ASSERT_OK(encryptor); - absl::StatusOr encrypted = - encryptor->Encrypt(test_data.AsStringView(), salt.AsStringView()); - ASSERT_OK(encrypted); - absl::StatusOr decrypted = - encryptor->DecryptAndVerify(*encrypted, salt.AsStringView()); - ASSERT_OK(decrypted); - EXPECT_EQ(*decrypted, test_data.AsStringView()); -} - -TEST(Ldt, EncryptAndroidData) { - absl::StatusOr encryptor = - LdtEncryptor::Create(absl::HexStringToBytes(kKeySeedBase16), - absl::HexStringToBytes(kKnownMacBase16)); - ASSERT_OK(encryptor); - - absl::StatusOr encrypted = - encryptor->Encrypt(absl::HexStringToBytes(kPlainTextBase16), - absl::HexStringToBytes(kSaltBase16)); - - ASSERT_OK(encrypted); - EXPECT_EQ(*encrypted, absl::HexStringToBytes(kCipherTextBase16)); -} - -TEST(Ldt, DecryptAndroidData) { - absl::StatusOr encryptor = - LdtEncryptor::Create(absl::HexStringToBytes(kKeySeedBase16), - absl::HexStringToBytes(kKnownMacBase16)); - ASSERT_OK(encryptor); - - absl::StatusOr decrypted = - encryptor->DecryptAndVerify(absl::HexStringToBytes(kCipherTextBase16), - absl::HexStringToBytes(kSaltBase16)); - - ASSERT_OK(decrypted); - EXPECT_EQ(*decrypted, absl::HexStringToBytes(kPlainTextBase16)); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/mediums/BUILD b/presence/implementation/mediums/BUILD deleted file mode 100644 index 80dc9214..00000000 --- a/presence/implementation/mediums/BUILD +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2020 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. - -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -licenses(["notice"]) - -cc_library( - name = "mediums", - srcs = [ - ], - hdrs = [ - "advertisement_data.h", - "ble.h", - "mediums.h", - ], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:uuid", - "//internal/platform/implementation:comm", - "//presence:types", - ], -) - -cc_test( - name = "mediums_test", - size = "small", - srcs = [ - "ble_test.cc", - ], - shard_count = 16, - deps = [ - ":mediums", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform:uuid", - "//internal/platform/implementation:comm", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:variant", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) diff --git a/presence/implementation/mediums/advertisement_data.h b/presence/implementation/mediums/advertisement_data.h deleted file mode 100644 index 654f89b9..00000000 --- a/presence/implementation/mediums/advertisement_data.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2022 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_PRESENCE_IMPLEMENTATION_MEDIUMS_ADVERTISEMENT_DATA_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_ADVERTISEMENT_DATA_H_ - -#include - -namespace nearby { -namespace presence { - -// Nearby Presence advertisement data over the air. -struct AdvertisementData { - // If true, the advertisement needs to be broadcasted over BLE 5.0. - bool is_extended_advertisement; - // The advertised data. - std::string content; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_ADVERTISEMENT_DATA_H_ diff --git a/presence/implementation/mediums/ble.h b/presence/implementation/mediums/ble.h deleted file mode 100644 index 715c0b9b..00000000 --- a/presence/implementation/mediums/ble.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2020 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_PRESENCE_IMPLEMENTATION_MEDIUMS_BLE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_BLE_H_ - -#include -#include - -#include "internal/platform/ble.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/uuid.h" -#include "presence/implementation/mediums/advertisement_data.h" -#include "presence/power_mode.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -/** Presence advertisement service data uuid. */ -ABSL_CONST_INIT const nearby::Uuid kPresenceServiceUuid(0x0000fcf100001000, - 0x800000805f9b34fb); - -/* - * This Ble class utilizes platform/ble BleMedium, provides ble functions - * for presence logic layer to invoke. - * This class would have states like if ble is available or not, if it's doing - * broadcast/scan. - */ -class Ble { - public: - using TxPowerLevel = ::nearby::api::ble::TxPowerLevel; - using ScanningSession = ::nearby::api::ble::BleMedium::ScanningSession; - using ScanningCallback = ::nearby::api::ble::BleMedium::ScanningCallback; - using AdvertiseParameters = ::nearby::api::ble::AdvertiseParameters; - using AdvertisingSession = ::nearby::api::ble::BleMedium::AdvertisingSession; - using AdvertisingCallback = - ::nearby::api::ble::BleMedium::AdvertisingCallback; - using BleAdvertisementData = ::nearby::api::ble::BleAdvertisementData; - using BleMedium = ::nearby::api::ble::BleMedium; - - explicit Ble(nearby::BluetoothAdapter& bluetooth_adapter) - : medium_(bluetooth_adapter) {} - - bool IsAvailable() const { return medium_.IsValid(); } - - // Starts broadcasting NP advertisement in `payload`. The caller should use - // the returned `AdvertisingSession` to stop the broadcast. - std::unique_ptr StartAdvertising( - const AdvertisementData& payload, PowerMode power_mode, - AdvertisingCallback callback) { - BleAdvertisementData advertising_data = { - .is_extended_advertisement = payload.is_extended_advertisement}; - advertising_data.service_data.insert( - {kPresenceServiceUuid, nearby::ByteArray(payload.content)}); - AdvertiseParameters advertise_set_parameters = { - .tx_power_level = ConvertPowerModeToPowerLevel(power_mode), - .is_connectable = true, - }; - return medium_.StartAdvertising(advertising_data, advertise_set_parameters, - std::move(callback)); - } - - // Starts scanning for NP advertisements. The caller should use the returned - // `ScanningSession` to stop scanning. - std::unique_ptr StartScanning(ScanRequest scan_request, - ScanningCallback callback) { - return medium_.StartScanning( - kPresenceServiceUuid, - ConvertPowerModeToPowerLevel(scan_request.power_mode), - std::move(callback)); - } - - // Provides access to platform implementation. It's used in tests. - BleMedium* GetImpl() const { return medium_.GetImpl(); } - - private: - TxPowerLevel ConvertPowerModeToPowerLevel(PowerMode power_mode) { - switch (power_mode) { - case PowerMode::kNoPower: - return TxPowerLevel::kUnknown; - case PowerMode::kLowPower: - return TxPowerLevel::kLow; - case PowerMode::kBalanced: - return TxPowerLevel::kMedium; - case PowerMode::kLowLatency: - return TxPowerLevel::kHigh; - } - return TxPowerLevel::kUnknown; - } - - nearby::BleMedium medium_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_BLE_H_ diff --git a/presence/implementation/mediums/ble_test.cc b/presence/implementation/mediums/ble_test.cc deleted file mode 100644 index 70633ad7..00000000 --- a/presence/implementation/mediums/ble_test.cc +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/mediums/ble.h" - -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/time/time.h" -#include "absl/types/variant.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/uuid.h" -#include "presence/data_element.h" -#include "presence/implementation/mediums/advertisement_data.h" -#include "presence/power_mode.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { -namespace { - -using FeatureFlags = ::nearby::FeatureFlags::Flags; -using BleMediumStatus = ::nearby::MediumEnvironment::BleMediumStatus; -using ScanningSession = ::nearby::api::ble::BleMedium::ScanningSession; -using TxPowerLevel = ::nearby::api::ble::TxPowerLevel; -using ScanningCallback = ::nearby::api::ble::BleMedium::ScanningCallback; -using Uuid = ::nearby::Uuid; -using ::nearby::api::ble::BleAdvertisementData; -using ::nearby::api::ble::BlePeripheral; -using AdvertisingCallback = ::nearby::api::ble::BleMedium::AdvertisingCallback; -using AdvertisingSession = ::nearby::api::ble::BleMedium::AdvertisingSession; - -constexpr FeatureFlags kTestCases[] = { - FeatureFlags{}, -}; - -class BleTest : public testing::TestWithParam { - public: - constexpr static absl::Duration kWaitDuration = absl::Milliseconds(1000); - - std::string account_name_ = "Test-Name"; - constexpr static PowerMode kPowerMode = PowerMode::kBalanced; - std::vector identity_types_ = { - nearby::internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP, - }; - std::vector extended_properties_ = { - DataElement{DataElement::kTxPowerFieldType, "-10"}}; - std::vector > - filters_ = {PresenceScanFilter{ - .scan_type = ScanType::kPresenceScan, - .extended_properties = extended_properties_, - }}; - constexpr static bool kUseBle = true; - constexpr static ScanType kScanType = ScanType::kPresenceScan; - constexpr static bool kScanOnlyWhenScreenOn = true; - - ScanRequest scan_request_ = { - .account_name = account_name_, - .identity_types = identity_types_, - .scan_filters = filters_, - .use_ble = kUseBle, - .scan_type = kScanType, - .power_mode = kPowerMode, - .scan_only_when_screen_on = kScanOnlyWhenScreenOn, - }; - - protected: - std::optional GetBleStatus(const Ble& ble) { - return env_.GetBleMediumStatus(*ble.GetImpl()); - } - nearby::MediumEnvironment& env_{nearby::MediumEnvironment::Instance()}; -}; - -INSTANTIATE_TEST_SUITE_P(ParametrisedBleTest, BleTest, - ::testing::ValuesIn(kTestCases)); - -// Using MediumEnvironment to verify the start&stop StartScanning callback flows -// are working as intended. -TEST_P(BleTest, CanStartThenStopScanning) { - env_.Start(); - ::nearby::BluetoothAdapter adapter; - Ble ble(adapter); - - ScanRequest scan_request{ - .power_mode = PowerMode::kBalanced, - }; - ScanningCallback scanning_callback; - nearby::CountDownLatch started_scanning_latch(1); - - std::unique_ptr scannning_session = ble.StartScanning( - scan_request, ScanningCallback{ - .start_scanning_result = - [&started_scanning_latch](absl::Status status) { - if (status.ok()) { - started_scanning_latch.CountDown(); - } - }, - }); - - EXPECT_TRUE(started_scanning_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(GetBleStatus(ble).has_value() && - GetBleStatus(ble).value().is_scanning == true); - absl::Status stop_scanning_status = scannning_session->stop_scanning(); - EXPECT_OK(stop_scanning_status); - EXPECT_TRUE(GetBleStatus(ble).has_value() && - GetBleStatus(ble).value().is_scanning == false); - env_.Stop(); -} - -TEST_P(BleTest, AdvertiseAndScan) { - // Create two Ble devices, one advertises, the other one scans, and verify - // that the NP advertisement was sent from one to the other. - env_.Start(); - nearby::BluetoothAdapter client_adapter; - Ble client(client_adapter); - nearby::BluetoothAdapter server_adapter; - Ble server(server_adapter); - AdvertisementData advert_data = {.is_extended_advertisement = false, - .content = "my advertisement"}; - ScanRequest scan_request{ - .power_mode = PowerMode::kBalanced, - }; - nearby::CountDownLatch advertise_latch(1); - nearby::CountDownLatch scan_latch(1); - std::vector advertisements; - std::unique_ptr scanning_session = client.StartScanning( - scan_request, - ScanningCallback{.advertisement_found_cb = - [&](BlePeripheral::UniqueId peripheral_id, - BleAdvertisementData advertisement_data) { - advertisements.push_back(advertisement_data); - scan_latch.CountDown(); - }}); - std::unique_ptr - advertising_session = server.StartAdvertising( - advert_data, PowerMode::kBalanced, - AdvertisingCallback{ - .start_advertising_result = [&](absl::Status status) { - advertise_latch.CountDown(); - }}); - - EXPECT_TRUE(advertise_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(scan_latch.Await(kWaitDuration).result()); - EXPECT_OK(scanning_session->stop_scanning()); - EXPECT_OK(advertising_session->stop_advertising()); - ASSERT_FALSE(advertisements.empty()); - EXPECT_EQ(advertisements[0] - .service_data.find(kPresenceServiceUuid) - ->second.AsStringView(), - advert_data.content); - env_.Stop(); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/mediums/mediums.h b/presence/implementation/mediums/mediums.h deleted file mode 100644 index a47679da..00000000 --- a/presence/implementation/mediums/mediums.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2020 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_PRESENCE_IMPLEMENTATION_MEDIUMS_MEDIUMS_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_MEDIUMS_H_ - -#include "internal/platform/bluetooth_adapter.h" -#include "presence/implementation/mediums/ble.h" - -namespace nearby { -namespace presence { - -/* - * This class owns medium instance like Ble and etc. And the instance of - * this class will be owned in {@code ServiceControllerImpl}. - */ -class Mediums { - public: - // Returns a handle to the Ble medium. - Ble& GetBle() { return ble_; } - - private: - nearby::BluetoothAdapter adapter_; - Ble ble_{adapter_}; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_MEDIUMS_H_ diff --git a/presence/implementation/mock_connection_authenticator.h b/presence/implementation/mock_connection_authenticator.h deleted file mode 100644 index 24e860eb..00000000 --- a/presence/implementation/mock_connection_authenticator.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2023 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_PRESENCE_IMPLEMENTATION_MOCK_CONNECTION_AUTHENTICATOR_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_CONNECTION_AUTHENTICATOR_H_ - -#include -#include - -#include "gmock/gmock.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" -#include "presence/implementation/connection_authenticator.h" - -namespace nearby { -namespace presence { - -/* - * This class is for unit tests, mocking {@code ConnectionAuthenticator} - * functions in `PresenceDeviceProviderTest`. - */ -class MockConnectionAuthenticator : public ConnectionAuthenticator { - public: - MOCK_METHOD(absl::StatusOr, BuildSignedMessageAsInitiator, - (absl::string_view ukey2_secret, - std::optional local_credential, - const internal::SharedCredential& shared_credential), - (const, override)); - MOCK_METHOD(absl::StatusOr, BuildSignedMessageAsResponder, - (absl::string_view ukey2_secret, - const internal::LocalCredential& local_credential), - (const, override)); - MOCK_METHOD( - absl::Status, VerifyMessageAsInitiator, - (ResponderData authentication_data, absl::string_view ukey2_secret, - const std::vector& shared_credentials), - (const, override)); - MOCK_METHOD( - absl::StatusOr, VerifyMessageAsResponder, - (absl::string_view ukey2_secret, InitiatorData initiator_data, - const std::vector& local_credentials, - const std::vector& shared_credentials), - (const, override)); -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_CONNECTION_AUTHENTICATOR_H_ diff --git a/presence/implementation/mock_credential_manager.h b/presence/implementation/mock_credential_manager.h deleted file mode 100644 index 64d6e848..00000000 --- a/presence/implementation/mock_credential_manager.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2023 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_PRESENCE_IMPLEMENTATION_MOCK_CREDENTIAL_MANAGER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_CREDENTIAL_MANAGER_H_ - -#include -#include - -#include "gmock/gmock.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "presence/implementation/credential_manager.h" - -namespace nearby { -namespace presence { - -class MockCredentialManager : public CredentialManager { - public: - MOCK_METHOD( - void, GenerateCredentials, - (const nearby::internal::DeviceIdentityMetaData& device_identity_metadata, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb), - (override)); - MOCK_METHOD(void, UpdateRemotePublicCredentials, - (absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb), - (override)); - MOCK_METHOD(void, UpdateLocalCredential, - (const CredentialSelector& credential_selector, - nearby::internal::LocalCredential credential, - SaveCredentialsResultCallback result_callback), - (override)); - MOCK_METHOD(void, GetLocalCredentials, - (const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback), - (override)); - MOCK_METHOD(void, GetPublicCredentials, - (const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback), - (override)); - MOCK_METHOD(SubscriberId, SubscribeForPublicCredentials, - (const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback), - (override)); - MOCK_METHOD(void, UnsubscribeFromPublicCredentials, (SubscriberId id), - (override)); - MOCK_METHOD(std::string, DecryptDeviceIdentityMetaData, - (absl::string_view metadata_encryption_key, - absl::string_view key_seed, absl::string_view metadata_string), - (override)); - MOCK_METHOD( - void, SetDeviceIdentityMetaData, - (const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb), - (override)); - MOCK_METHOD(::nearby::internal::DeviceIdentityMetaData, - GetDeviceIdentityMetaData, (), (override)); -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_CREDENTIAL_MANAGER_H_ diff --git a/presence/implementation/mock_service_controller.h b/presence/implementation/mock_service_controller.h deleted file mode 100644 index 90c3b31d..00000000 --- a/presence/implementation/mock_service_controller.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2020 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_PRESENCE_IMPLEMENTATION_MOCK_SERVICE_CONTROLLER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_SERVICE_CONTROLLER_H_ - -#include -#include - -#include "gmock/gmock.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "presence/implementation/service_controller.h" - -namespace nearby { -namespace presence { - -/* - * This class is for unit test, mocking {@code ServiceController} functions. - */ -class MockServiceController : public ServiceController { - public: - MockServiceController() = default; - ~MockServiceController() override = default; - - MOCK_METHOD(absl::StatusOr, StartScan, - (ScanRequest scan_request, ScanCallback callback), (override)); - MOCK_METHOD(void, StopScan, (ScanSessionId session_id), (override)); - MOCK_METHOD(absl::StatusOr, StartBroadcast, - (BroadcastRequest broadcast_request, BroadcastCallback callback), - (override)); - MOCK_METHOD(void, StopBroadcast, (BroadcastSessionId session_id), (override)); - MOCK_METHOD( - void, UpdateLocalDeviceMetadata, - (const ::nearby::internal::Metadata& metadata, bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb), - (override)); - MOCK_METHOD( - void, UpdateDeviceIdentityMetaData, - (const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb), - (override)); - MOCK_METHOD(::nearby::internal::DeviceIdentityMetaData, - GetDeviceIdentityMetaData, (), (override)); - MOCK_METHOD(void, GetLocalPublicCredentials, - (const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback), - (override)); - MOCK_METHOD(void, UpdateRemotePublicCredentials, - (absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb), - (override)); - MOCK_METHOD(void, GetLocalCredentials, - (const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback), - (override)); -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_SERVICE_CONTROLLER_H_ diff --git a/presence/implementation/np_ldt.h b/presence/implementation/np_ldt.h deleted file mode 100644 index 9047c12a..00000000 --- a/presence/implementation/np_ldt.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_NP_LDT_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_NP_LDT_H_ - -// Copyright 2022 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. -// C API for Rust implementation of LDT [1], tailored to Nearby Presence's -// BLE 4.2 legacy format advertisement parsing usecase. -// -// [1] https://eprint.iacr.org/2017/841.pdf - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -// Individual encrypt/decrypt API, useful when creating advertisements or when -// decrypting advertisements from a known origin - -// The allocated handle to use for encryption -typedef struct { - uint64_t handle; -} NpLdtEncryptHandle; - -// The allocated handle to use for decryption -typedef struct { - uint64_t handle; -} NpLdtDecryptHandle; - -// Key material from the Nearby Presence credential from which keys will be -// derived. -typedef struct { - uint8_t bytes[32]; -} NpLdtKeySeed; - -typedef struct { - uint8_t bytes[32]; -} NpMetadataKeyHmac; - -typedef struct { - uint8_t bytes[2]; -} NpLdtSalt; - -// Possible result codes returned from the LDT NP API's -typedef enum { - // Call to api was succesful - NP_LDT_SUCCESS = 0, - // Payload of invalid length was provided must be >= 16 and <=31 bytes - NP_LDT_ERROR_INVALID_LENGTH = -1, - // The provided metadata hmac did not match the calculated hmac on call to - // decrypt and verify - NP_LDT_ERROR_MAC_MISMATCH = -2, -} NP_LDT_RESULT; - -// Allocate an LDT-XTS-AES128 Decryption cipher using the "swap" mix function. -// -// `key_seed` is the key material from the Nearby Presence credential from which -// the LDT key will be derived. -// 'hmac_tag' is the hmac auth tag calculated on the metadata key used to verify -// decryption was successful -// -// Returns 0 on error, or a non-zero handle on success. -NpLdtDecryptHandle NpLdtDecryptCreate(NpLdtKeySeed key_seed, - NpMetadataKeyHmac hmac_tag); - -// Allocate an LDT-XTS-AES128 Encryption cipher using the "swap" mix function. -// -// `key_seed` is the key material from the Nearby Presence credential from which -// the LDT key will be derived. -// -// Returns 0 on error, or a non-zero handle on success. -NpLdtEncryptHandle NpLdtEncryptCreate(NpLdtKeySeed key_seed); - -// Release allocated resources for an NpLdtEncryptHandle -// -// Returns 0 on success or an NP_LDT_RESULT error code on failure -NP_LDT_RESULT NpLdtEncryptClose(NpLdtEncryptHandle handle); - -// Release allocated resources for an NpLdtDecryptHandle -// -// Returns 0 on success or an NP_LDT_RESULT error code on failure -NP_LDT_RESULT NpLdtDecryptClose(NpLdtDecryptHandle handle); - -// Encrypt a 16-31 byte buffer in-place. -// -// `buffer` is a pointer to a 16-31 byte plaintext, with length in `buffer_len`. -// `salt` is the big-endian 2 byte salt that will be used in the Nearby -// Presence advertisement, which will be incorporated into the tweaks LDT uses -// while encrypting. -// -// Returns 0 on success, in which case `buffer` will now contain ciphertext. -// Returns an NP_LDT_RESULT error code on failure -NP_LDT_RESULT NpLdtEncrypt(NpLdtEncryptHandle handle, uint8_t* buffer, - size_t buffer_len, NpLdtSalt salt); - -// Decrypt a 16-31 byte buffer in-place. -// -// `buffer` is a pointer to a 16-31 byte ciphertext, with length in -// `buffer_len`. -// `salt` is the big-endian 2 byte salt found in the Nearby Presence -// advertisement, which will be incorporated into the tweaks LDT uses while -// decrypting. -// -// Returns 0 on success, in which case `buffer` will now contain plaintext. -// Returns an NP_LDT_RESULT error code on failure -NP_LDT_RESULT NpLdtDecryptAndVerify(NpLdtDecryptHandle handle, uint8_t* buffer, - size_t buffer_len, NpLdtSalt salt); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_NP_LDT_H_ diff --git a/presence/implementation/scan_manager.cc b/presence/implementation/scan_manager.cc deleted file mode 100644 index 3f6d7e03..00000000 --- a/presence/implementation/scan_manager.cc +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/scan_manager.h" - -#include - -#include -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/status/status.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "internal/platform/future.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/implementation/crypto.h" -#include "internal/platform/logging.h" -#include "presence//implementation/advertisement_filter.h" -#include "presence/data_element.h" -#include "presence/data_types.h" -#include "presence/device_motion.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/implementation/mediums/ble.h" -#include "presence/presence_action.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -namespace { -using BleAdvertisementData = ::nearby::api::ble::BleAdvertisementData; -using BlePeripheral = ::nearby::api::ble::BlePeripheral; -using ScanningSession = ::nearby::api::ble::BleMedium::ScanningSession; -using ScanningCallback = ::nearby::api::ble::BleMedium::ScanningCallback; -} // namespace - -ScanSessionId ScanManager::StartScan(ScanRequest scan_request, - ScanCallback cb) { - ScanSessionId id = nearby::RandData(); - RunOnServiceControllerThread( - "start-scan", - [this, id, scan_request, - scan_callback = - std::move(cb)]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) mutable { - ScanningCallback callback = ScanningCallback{ - .start_scanning_result = - [start_scan_client = std::move(scan_callback.start_scan_cb)]( - absl::Status ble_status) mutable { - start_scan_client(ble_status); - }, - .advertisement_found_cb = - [this, id](BlePeripheral::UniqueId peripheral_id, - BleAdvertisementData data) { - RunOnServiceControllerThread( - "notify-found-ble", - [this, id, data = std::move(data), peripheral_id]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - NotifyFoundBle(id, data, peripheral_id); - }); - }, - .advertisement_lost_cb = - [this, id](BlePeripheral::UniqueId peripheral_id) { - RunOnServiceControllerThread( - "notify-lost-ble", - [this, id, peripheral_id]() ABSL_EXCLUSIVE_LOCKS_REQUIRED( - *executor_) { NotifyLostBle(id, peripheral_id); }); - }}; - FetchCredentials(id, scan_request); - scan_sessions_.insert( - {id, ScanSessionState{ - .request = scan_request, - .callback = std::move(scan_callback), - .decoder = AdvertisementDecoderImpl(), - .advertisement_filter = AdvertisementFilter(scan_request), - .scanning_session = mediums_->GetBle().StartScanning( - scan_request, std::move(callback))}}); - }); - return id; -} - -void ScanManager::StopScan(ScanSessionId id) { - RunOnServiceControllerThread( - "stop-scan", [this, id]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - auto it = scan_sessions_.find(id); - if (it == scan_sessions_.end()) { - return; - } - if (it->second.scanning_session) { - absl::Status status = it->second.scanning_session->stop_scanning(); - if (!status.ok()) { - LOG(WARNING) << "StopScan error: " << status; - } - } - scan_sessions_.erase(it); - }); -} - -void ScanManager::NotifyFoundBle(ScanSessionId id, BleAdvertisementData data, - BlePeripheral::UniqueId peripheral_id) { - auto it = scan_sessions_.find(id); - if (it == scan_sessions_.end()) { - return; - } - - auto advertisement_data = - data.service_data[kPresenceServiceUuid].AsStringView(); - - auto advert = it->second.decoder.DecodeAdvertisement(advertisement_data); - if (!advert.ok()) { - // This advertisement is not relevant to the current element, skip. - return; - } - - std::string remote_address = absl::StrCat(absl::Hex(peripheral_id)); - if (it->second.advertisement_filter.MatchesScanFilter(*advert)) { - internal::DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_bluetooth_mac_address(remote_address); - - if (!device_unique_id_to_endpoint_id_map_.contains(peripheral_id)) { - PresenceDevice device(DeviceMotion(), device_identity_metadata, - advert->identity_type); - // Ok if the advertisement is for trusted/private identity. - if (advert->public_credential.ok()) { - device.SetDecryptSharedCredential(*(advert->public_credential)); - } - device.AddExtendedProperties(advert->data_elements); - for (const auto& data_element : advert->data_elements) { - if (data_element.GetType() == DataElement::kActionFieldType) { - device.AddAction(PresenceAction(static_cast( - static_cast(data_element.GetValue()[0])))); - } - } - - device_unique_id_to_endpoint_id_map_.emplace(peripheral_id, - device.GetEndpointId()); - - it->second.callback.on_discovered_cb(std::move(device)); - } else { - PresenceDevice device( - device_unique_id_to_endpoint_id_map_.at(peripheral_id)); - device.SetDeviceIdentityMetaData(device_identity_metadata); - // Ok if the advertisement is for trusted/private identity. - if (advert->public_credential.ok()) { - device.SetDecryptSharedCredential(*(advert->public_credential)); - } - device.AddExtendedProperties(advert->data_elements); - for (const auto& data_element : advert->data_elements) { - if (data_element.GetType() == DataElement::kActionFieldType) { - device.AddAction(PresenceAction(static_cast( - static_cast(data_element.GetValue()[0])))); - } - } - - it->second.callback.on_updated_cb(std::move(device)); - } - } -} - -void ScanManager::NotifyLostBle(ScanSessionId id, - BlePeripheral::UniqueId peripheral_id) { - auto it = scan_sessions_.find(id); - if (it == scan_sessions_.end()) { - return; - } - - std::string remote_address = absl::StrCat(absl::Hex(peripheral_id)); - if (device_unique_id_to_endpoint_id_map_.contains(peripheral_id)) { - internal::DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_bluetooth_mac_address( - std::string(remote_address)); - PresenceDevice device( - device_unique_id_to_endpoint_id_map_.at(peripheral_id)); - device.SetDeviceIdentityMetaData(device_identity_metadata); - - device_unique_id_to_endpoint_id_map_.erase(peripheral_id); - - it->second.callback.on_lost_cb(std::move(device)); - } -} - -std::vector GetCredentialSelectors( - const ScanRequest& scan_request) { - std::vector all_types = { - nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP, - nearby::internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP, - nearby::internal::IdentityType::IDENTITY_TYPE_PUBLIC}; - std::vector selectors; - for (auto identity_type : - (scan_request.identity_types.empty() ? all_types - : scan_request.identity_types)) { - selectors.push_back( - CredentialSelector{.manager_app_id = scan_request.manager_app_id, - .account_name = scan_request.account_name, - .identity_type = identity_type}); - } - return selectors; -} - -void ScanManager::FetchCredentials(ScanSessionId id, - const ScanRequest& scan_request) { - std::vector credential_selectors = - GetCredentialSelectors(scan_request); - for (const CredentialSelector& selector : credential_selectors) { - // Not fetching for PUBLIC. - if (selector.identity_type == internal::IDENTITY_TYPE_UNSPECIFIED || - selector.identity_type == internal::IDENTITY_TYPE_PUBLIC) { - LOG(INFO) << __func__ << ": skip feteching creds for identity type: " - << selector.identity_type; - continue; - } - credential_manager_->GetPublicCredentials( - selector, PublicCredentialType::kRemotePublicCredential, - {.credentials_fetched_cb = - [this, id, identity_type = selector.identity_type]( - absl::StatusOr< - std::vector<::nearby::internal::SharedCredential>> - credentials) { - if (!credentials.ok()) { - LOG(WARNING) - << "Failed to fetch credentials: " << credentials.status(); - return; - } - RunOnServiceControllerThread( - "update-credentials", - [this, id, identity_type, - credentials = std::move(*credentials)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - UpdateCredentials(id, identity_type, - std::move(credentials)); - }); - }}); - } -} - -void ScanManager::UpdateCredentials(ScanSessionId id, - IdentityType identity_type, - std::vector credentials) { - // Credentials should never get fetched for PUBLIC of No-Identity requests - assert(identity_type != internal::IDENTITY_TYPE_UNSPECIFIED); - assert(identity_type != internal::IDENTITY_TYPE_PUBLIC); - - auto it = scan_sessions_.find(id); - - if (it == scan_sessions_.end()) { - return; - } - - ScanSessionState& session = it->second; - session.credentials[identity_type] = std::move(credentials); - session.decoder = AdvertisementDecoderImpl(&session.credentials); -} - -int ScanManager::ScanningCallbacksLengthForTest() { - ::nearby::Future count; - RunOnServiceControllerThread("callbacks-size", - [&]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - count.Set(scan_sessions_.size()); - }); - return count.Get().GetResult(); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/scan_manager.h b/presence/implementation/scan_manager.h deleted file mode 100644 index a174884f..00000000 --- a/presence/implementation/scan_manager.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2020 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_PRESENCE_IMPLEMENTATION_SCAN_MANAGER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SCAN_MANAGER_H_ - -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/container/flat_hash_map.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/mutex.h" -#include "internal/platform/mutex_lock.h" -#include "internal/platform/runnable.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_types.h" -#include "presence/implementation/advertisement_filter.h" -#include "presence/implementation/credential_manager.h" -#include "presence/implementation/mediums/mediums.h" -#include "presence/scan_request.h" - -#ifdef USE_RUST_DECODER -#include "presence/implementation/advertisement_decoder_rust_impl.h" -#else -#include "presence/implementation/advertisement_decoder_impl.h" -#endif - -namespace nearby { -namespace presence { - -// The instance of ScanManager is owned by `ServiceControllerImpl`. -// Helping service controller to manage scan requests and callbacks. -class ScanManager { - public: - using SingleThreadExecutor = ::nearby::SingleThreadExecutor; - using Mutex = ::nearby::Mutex; - using MutexLock = ::nearby::MutexLock; - using ScanningSession = ::nearby::api::ble::BleMedium::ScanningSession; - using Runnable = ::nearby::Runnable; - using BleAdvertisementData = ::nearby::api::ble::BleAdvertisementData; - using SharedCredential = ::nearby::internal::SharedCredential; - using IdentityType = ::nearby::internal::IdentityType; - - ScanManager(Mediums& mediums, CredentialManager& credential_manager, - SingleThreadExecutor& executor) { - mediums_ = &mediums, credential_manager_ = &credential_manager; - executor_ = &executor; - } - ~ScanManager() = default; - - ScanSessionId StartScan(ScanRequest scan_request, ScanCallback cb); - void StopScan(ScanSessionId session_id); - // Below functions are test only. - // Reference: go/totw/135#augmenting-the-public-api-for-tests - int ScanningCallbacksLengthForTest(); - - private: - struct ScanSessionState { - ScanRequest request; - ScanCallback callback; - absl::flat_hash_map> - credentials; - AdvertisementDecoderImpl decoder; - AdvertisementFilter advertisement_filter; - std::unique_ptr scanning_session; - }; - void NotifyFoundBle(ScanSessionId id, BleAdvertisementData data, - nearby::api::ble::BlePeripheral::UniqueId peripheral_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void NotifyLostBle(ScanSessionId id, - nearby::api::ble::BlePeripheral::UniqueId peripheral_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void FetchCredentials(ScanSessionId id, const ScanRequest& scan_request) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void UpdateCredentials(ScanSessionId id, IdentityType identity_type, - std::vector credentials) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void RunOnServiceControllerThread(absl::string_view name, Runnable runnable) { - executor_->Execute(std::string(name), std::move(runnable)); - } - Mediums* mediums_; - CredentialManager* credential_manager_; - absl::flat_hash_map scan_sessions_ - ABSL_GUARDED_BY(*executor_); - absl::flat_hash_map - device_unique_id_to_endpoint_id_map_ ABSL_GUARDED_BY(*executor_); - SingleThreadExecutor* executor_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SCAN_MANAGER_H_ diff --git a/presence/implementation/scan_manager_test.cc b/presence/implementation/scan_manager_test.cc deleted file mode 100644 index 4ddee9ee..00000000 --- a/presence/implementation/scan_manager_test.cc +++ /dev/null @@ -1,453 +0,0 @@ -// Copyright 2022 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. - -#include "presence/implementation/scan_manager.h" - -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "absl/strings/str_cat.h" -#include "absl/types/variant.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/logging.h" -#include "internal/platform/mac_address.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/credential.proto.h" -#include "presence/data_element.h" -#include "presence/data_types.h" -#include "presence/implementation/credential_manager_impl.h" -#include "presence/implementation/mediums/advertisement_data.h" -#include "presence/implementation/mediums/ble.h" -#include "presence/implementation/mediums/mediums.h" -#include "presence/implementation/mock_credential_manager.h" -#include "presence/power_mode.h" -#include "presence/presence_action.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { -namespace { - -using AdvertisingSession = ::nearby::api::ble::BleMedium::AdvertisingSession; -using AdvertisingCallback = - ::nearby::api::ble::BleMedium::AdvertisingCallback; -using ::nearby::SingleThreadExecutor; - -using CountDownLatch = ::nearby::CountDownLatch; -using ::testing::Contains; - -class ScanManagerTest : public testing::Test { - protected: - void SetUp() override { env_.Start(); } - void TearDown() override { - executor_.Shutdown(); - env_.Stop(); - } - - std::unique_ptr StartAdvertisingOn(Ble& ble) { - auto advertisement = AdvertisementData{ - .is_extended_advertisement = false, - .content = {0x00, 0x26, 0x00, 0x40}, - }; - std::unique_ptr session = ble.StartAdvertising( - advertisement, PowerMode::kLowPower, - AdvertisingCallback{.start_advertising_result = [](absl::Status) {}}); - env_.Sync(); - return session; - } - - ScanRequest MakeDefaultScanRequest() { - std::vector> - filters = {PresenceScanFilter{ - .scan_type = ScanType::kPresenceScan, - .extended_properties = MakeDefaultExtendedProperties(), - }}; - return { - .account_name = "Test account", - .identity_types = MakeDefaultIdentityTypes(), - .scan_filters = filters, - .use_ble = true, - .scan_type = ScanType::kPresenceScan, - .power_mode = PowerMode::kBalanced, - .scan_only_when_screen_on = true, - }; - } - - ScanCallback MakeDefaultScanCallback() { - return { - .start_scan_cb = - [this](absl::Status status) { - if (status.ok()) { - start_latch_.CountDown(); - } - }, - .on_discovered_cb = - [this](PresenceDevice pd) { found_latch_.CountDown(); }, - .on_updated_cb = - [this](PresenceDevice pd) { updated_latch_.CountDown(); }, - .on_lost_cb = [this](PresenceDevice pd) { lost_latch_.CountDown(); }}; - } - - std::vector MakeDefaultIdentityTypes() { - return { - nearby::internal::IdentityType::IDENTITY_TYPE_PUBLIC, - }; - } - std::vector MakeDefaultExtendedProperties() { - return {DataElement(ActionBit::kNearbyShareAction)}; - } - SingleThreadExecutor executor_; - CredentialManagerImpl credential_manager_{&executor_}; - nearby::MediumEnvironment& env_ = {nearby::MediumEnvironment::Instance()}; - CountDownLatch start_latch_{1}; - CountDownLatch found_latch_{1}; - CountDownLatch updated_latch_{1}; - CountDownLatch lost_latch_{1}; -}; - -TEST_F(ScanManagerTest, CanStartThenStopScanning) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - // Set up advertiser - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - - // Start scanning - ScanSessionId scan_session = - manager.StartScan(MakeDefaultScanRequest(), MakeDefaultScanCallback()); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - EXPECT_TRUE(start_latch_.Await().Ok()); - EXPECT_TRUE(found_latch_.Await().Ok()); - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -TEST_F(ScanManagerTest, CannotStopScanTwice) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - - ScanSessionId scan_session = - manager.StartScan(MakeDefaultScanRequest(), MakeDefaultScanCallback()); - - LOG(INFO) << "Start scan"; - EXPECT_TRUE(start_latch_.Await().Ok()); - // Ensure that we have started scanning before we try to stop. - env_.Sync(); - LOG(INFO) << "Stop scan"; - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); - LOG(INFO) << "Stop scan again"; - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -TEST_F(ScanManagerTest, TestNoFilter) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - // Set up advertiser - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - - // Start scanning - ScanRequest scan_request_no_filter = MakeDefaultScanRequest(); - scan_request_no_filter.scan_filters.clear(); - ScanSessionId scan_session = - manager.StartScan(scan_request_no_filter, MakeDefaultScanCallback()); - - ASSERT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - ASSERT_TRUE(mediums.GetBle().IsAvailable()); - EXPECT_TRUE(start_latch_.Await().Ok()); - EXPECT_TRUE(found_latch_.Await().Ok()); - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -TEST_F(ScanManagerTest, PresenceMetadataIsRetained) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - // Set up advertiser - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - std::string address = - absl::StrCat(absl::Hex(server_adapter.GetAddress().address())); - ScanCallback callback = { - .start_scan_cb = - [this](absl::Status status) { - if (status.ok()) { - start_latch_.CountDown(); - } - }, - .on_discovered_cb = - [this, &address](PresenceDevice pd) { - if (pd.GetDeviceIdentityMetadata().bluetooth_mac_address() == - address) { - EXPECT_THAT(pd.GetExtendedProperties(), - Contains(DataElement(ActionBit::kNearbyShareAction)) - .Times(1)); - EXPECT_THAT( - pd.GetActions(), - Contains(PresenceAction{(int)ActionBit::kNearbyShareAction}) - .Times(1)); - - found_latch_.CountDown(); - } - }, - .on_updated_cb = - [this, &address](PresenceDevice pd) { - if (pd.GetDeviceIdentityMetadata().bluetooth_mac_address() == - address) { - EXPECT_THAT(pd.GetExtendedProperties(), - Contains(DataElement(ActionBit::kNearbyShareAction)) - .Times(1)); - EXPECT_THAT( - pd.GetActions(), - Contains(PresenceAction{(int)ActionBit::kNearbyShareAction}) - .Times(1)); - - updated_latch_.CountDown(); - } - }}; - // Start scanning - ScanRequest scan_request_no_filter = MakeDefaultScanRequest(); - scan_request_no_filter.scan_filters.clear(); - auto scan_session = - manager.StartScan(scan_request_no_filter, std::move(callback)); - - ASSERT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - ASSERT_TRUE(mediums.GetBle().IsAvailable()); - EXPECT_TRUE(start_latch_.Await().Ok()); - EXPECT_TRUE(found_latch_.Await().Ok()); - - // Advertise again to trigger `on_updated_cb` - advertising_session = StartAdvertisingOn(ble2); - - EXPECT_TRUE(updated_latch_.Await().Ok()); - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -TEST_F(ScanManagerTest, DiscoverThenLoseAdvertisement) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - // Set up advertiser - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - - // Start scanning - ScanSessionId scan_session = - manager.StartScan(MakeDefaultScanRequest(), MakeDefaultScanCallback()); - - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - EXPECT_TRUE(start_latch_.Await().Ok()); - EXPECT_TRUE(found_latch_.Await().Ok()); - - // Stop advertising to trigger `on_lost_cb` - EXPECT_OK(advertising_session->stop_advertising()); - env_.Sync(); - - EXPECT_TRUE(lost_latch_.Await().Ok()); - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -TEST_F(ScanManagerTest, StopOneSessionFromAnotherDeadlock) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - CountDownLatch start_latch2{1}; - CountDownLatch found_latch2{1}; - - // Start scanning - std::vector extended_properties_mismatch = { - DataElement(ActionBit::kInstantTetheringAction)}; - std::vector> - mismatch_filters = {PresenceScanFilter{ - .scan_type = ScanType::kPresenceScan, - .extended_properties = extended_properties_mismatch, - }}; - ScanRequest scan_request_mismatch = { - .account_name = "Test account", - .identity_types = MakeDefaultIdentityTypes(), - .scan_filters = mismatch_filters, - .use_ble = true, - .scan_type = ScanType::kPresenceScan, - .power_mode = PowerMode::kBalanced, - .scan_only_when_screen_on = true, - }; - // we use scan_request_mismatch so this session's discovery doesn't get - // triggered. - ScanSessionId scan_session = - manager.StartScan(scan_request_mismatch, MakeDefaultScanCallback()); - ScanCallback scanning_callback2 = {.start_scan_cb = - [&](absl::Status status) { - if (status.ok()) { - start_latch2.CountDown(); - } - }, - .on_discovered_cb = - [&](PresenceDevice pd) { - LOG(INFO) << "scansession2 found"; - found_latch2.CountDown(); - manager.StopScan(scan_session); - }}; - ScanSessionId scan_session2 = manager.StartScan( - MakeDefaultScanRequest(), std::move(scanning_callback2)); - - ASSERT_EQ(manager.ScanningCallbacksLengthForTest(), 2); - - // Set up advertiser - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - - EXPECT_TRUE(found_latch2.Await().Ok()); - // Session was stopped before, this should not be able to stop successfully. - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - ASSERT_TRUE(mediums.GetBle().IsAvailable()); - manager.StopScan(scan_session2); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -// Receive a BLE advertisement after StopScan. `on_discovered_cb` -// must not be called. -TEST_F(ScanManagerTest, NoDeviceFoundAfterStopScan) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - CountDownLatch start_scan_latch{1}; - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::atomic_bool stopped = false; - ScanSessionId scan_session = manager.StartScan( - MakeDefaultScanRequest(), - ScanCallback{.start_scan_cb = - [&start_scan_latch](absl::Status status) { - if (status.ok()) { - start_scan_latch.CountDown(); - } - }, - .on_discovered_cb = - [&](PresenceDevice pd) { EXPECT_FALSE(stopped); }}); - - start_scan_latch.Await(); - manager.StopScan(scan_session); - stopped = true; - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); - executor_.Shutdown(); -} - -internal::SharedCredential GetPublicCredential() { - // Values copied from LDT tests - ByteArray seed({ - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - }); - ByteArray known_mac({0x09, 0xFE, 0x9E, 0x81, 0xB7, 0x3E, 0x5E, 0xCC, - 0x76, 0x59, 0x57, 0x71, 0xE0, 0x1F, 0xFB, 0x34, - 0x38, 0xE7, 0x5F, 0x24, 0xA7, 0x69, 0x56, 0xA0, - 0xB8, 0xEA, 0x67, 0xD1, 0x1C, 0x3E, 0x36, 0xFD}); - internal::SharedCredential public_credential; - public_credential.set_key_seed(seed.AsStringView()); - public_credential.set_metadata_encryption_key_tag_v0( - known_mac.AsStringView()); - return public_credential; -} - -std::vector BuildSharedCredentials() { - return {GetPublicCredential()}; -} - -TEST_F(ScanManagerTest, ScanningE2EWithEncryptedAdvertisementAndCredentials) { - Mediums mediums; - auto mock_credential_manager = MockCredentialManager(); - EXPECT_CALL(mock_credential_manager, GetPublicCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) { - callback.credentials_fetched_cb(BuildSharedCredentials()); - }); - ScanManager manager(mediums, mock_credential_manager, executor_); - - // Set up advertiser to broadcast a private identity adv - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::string V0AdvEncryptedBytes = "042222D82212EF16DBF872F2A3A7C0FA5248EC"; - std::string payload = absl::HexStringToBytes(V0AdvEncryptedBytes); - auto advertisement = AdvertisementData{ - .is_extended_advertisement = false, - .content = payload, - }; - - std::unique_ptr session = ble2.StartAdvertising( - advertisement, PowerMode::kLowPower, - AdvertisingCallback{.start_advertising_result = [](absl::Status) {}}); - env_.Sync(); - - std::vector< - absl::variant> // NOLINT - filters = {PresenceScanFilter{ - .scan_type = ScanType::kPresenceScan, - .extended_properties = {DataElement(DataElement::kTxPowerFieldType, - 3)}, - }}; - - ScanRequest scan_request = { - .account_name = "Test account", - .identity_types = - {nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP}, - .scan_filters = filters, - .use_ble = true, - .scan_type = ScanType::kPresenceScan, - .power_mode = PowerMode::kBalanced, - .scan_only_when_screen_on = true, - }; - - // Start scanning - ScanSessionId scan_session = - manager.StartScan(scan_request, MakeDefaultScanCallback()); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - EXPECT_TRUE(start_latch_.Await().Ok()); - EXPECT_TRUE(found_latch_.Await().Ok()); - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/sensor_fusion.h b/presence/implementation/sensor_fusion.h deleted file mode 100644 index 31639bd7..00000000 --- a/presence/implementation/sensor_fusion.h +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2022 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_PRESENCE_IMPLEMENTATION_SENSOR_FUSION_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SENSOR_FUSION_H_ - -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "presence/device_motion.h" -#include "presence/presence_zone.h" - -namespace nearby { -namespace presence { - -enum class DataSource { - kUnknown = 0, - kBle = 1, - kUwb = 2, - kNanRtt = 4, -}; - -struct RangingMeasurement { - // [0.0, 1.0], 1.0 is the max confidence. - float confidence_level; - float value; -}; - -struct RangingPosition { - RangingMeasurement distance; - std::optional azimuth; - std::optional elevation; - uint64_t elapsed_realtime_millis; -}; - -struct ZoneTransition { - PresenceZone::DistanceBoundary::RangeType distance_range_type; - float confidence_level; -}; - -struct RangingData { - DataSource data_source; - RangingPosition position; - std::optional zone_transition; - std::vector device_motions; -}; - -struct ZoneTransitionCallback { - absl::AnyInvocable - on_proximity_zone_changed = - [](uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType proximity_zone) {}; - absl::AnyInvocable on_callback_id_generated = - [](uint64_t callback_id) {}; -}; - -class SensorFusion { - public: - virtual ~SensorFusion() = default; - - // Called when a device motion gesture is detected. - typedef std::function - DeviceMotionCallback; - - /** - * Returns a list of data sources would be used by the sensor fusion if they - * are available. - * This is to control what kinds of sources the NP scan engine should use for - * ranging. For instance, if both NAN RTT and UWB are supported, FPP may - * decide NAN RTT isn't useful at a certain moment, so NP scan engine won't - * try to request NAN RTT. - * - * @param elapsed_realtime_millis Elapsed timestamp since boot of the data - * source query. - * @param available_sources A bit mask of data sources that are available. - */ - virtual std::vector GetDataSources( - uint64_t elapsed_realtime_millis, - const std::vector& available_sources) = 0; - - /** - * Updates BLE scanned results to Sensor Fusion. - * - * @param device_id A unique device id of the peer device. - * @param txPower Calibrated TX power of the scan result, {@code - * std::nullopt} if the calibrated TX power is not available. - * @param rssi Received signal strength indicator for the scan result. - * @param elapsed_realtime_millis Elapsed timestamp since boot when the - * scan result is discovered. - */ - virtual absl::Status UpdateBleScanResult( - uint64_t device_id, std::optional txPower, int rssi, - uint64_t elapsed_realtime_millis) = 0; - /** - * Updates UWB ranging results to Sensor Fusion. - * - * @param device_id A unique device id of the peer device. - * @param position UWB ranging result (distance and optionally angle) - */ - virtual void UpdateUwbRangingResult(uint64_t device_id, - RangingPosition position) = 0; - - /** - * Adds callback for updates of proximity zone transitions. - */ - virtual void RequestZoneTransitionUpdates( - ZoneTransitionCallback callback) = 0; - - /** - * Removes callback for updates of proximity zone transitions. - */ - virtual void RemoveZoneTransitionUpdates(uint64_t callback_id) = 0; - - /** - * Adds callback for updates of device motion events. - */ - virtual void RequestDeviceMotionUpdates(DeviceMotionCallback callback) = 0; - - /** - * Remove callback for updates of device motion events. - */ - virtual void RemoveDeviceMotionUpdates(DeviceMotionCallback callback) = 0; - - /** - * Returns the best ranging estimate to a given device. Returns {@code - * std::nullopt} if the sensor fusion cannot produce a ranging estimate. - * - * @param device_id Id of the peer device. - */ - virtual std::optional GetRangingData(uint64_t device_id) = 0; -}; - -} // namespace presence -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SENSOR_FUSION_H_ - diff --git a/presence/implementation/service_controller.h b/presence/implementation/service_controller.h deleted file mode 100644 index 9389741e..00000000 --- a/presence/implementation/service_controller.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2020 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_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_H_ - -#include - -#include "absl/status/statusor.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/proto/metadata.pb.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -/* - * This class is owned in {@code PresenceService}. It specifies the function - * signatures. {@code ServiceControllerImpl} and {@code MockServiceController} - * inherit this class and provides real implementation and mock impl for tests. - */ -class ServiceController { - public: - ServiceController() = default; - virtual ~ServiceController() = default; - virtual absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) = 0; - virtual void StopScan(ScanSessionId session_id) = 0; - virtual absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) = 0; - virtual void StopBroadcast(BroadcastSessionId session_id) = 0; - virtual void UpdateLocalDeviceMetadata( - const ::nearby::internal::Metadata& metadata, bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) = 0; - virtual void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) = 0; - virtual ::nearby::internal::DeviceIdentityMetaData - GetDeviceIdentityMetaData() = 0; - virtual void GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) = 0; - virtual void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) = 0; - virtual void GetLocalCredentials( - const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_H_ diff --git a/presence/implementation/service_controller_impl.cc b/presence/implementation/service_controller_impl.cc deleted file mode 100644 index 3c158fc6..00000000 --- a/presence/implementation/service_controller_impl.cc +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2020 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. - -#include "presence/implementation/service_controller_impl.h" - -#include -#include - -#include "absl/status/statusor.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "presence/data_types.h" -#include "presence/implementation/credential_manager.h" - -namespace nearby { -namespace presence { - -absl::StatusOr ServiceControllerImpl::StartScan( - ScanRequest scan_request, ScanCallback callback) { - return scan_manager_.StartScan(scan_request, std::move(callback)); -} -void ServiceControllerImpl::StopScan(ScanSessionId id) { - scan_manager_.StopScan(id); -} - -absl::StatusOr ServiceControllerImpl::StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) { - return broadcast_manager_.StartBroadcast(broadcast_request, - std::move(callback)); -} - -void ServiceControllerImpl::StopBroadcast(BroadcastSessionId id) { - broadcast_manager_.StopBroadcast(id); -} - -// TODO(b/327629276): Remove this function. -void ServiceControllerImpl::UpdateLocalDeviceMetadata( - const ::nearby::internal::Metadata& metadata, bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) {} - -void ServiceControllerImpl::UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) { - credential_manager_.SetDeviceIdentityMetaData( - device_identity_metadata, regen_credentials, manager_app_id, - identity_types, credential_life_cycle_days, - contiguous_copy_of_credentials, std::move(credentials_generated_cb)); -} - -void ServiceControllerImpl::GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) { - credential_manager_.GetPublicCredentials( - credential_selector, PublicCredentialType::kLocalPublicCredential, - std::move(callback)); -} - -void ServiceControllerImpl::UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) { - credential_manager_.UpdateRemotePublicCredentials( - manager_app_id, account_name, remote_public_creds, - std::move(credentials_updated_cb)); -} - -void ServiceControllerImpl::GetLocalCredentials( - const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - credential_manager_.GetLocalCredentials(credential_selector, - std::move(callback)); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/service_controller_impl.h b/presence/implementation/service_controller_impl.h deleted file mode 100644 index b858b7b3..00000000 --- a/presence/implementation/service_controller_impl.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2020 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_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_IMPL_H_ - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/runnable.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/metadata.pb.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/implementation/broadcast_manager.h" -#include "presence/implementation/credential_manager.h" -#include "presence/implementation/scan_manager.h" -#include "presence/implementation/service_controller.h" -#include "presence/scan_request.h" - -/* - * This class implements {@code ServiceController} functions. Owns mediums and - * other managers instances. - */ -namespace nearby { -namespace presence { - -class ServiceControllerImpl : public ServiceController { - public: - using SingleThreadExecutor = ::nearby::SingleThreadExecutor; - - ServiceControllerImpl(SingleThreadExecutor* executor, - CredentialManager* credential_manager, - ScanManager* scan_manager, - BroadcastManager* broadcast_manager) - : executor_(*executor), - credential_manager_(*credential_manager), - scan_manager_(*scan_manager), - broadcast_manager_(*broadcast_manager) {} - ~ServiceControllerImpl() override { executor_.Shutdown(); } - - absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) override; - void StopScan(ScanSessionId session_id) override; - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) override; - void StopBroadcast(BroadcastSessionId) override; - void UpdateLocalDeviceMetadata( - const ::nearby::internal::Metadata& metadata, bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override; - void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override; - - ::nearby::internal::DeviceIdentityMetaData GetDeviceIdentityMetaData() - override { - return credential_manager_.GetDeviceIdentityMetaData(); - } - void GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) override; - void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) override; - void GetLocalCredentials(const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) override; - - SingleThreadExecutor& GetBackgroundExecutor() { return executor_; } - - private: - void NotifyStartCallbackStatus(BroadcastSessionId id, absl::Status status); - void RunOnServiceControllerThread(absl::string_view name, Runnable runnable) { - executor_.Execute(std::string(name), std::move(runnable)); - } - - SingleThreadExecutor& executor_; - CredentialManager& credential_manager_; - ScanManager& scan_manager_; - BroadcastManager& broadcast_manager_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_IMPL_H_ diff --git a/presence/implementation/service_controller_impl_test.cc b/presence/implementation/service_controller_impl_test.cc deleted file mode 100644 index 5d638186..00000000 --- a/presence/implementation/service_controller_impl_test.cc +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2023 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. - -#include "presence/implementation/service_controller_impl.h" - -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/credential.pb.h" -#include "presence/implementation/broadcast_manager.h" -#include "presence/implementation/mediums/mediums.h" -#include "presence/implementation/mock_credential_manager.h" -#include "presence/implementation/scan_manager.h" - -namespace nearby { -namespace presence { -namespace { - -constexpr absl::string_view kManagerAppId = "TEST_MANAGER_APP"; -constexpr absl::string_view kAccountName = "test account"; -constexpr absl::string_view kSecretId1 = "1111111"; -constexpr absl::string_view kSecretId2 = "2222222"; -constexpr absl::string_view kSecretId3 = "3333333"; - -CredentialSelector BuildDefaultCredentialSelector() { - CredentialSelector credential_selector; - credential_selector.manager_app_id = std::string(kManagerAppId); - credential_selector.account_name = std::string(kAccountName); - credential_selector.identity_type = - ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; - return credential_selector; -} - -std::vector BuildLocalCredentials() { - internal::LocalCredential local_credential1; - local_credential1.set_secret_id(kSecretId1); - internal::LocalCredential local_credential2; - local_credential2.set_secret_id(kSecretId2); - internal::LocalCredential local_credential3; - local_credential3.set_secret_id(kSecretId3); - return {local_credential1, local_credential2, local_credential3}; -} - -TEST(ServiceControllerImplTest, GetLocalCredentials) { - auto mock_credential_manager = std::make_unique(); - EXPECT_CALL(*mock_credential_manager.get(), GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - callback.credentials_fetched_cb(BuildLocalCredentials()); - }); - - Mediums mediums; - SingleThreadExecutor executor; - ScanManager scan_manager{mediums, *mock_credential_manager, executor}; - BroadcastManager broadcast_manager{mediums, *mock_credential_manager, - executor}; - - auto service_controller = std::make_unique( - &executor, mock_credential_manager.get(), &scan_manager, - &broadcast_manager); - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - absl::StatusOr> - private_credentials; - service_controller->GetLocalCredentials( - credential_selector, - {.credentials_fetched_cb = - [&](absl::StatusOr> - credentials) { - private_credentials = std::move(credentials); - }}); - - EXPECT_OK(private_credentials); - ASSERT_EQ(3u, private_credentials->size()); - ASSERT_EQ(private_credentials->at(0).secret_id(), kSecretId1); - ASSERT_EQ(private_credentials->at(1).secret_id(), kSecretId2); - ASSERT_EQ(private_credentials->at(2).secret_id(), kSecretId3); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/power_mode.h b/presence/power_mode.h deleted file mode 100644 index 229c59fd..00000000 --- a/presence/power_mode.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 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_PRESENCE_POWER_MODE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_POWER_MODE_H_ - -namespace nearby { -namespace presence { - -// High level concept of Power mode for Scan and Broadcast. -// More frequent, more power consumption, but less interval and latency. -// Native platforms would decide the specific interval based on their own -// configs. -enum class PowerMode { - kNoPower = 0, - kLowPower = 1, - kBalanced = 2, - kLowLatency = 3, -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_POWER_MODE_H_ diff --git a/presence/presence_action.cc b/presence/presence_action.cc deleted file mode 100644 index 1265eada..00000000 --- a/presence/presence_action.cc +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2020 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. - -#include "presence/presence_action.h" - -#include "internal/platform/logging.h" - -namespace nearby { -namespace presence { - -PresenceAction::PresenceAction(int action_identifier) - : action_identifier_(action_identifier) { - CHECK(kMinActionIdentifierValue <= action_identifier_ && - action_identifier_ <= kMaxActionIdentifierValue); -} - -int PresenceAction::GetActionIdentifier() const { return action_identifier_; } - -} // namespace presence -} // namespace nearby diff --git a/presence/presence_action.h b/presence/presence_action.h deleted file mode 100644 index a073f6b6..00000000 --- a/presence/presence_action.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2020 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_PRESENCE_PRESENCE_ACTION_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_ACTION_H_ - -namespace nearby { -namespace presence { -class PresenceAction { - public: - PresenceAction(int action_identifier = 1); - int GetActionIdentifier() const; - - private: - static constexpr int kMinActionIdentifierValue = 1; - static constexpr int kMaxActionIdentifierValue = 255; - const int action_identifier_; -}; - -inline bool operator==(const PresenceAction& a1, const PresenceAction& a2) { - return a1.GetActionIdentifier() == a2.GetActionIdentifier(); -} - -inline bool operator!=(const PresenceAction& a1, const PresenceAction& a2) { - return !(a1 == a2); -} -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_ACTION_H_ diff --git a/presence/presence_action_test.cc b/presence/presence_action_test.cc deleted file mode 100644 index 64b5e78e..00000000 --- a/presence/presence_action_test.cc +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 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. - -#include "presence/presence_action.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace presence { -namespace { -constexpr int kDefaultActionIdentifier = 1; -constexpr int kTestActionIdentifier = 2; -TEST(PresenceActionTest, DefaultConstructorWorks) { - PresenceAction action; - EXPECT_EQ(action.GetActionIdentifier(), kDefaultActionIdentifier); -} - -TEST(PresenceActionTest, DefaultEquals) { - PresenceAction action1; - PresenceAction action2; - EXPECT_EQ(action1, action2); -} - -TEST(PresenceActionTest, ExplicitInitEquals) { - PresenceAction action1 = {kTestActionIdentifier}; - PresenceAction action2 = {kTestActionIdentifier}; - EXPECT_EQ(action1, action2); - EXPECT_EQ(action1.GetActionIdentifier(), kTestActionIdentifier); -} - -TEST(PresenceActionTest, ExplicitInitNotEquals) { - PresenceAction action1 = {kDefaultActionIdentifier}; - PresenceAction action2 = {kTestActionIdentifier}; - EXPECT_NE(action1, action2); -} - -TEST(PresenceActionTest, CopyInitEquals) { - PresenceAction action1 = {kTestActionIdentifier}; - PresenceAction action2 = {action1}; - - EXPECT_EQ(action1, action2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_client.h b/presence/presence_client.h deleted file mode 100644 index 92807d95..00000000 --- a/presence/presence_client.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2020 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_PRESENCE_PRESENCE_CLIENT_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_H_ - -#include - -#include "absl/status/statusor.h" -#include "internal/platform/borrowable.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -class PresenceService; -/** - * Interface for detecting and interacting with nearby devices that are also - * part of the Presence ecosystem. - */ -class PresenceClient { - public: - using BorrowablePresenceService = ::nearby::Borrowable; - - virtual ~PresenceClient() = default; - - // Starts a Nearby Presence scan and registers `ScanCallback` - // which will be invoked when a matching `PresenceDevice` is detected, - // lost, and status changed. - // The session can be terminated with `StopScan()`. - // - // `ScanCallback` is kept in the Nearby Presence service until `StopScan()` is - // called. - // - // `ScanRequest` contains the options like scan power mode - // and type; the filters including credentials, actions and extended - // properties. - virtual absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) = 0; - - // Terminates the scan session. Does nothing if the session is already - // terminated. - virtual void StopScan(ScanSessionId session_id) = 0; - - // Starts a Nearby Presence broadcast and registers `BroadcastCallback` - // which will be invoked after broadcast is started. - // The session can be terminated with `StopBroadcast()`. - // - // `BroadcastCallback` is kept in the Nearby Presence service until - // `StopBroadcast()` is called. - // - // `BroadcastRequest` contains the options like tx_power, - // the credential info like salt and private credential, the actions and - // extended properties. - virtual absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) = 0; - - // Terminates a broadcast session. Does nothing if the session is already - // terminated. - virtual void StopBroadcast(BroadcastSessionId session_id) = 0; - - // Returns the local PresenceDevice describing the current device's actions, - // connectivity info and unique identifier for use in Connections and - // Presence. - virtual std::optional GetLocalDevice() = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_H_ diff --git a/presence/presence_client_impl.cc b/presence/presence_client_impl.cc deleted file mode 100644 index 706e52f2..00000000 --- a/presence/presence_client_impl.cc +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2023 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. - -#include "presence/presence_client_impl.h" - -#include -#include -#include - -#include "absl/status/status.h" -#include "internal/platform/borrowable.h" -#include "internal/platform/logging.h" -#include "presence/presence_device.h" -#include "presence/presence_service.h" - -namespace nearby { -namespace presence { - -// static -PresenceClientImpl::Factory* PresenceClientImpl::Factory::g_test_factory_ = - nullptr; - -// static -std::unique_ptr PresenceClientImpl::Factory::Create( - BorrowablePresenceService service) { - if (g_test_factory_) { - return g_test_factory_->CreateInstance(service); - } - return absl::WrapUnique(new PresenceClientImpl(service)); -} - -// static -void PresenceClientImpl::Factory::SetFactoryForTesting( - Factory* g_test_factory) { - g_test_factory_ = g_test_factory; -} - -PresenceClientImpl::Factory::~Factory() = default; - -absl::StatusOr PresenceClientImpl::StartScan( - ScanRequest scan_request, ScanCallback callback) { - ::nearby::Borrowed borrowed = service_.Borrow(); - if (!borrowed) { - return absl::FailedPreconditionError( - "Can't start scan, presence service is gone"); - } - return (*borrowed)->StartScan(scan_request, std::move(callback)); -} - -void PresenceClientImpl::StopScan(ScanSessionId id) { - ::nearby::Borrowed borrowed = service_.Borrow(); - if (borrowed) { - (*borrowed)->StopScan(id); - } -} - -absl::StatusOr PresenceClientImpl::StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) { - ::nearby::Borrowed borrowed = service_.Borrow(); - if (!borrowed) { - return absl::FailedPreconditionError( - "Can't start broadcast, presence service is gone"); - } - return (*borrowed)->StartBroadcast(broadcast_request, std::move(callback)); -} - -void PresenceClientImpl::StopBroadcast(BroadcastSessionId session_id) { - ::nearby::Borrowed borrowed = service_.Borrow(); - if (borrowed) { - (*borrowed)->StopBroadcast(session_id); - } else { - VLOG(1) << "Session already finished, id: " << session_id; - } -} - -std::optional PresenceClientImpl::GetLocalDevice() { - ::nearby::Borrowed borrowed = service_.Borrow(); - if (borrowed) { - const PresenceDevice* device = static_cast( - (*borrowed)->GetLocalDeviceProvider()->GetLocalDevice()); - return PresenceDevice(*device); - } - return std::nullopt; -} - -} // namespace presence -} // namespace nearby diff --git a/presence/presence_client_impl.h b/presence/presence_client_impl.h deleted file mode 100644 index e7f376c8..00000000 --- a/presence/presence_client_impl.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2023 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_PRESENCE_PRESENCE_CLIENT_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_IMPL_H_ - -#include -#include - -#include "absl/status/statusor.h" -#include "internal/platform/borrowable.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/presence_client.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -class PresenceClientImpl : public PresenceClient{ - public: - using BorrowablePresenceService = ::nearby::Borrowable; - - class Factory { - public: - static std::unique_ptr Create( - BorrowablePresenceService service); - static void SetFactoryForTesting(Factory* test_factory); - - protected: - virtual ~Factory(); - virtual std::unique_ptr CreateInstance( - BorrowablePresenceService service) = 0; - - private: - static Factory* g_test_factory_; - }; - - PresenceClientImpl(const PresenceClientImpl&) = delete; - PresenceClientImpl(PresenceClientImpl&&) = default; - PresenceClientImpl& operator=(const PresenceClientImpl&) = delete; - ~PresenceClientImpl() override = default; - - // PresenceClient: - absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) override; - void StopScan(ScanSessionId session_id) override; - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) override; - void StopBroadcast(BroadcastSessionId session_id) override; - std::optional GetLocalDevice() override; - - private: - explicit PresenceClientImpl(BorrowablePresenceService service) - : service_(service) {} - - BorrowablePresenceService service_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_IMPL_H_ diff --git a/presence/presence_client_test.cc b/presence/presence_client_test.cc deleted file mode 100644 index 2c43f26f..00000000 --- a/presence/presence_client_test.cc +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2020 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. - -#include "presence/presence_client.h" - -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/future.h" -#include "internal/platform/medium_environment.h" -#include "presence/data_types.h" -#include "presence/presence_device.h" -#include "presence/presence_service_impl.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::internal::DeviceIdentityMetaData; -using ::testing::status::StatusIs; - -constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; - -// Creates a PresenceClient and destroys PresenceServiceImpl that was used to -// create it. -std::unique_ptr CreateDefunctPresenceClient() { - PresenceServiceImpl presence_service; - return presence_service.CreatePresenceClient(); -} - -DeviceIdentityMetaData CreateTestDeviceIdentityMetaData() { - DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_device_type( - internal::DeviceType::DEVICE_TYPE_PHONE); - device_identity_metadata.set_device_name("NP test device"); - device_identity_metadata.set_bluetooth_mac_address(kMacAddr); - device_identity_metadata.set_device_id("\x12\xab\xcd"); - return device_identity_metadata; -} - -class PresenceClientTest : public testing::Test { - protected: - nearby::MediumEnvironment& env_{nearby::MediumEnvironment::Instance()}; -}; - -TEST_F(PresenceClientTest, StartBroadcastWithDefaultConstructor) { - env_.Start(); - absl::Status broadcast_result; - - PresenceServiceImpl presence_service; - std::unique_ptr presence_client = - presence_service.CreatePresenceClient(); - auto unused = presence_client->StartBroadcast( - {}, { - .start_broadcast_cb = - [&](absl::Status status) { broadcast_result = status; }, - }); - - EXPECT_THAT(broadcast_result, StatusIs(absl::StatusCode::kInvalidArgument)); - env_.Stop(); -} - -TEST_F(PresenceClientTest, StartBroadcastFailsWhenPresenceServiceIsGone) { - env_.Start(); - absl::Status broadcast_result = absl::UnknownError(""); - - absl::StatusOr session_id = - CreateDefunctPresenceClient()->StartBroadcast( - {}, { - .start_broadcast_cb = - [&](absl::Status status) { broadcast_result = status; }, - }); - - EXPECT_THAT(session_id, StatusIs(absl::StatusCode::kFailedPrecondition)); - EXPECT_THAT(broadcast_result, StatusIs(absl::StatusCode::kUnknown)); - env_.Stop(); -} - -TEST_F(PresenceClientTest, StartScanWithDefaultConstructor) { - env_.Start(); - ::nearby::Future scan_result; - ScanCallback scan_callback = { - .start_scan_cb = [&](absl::Status status) { scan_result.Set(status); }, - }; - - PresenceServiceImpl presence_service; - std::unique_ptr presence_client = - presence_service.CreatePresenceClient(); - EXPECT_OK(presence_client->StartScan({}, std::move(scan_callback))); - - EXPECT_TRUE(scan_result.Get().ok()); - EXPECT_OK(scan_result.Get().GetResult()); - env_.Stop(); -} - -TEST_F(PresenceClientTest, StartScanFailsWhenPresenceServiceIsGone) { - env_.Start(); - absl::Status scan_result = absl::UnknownError(""); - - absl::StatusOr session_id = - CreateDefunctPresenceClient()->StartScan( - {}, { - .start_scan_cb = - [&](absl::Status status) { scan_result = status; }, - }); - - EXPECT_THAT(session_id, StatusIs(absl::StatusCode::kFailedPrecondition)); - EXPECT_THAT(scan_result, StatusIs(absl::StatusCode::kUnknown)); - env_.Stop(); -} - -TEST_F(PresenceClientTest, GettingDeviceWorks) { - PresenceServiceImpl presence_service; - std::unique_ptr presence_client = - presence_service.CreatePresenceClient(); - presence_service.UpdateDeviceIdentityMetaData( - CreateTestDeviceIdentityMetaData(), false, "", {}, 0, 0, {}); - auto device = presence_client->GetLocalDevice(); - ASSERT_NE(device, std::nullopt); - EXPECT_EQ(device->GetEndpointId().length(), kEndpointIdLength); - EXPECT_EQ(device->GetDeviceIdentityMetadata().SerializeAsString(), - CreateTestDeviceIdentityMetaData().SerializeAsString()); -} - -TEST_F(PresenceClientTest, TestGettingDeviceDefunct) { - std::unique_ptr presence_client = - CreateDefunctPresenceClient(); - auto device = presence_client->GetLocalDevice(); - EXPECT_EQ(device, std::nullopt); -} -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_device.cc b/presence/presence_device.cc deleted file mode 100644 index e2651089..00000000 --- a/presence/presence_device.cc +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2023 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. - -#include "presence/presence_device.h" - -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/types/variant.h" -#include "connections/implementation/proto/offline_wire_formats.pb.h" -#include "internal/interop/device.h" -#include "internal/platform/ble_connection_info.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/prng.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/device_motion.h" - -namespace nearby { -namespace presence { - -namespace { -constexpr char kEndpointIdChars[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; - -// LINT.IfChange -constexpr int kAndroidIdentityTypeUnknown = -1; -constexpr int kAndroidIdentityTypePrivateGroup = 0; -constexpr int kAndroidIdentityTypeContactsGroup = 1; -constexpr int kAndroidIdentityTypePublic = 2; -// LINT.ThenChange( -// //depot/google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/presence/PresenceIdentity.java -// ) - -std::string GenerateRandomEndpointId() { - std::string result(kEndpointIdLength, 0); - nearby::Prng prng; - for (int i = 0; i < kEndpointIdLength; i++) { - result[i] = kEndpointIdChars[prng.NextUint32() % sizeof(kEndpointIdChars)]; - } - return result; -} - -location::nearby::connections::PresenceDevice::DeviceType -ConvertToConnectionsDeviceType(internal::DeviceType device_type) { - switch (device_type) { - case internal::DEVICE_TYPE_FOLDABLE: - case internal::DEVICE_TYPE_PHONE: - return location::nearby::connections::PresenceDevice::PHONE; - case internal::DEVICE_TYPE_TABLET: - return location::nearby::connections::PresenceDevice::TABLET; - case internal::DEVICE_TYPE_DISPLAY: - return location::nearby::connections::PresenceDevice::DISPLAY; - case internal::DEVICE_TYPE_CHROMEOS: - case internal::DEVICE_TYPE_LAPTOP: - return location::nearby::connections::PresenceDevice::LAPTOP; - case internal::DEVICE_TYPE_TV: - return location::nearby::connections::PresenceDevice::TV; - case internal::DEVICE_TYPE_WATCH: - return location::nearby::connections::PresenceDevice::WATCH; - default: - return location::nearby::connections::PresenceDevice::UNKNOWN; - } -} - -int ConvertToAndroidIdentityType(nearby::internal::IdentityType identity_type) { - switch (identity_type) { - case internal::IDENTITY_TYPE_PRIVATE_GROUP: - return kAndroidIdentityTypePrivateGroup; - case internal::IDENTITY_TYPE_CONTACTS_GROUP: - return kAndroidIdentityTypeContactsGroup; - case internal::IDENTITY_TYPE_PUBLIC: - return kAndroidIdentityTypePublic; - default: - // Unknown identity. - return kAndroidIdentityTypeUnknown; - } -} -} // namespace - -PresenceDevice::PresenceDevice(absl::string_view endpoint_id) noexcept - : endpoint_id_(endpoint_id) {} - -PresenceDevice::PresenceDevice( - DeviceIdentityMetaData device_identity_metadata) noexcept - : discovery_timestamp_(nearby::SystemClock::ElapsedRealtime()), - device_motion_(DeviceMotion()), - device_identity_metadata_(device_identity_metadata) { - endpoint_id_ = GenerateRandomEndpointId(); -} -PresenceDevice::PresenceDevice( - DeviceMotion device_motion, - DeviceIdentityMetaData device_identity_metadata) noexcept - : discovery_timestamp_(nearby::SystemClock::ElapsedRealtime()), - device_motion_(device_motion), - device_identity_metadata_(device_identity_metadata) { - endpoint_id_ = GenerateRandomEndpointId(); -} - -PresenceDevice::PresenceDevice( - DeviceMotion device_motion, DeviceIdentityMetaData device_identity_metadata, - nearby::internal::IdentityType identity_type) noexcept - : discovery_timestamp_(nearby::SystemClock::ElapsedRealtime()), - device_motion_(device_motion), - device_identity_metadata_(device_identity_metadata), - identity_type_(identity_type) { - endpoint_id_ = GenerateRandomEndpointId(); -} - -std::vector PresenceDevice::GetConnectionInfos() - const { - std::vector transformed_actions; - transformed_actions.reserve(actions_.size()); - for (const auto& action : actions_) { - transformed_actions.push_back(action.GetActionIdentifier()); - } - return {nearby::BleConnectionInfo( - device_identity_metadata_.bluetooth_mac_address(), - /*gatt_characteristic=*/"", /*psm=*/"", transformed_actions)}; -} - -std::string PresenceDevice::ToProtoBytes() const { - location::nearby::connections::PresenceDevice device; - device.set_endpoint_id(endpoint_id_); - device.add_identity_type(ConvertToAndroidIdentityType(identity_type_)); - device.set_endpoint_type( - location::nearby::connections::EndpointType::PRESENCE_ENDPOINT); - auto* actions = device.mutable_actions(); - for (const auto& action : actions_) { - actions->Add(action.GetActionIdentifier()); - } - std::string connection_infos = ""; - for (const auto& connection_info : GetConnectionInfos()) { - if (absl::holds_alternative(connection_info)) { - continue; - } - if (absl::holds_alternative(connection_info)) { - connection_infos += - absl::get(connection_info).ToDataElementBytes(); - } - if (absl::holds_alternative(connection_info)) { - connection_infos += absl::get(connection_info) - .ToDataElementBytes(); - } - if (absl::holds_alternative(connection_info)) { - connection_infos += absl::get(connection_info) - .ToDataElementBytes(); - } - } - device.set_device_type( - ConvertToConnectionsDeviceType(device_identity_metadata_.device_type())); - device.set_device_name(device_identity_metadata_.device_name()); - device.set_connectivity_info_list(connection_infos); - device.set_device_image_url("dummy url"); // Not used. - return device.SerializeAsString(); -} -} // namespace presence -} // namespace nearby diff --git a/presence/presence_device.h b/presence/presence_device.h deleted file mode 100644 index 93bac818..00000000 --- a/presence/presence_device.h +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2020 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_PRESENCE_PRESENCE_DEVICE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_H_ - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "internal/interop/device.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/data_element.h" -#include "presence/device_motion.h" -#include "presence/presence_action.h" - -namespace nearby { -namespace presence { - -inline constexpr int kEndpointIdLength = 4; - -class PresenceDevice : public nearby::NearbyDevice { - using Metadata = ::nearby::internal::Metadata; - using DeviceIdentityMetaData = ::nearby::internal::DeviceIdentityMetaData; - - public: - explicit PresenceDevice(absl::string_view endpoint_id) noexcept; - explicit PresenceDevice( - DeviceIdentityMetaData device_identity_metadata) noexcept; - explicit PresenceDevice( - DeviceMotion device_motion, - DeviceIdentityMetaData device_identity_metadata) noexcept; - explicit PresenceDevice( - DeviceMotion device_motion, - DeviceIdentityMetaData device_identity_metadata, - nearby::internal::IdentityType identity_type) noexcept; - std::string GetEndpointId() const override { return endpoint_id_; } - std::vector GetConnectionInfos() - const override; - std::string ToProtoBytes() const override; - void AddExtendedProperty(const DataElement& data_element) { - extended_properties_.push_back(data_element); - } - void AddExtendedProperties(const std::vector& properties) { - extended_properties_.insert(extended_properties_.end(), properties.begin(), - properties.end()); - } - std::vector GetExtendedProperties() const { - return extended_properties_; - } - void AddAction(const PresenceAction& action) { actions_.push_back(action); } - std::vector GetActions() const { return actions_; } - NearbyDevice::Type GetType() const override { - return NearbyDevice::Type::kPresenceDevice; - } - DeviceMotion GetDeviceMotion() const { return device_motion_; } - DeviceIdentityMetaData GetDeviceIdentityMetadata() const { - return device_identity_metadata_; - } - void SetDeviceIdentityMetaData( - const DeviceIdentityMetaData& device_identity_metadata) { - device_identity_metadata_ = device_identity_metadata; - } - void SetDecryptSharedCredential( - const internal::SharedCredential& decrypt_shared_credential) { - decrypt_shared_credential_ = decrypt_shared_credential; - } - const std::optional& GetDecryptSharedCredential() - const { - return decrypt_shared_credential_; - } - absl::Time GetDiscoveryTimestamp() const { return discovery_timestamp_; } - internal::IdentityType GetIdentityType() const { return identity_type_; } - - private: - const absl::Time discovery_timestamp_; - const DeviceMotion device_motion_; - DeviceIdentityMetaData device_identity_metadata_; - std::vector extended_properties_; - std::vector actions_; - std::string endpoint_id_; - internal::IdentityType identity_type_ = internal::IDENTITY_TYPE_UNSPECIFIED; - std::optional decrypt_shared_credential_; -}; - -// Timestamp is not used for equality since if the same device is discovered -// twice, they will have different timestamps and thus will show up as two -// different devices when they are the same device. -inline bool operator==(const PresenceDevice& d1, const PresenceDevice& d2) { - bool shared_credential_equality = true; - shared_credential_equality &= d1.GetDecryptSharedCredential().has_value() == - d2.GetDecryptSharedCredential().has_value(); - if (shared_credential_equality && - d1.GetDecryptSharedCredential().has_value()) { - shared_credential_equality &= - d1.GetDecryptSharedCredential()->SerializeAsString() == - d2.GetDecryptSharedCredential()->SerializeAsString(); - } - return d1.GetDeviceMotion() == d2.GetDeviceMotion() && - d1.GetDeviceIdentityMetadata().SerializeAsString() == - d2.GetDeviceIdentityMetadata().SerializeAsString() && - d1.GetActions() == d2.GetActions() && - d1.GetExtendedProperties() == d2.GetExtendedProperties() && - d1.GetIdentityType() == d2.GetIdentityType() && - shared_credential_equality; -} - -inline bool operator!=(const PresenceDevice& d1, const PresenceDevice& d2) { - return !(d1 == d2); -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_H_ diff --git a/presence/presence_device_provider.cc b/presence/presence_device_provider.cc deleted file mode 100644 index 1b0d4258..00000000 --- a/presence/presence_device_provider.cc +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2023 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. - -#include "presence/presence_device_provider.h" - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "absl/types/variant.h" -#include "internal/interop/authentication_status.h" -#include "internal/interop/authentication_transport.h" -#include "internal/interop/device.h" -#include "internal/platform/exception.h" -#include "internal/platform/future.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/logging.h" -#include "presence/implementation/connection_authenticator.h" -#include "presence/implementation/service_controller.h" -#include "presence/presence_device.h" -#include "presence/proto/presence_frame.pb.h" - -namespace nearby { -namespace presence { - -namespace { - -constexpr int kPresenceVersion = 1; - -// TODO(b/317215548): Use Status code rather than custom defined -// authentication status. -std::string AuthenticationErrorToString(AuthenticationStatus status) { - switch (status) { - case AuthenticationStatus::kUnknown: - return "AuthenticationStatus::kUnknown"; - case AuthenticationStatus::kSuccess: - return "AuthenticationStatus::kSuccess"; - case AuthenticationStatus::kFailure: - return "AuthenticationStatus::kFailure"; - } - LOG(ERROR) << "Unexpected value for AuthenticationStatus: " - << static_cast(status); - return "AuthenticationStatus::kUnknown"; -} - -std::optional GetValidCredential( - std::vector local_credentials) { - absl::Time now = SystemClock::ElapsedRealtime(); - for (auto& credential : local_credentials) { - if (absl::FromUnixMillis(credential.start_time_millis()) <= now && - absl::FromUnixMillis(credential.end_time_millis()) > now) { - return credential; - } - } - return std::nullopt; -} - -PresenceAuthenticationFrame BuildInitiatorPresenceAuthenticationFrame( - ConnectionAuthenticator::InitiatorData initiator_data_variant) { - // It is expected that the `PresenceAuthenticationFrame` built for the - // initator role always is `TwoWayInitiatorData`, since the local device is - // always expected to have a valid local credential to be used, and this is - // verified in AuthenticateAsInitiator(), which returns failure if no valid - // local credential is found (which is expected to not happen, since valid - // credentials will be generated if needed before the authentiation is - // called). - // - // Note: std::holds_alternative and std::get cannot be used here because - // they are not supported in Chromium. - DCHECK(absl::holds_alternative( - initiator_data_variant)); - auto two_way_initiator_data = - absl::get( - initiator_data_variant); - - PresenceAuthenticationFrame authentication_frame; - authentication_frame.set_version(kPresenceVersion); - authentication_frame.set_private_key_signature( - two_way_initiator_data.private_key_signature); - authentication_frame.set_shared_credential_id_hash( - two_way_initiator_data.shared_credential_hash); - return authentication_frame; -} - -} // namespace - -PresenceDeviceProvider::PresenceDeviceProvider( - ServiceController* service_controller, - const ConnectionAuthenticator* connection_authenticator) - : service_controller_(*service_controller), - device_(service_controller_.GetDeviceIdentityMetaData()), - connection_authenticator_(*connection_authenticator) { - CHECK(connection_authenticator); -} - -AuthenticationStatus PresenceDeviceProvider::AuthenticateAsInitiator( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport) const { - Future response; - - // 1. Fetch the local credentials and select the correct one to use - // for authentication by calling `GetValidCredential()`, which - // iterates over the returned list and returns the local credential - // that corresponds with the current time. - // - // TODO(b/304843571): Add support for additional IdentityTypes and for - // AuthenticationStatus::kUnknown. Currently, only `IDENTITY_TYPE_PRIVATE` is - // supported in order to unblock Nearby Presence MVP on CrOS, however in - // order to support future IdentityTypes, there needs to be a way to - // plumb in the requested identity type, as well as report back the - // unknown result to callers in NC. - service_controller_.GetLocalCredentials( - /*credential_selector=*/{.manager_app_id = manager_app_id_, - .account_name = "dummy_account_name", - .identity_type = ::nearby::internal:: - IdentityType::IDENTITY_TYPE_PRIVATE_GROUP}, - /*callback=*/{.credentials_fetched_cb = [this, &response, &remote_device, - &authentication_transport, - &shared_secret]( - auto status_or_credentials) { - if (!status_or_credentials.ok()) { - LOG(INFO) << __func__ << ": failure to fetch local credentials"; - response.Set(AuthenticationStatus::kFailure); - return; - } - - auto credential = GetValidCredential(status_or_credentials.value()); - if (!credential.has_value()) { - LOG(INFO) << __func__ << ": failure to find a valid local credential"; - response.Set(AuthenticationStatus::kFailure); - return; - } - - // 2. Construct the frame and write to the - // |authentication_transport|. - if (!WriteToRemoteDevice( - /*remote_device=*/remote_device, - /*shared_secret=*/shared_secret, - /*authentication_transport=*/authentication_transport, - /*local_credential=*/credential.value(), - /*response=*/response)) { - response.Set(AuthenticationStatus::kFailure); - return; - } - - // 3. Read the message from the remote device via - // |authentication_transport| and verify the response data. - if (!ReadAndVerifyRemoteDeviceData( - /*remote_device=*/remote_device, - /*shared_secret=*/shared_secret, - /*authentication_transport=*/authentication_transport)) { - response.Set(AuthenticationStatus::kFailure); - return; - } - - // 4. Return the status of the authentication to the callers. - response.Set(AuthenticationStatus::kSuccess); - }}); - - LOG(INFO) << __func__ << ": Waiting for future to complete"; - ExceptionOr result = response.Get(); - CHECK(result.ok()); - - LOG(INFO) << "Future:[" << __func__ << "] completed with status:" - << AuthenticationErrorToString(result.result()); - return result.result(); -} - -bool PresenceDeviceProvider::WriteToRemoteDevice( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport, - const internal::LocalCredential& local_credential, - Future& response) const { - // Cast the |remote_device| to a `PresenceDevice` in order to retrieve - // it's shared credentials, which is safe to do since the |remote_device| - // passed to the `PresenceDeviceProvider` will always be a `PresenceDevice`. - const PresenceDevice* remote_presence_device = - static_cast(&remote_device); - auto shared_credential = remote_presence_device->GetDecryptSharedCredential(); - if (!shared_credential.has_value()) { - LOG(INFO) - << __func__ - << ": failure due to no decrypt shared credential from remote device"; - return false; - } - - auto status_or_initiator_data = - connection_authenticator_.BuildSignedMessageAsInitiator( - /*ukey2_secret=*/shared_secret, /*local_credential=*/local_credential, - /*shared_credential=*/shared_credential.value()); - if (!status_or_initiator_data.ok()) { - LOG(INFO) << __func__ << ": failure to build signed message as initiator"; - return false; - } - - // Once the initiator data has been built, construct the Presence frame - // which will be written to the device with the built data. - authentication_transport.WriteMessage( - BuildInitiatorPresenceAuthenticationFrame( - status_or_initiator_data.value()) - .SerializeAsString()); - return true; -} - -bool PresenceDeviceProvider::ReadAndVerifyRemoteDeviceData( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport) const { - // Fetch the local public credentials to be used to verify the response data. - Future read_and_verify_result; - service_controller_.GetLocalPublicCredentials( - /*credential_selector=*/{.manager_app_id = manager_app_id_, - .account_name = "dummy_account_name", - .identity_type = ::nearby::internal:: - IdentityType::IDENTITY_TYPE_PRIVATE_GROUP}, - /*callback=*/{.credentials_fetched_cb = [this, &read_and_verify_result, - &authentication_transport, - &shared_secret]( - auto status_or_credentials) { - if (!status_or_credentials.ok()) { - LOG(INFO) << __func__ - << ": failure to fetch local public credentials"; - read_and_verify_result.Set(/*success=*/false); - return; - } - - std::string response_data = authentication_transport.ReadMessage(); - auto status = connection_authenticator_.VerifyMessageAsInitiator( - /*authentication_data=*/{.private_key_signature = response_data}, - /*ukey2_secret=*/shared_secret, - /*shared_credential=*/status_or_credentials.value()); - if (!status.ok()) { - LOG(INFO) << __func__ << ": failure to verify remote device"; - read_and_verify_result.Set(/*success=*/false); - return; - } - - read_and_verify_result.Set(/*success=*/true); - }}); - - LOG(INFO) << __func__ << ": Waiting for future to complete"; - ExceptionOr result = read_and_verify_result.Get(); - LOG(INFO) << "Future:[" << __func__ - << "] completed with status:" << result.result(); - return result.result(); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/presence_device_provider.h b/presence/presence_device_provider.h deleted file mode 100644 index afa1df51..00000000 --- a/presence/presence_device_provider.h +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2023 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_PRESENCE_PRESENCE_DEVICE_PROVIDER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_PROVIDER_H_ - -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/interop/authentication_status.h" -#include "internal/interop/authentication_transport.h" -#include "internal/interop/device.h" -#include "internal/interop/device_provider.h" -#include "internal/platform/future.h" -#include "internal/proto/local_credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/implementation/connection_authenticator.h" -#include "presence/presence_device.h" - -namespace nearby { -namespace presence { - -class ServiceController; - -class PresenceDeviceProvider : public NearbyDeviceProvider { - public: - PresenceDeviceProvider( - ServiceController* service_controller, - const ConnectionAuthenticator* connection_authenticator); - - const NearbyDevice* GetLocalDevice() override { return &device_; } - - // To authenticate as an initiator (when the device is in the scanning role), - // the PresenceDeviceProvider will block and: - // 1. Fetch the local credentials and select the correct one to use for - // authentication. - // 2. Construct the frame and write to the |authentication_transport|. - // 3. Read the message from the remote device via |authentication_transport|. - // 4. Return the status of the authentication to the callers. - AuthenticationStatus AuthenticateAsInitiator( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport) const override; - - AuthenticationStatus AuthenticateAsResponder( - absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport) const override { - // TODO(b/282027237): Implement. - return AuthenticationStatus::kUnknown; - } - - void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata) { - device_.SetDeviceIdentityMetaData(device_identity_metadata); - } - - void SetManagerAppId(absl::string_view manager_app_id) { - manager_app_id_ = manager_app_id; - } - - std::string GetManagerAppId() { return manager_app_id_; } - - private: - bool WriteToRemoteDevice( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport, - const internal::LocalCredential& local_credential, - Future& response) const; - bool ReadAndVerifyRemoteDeviceData( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport) const; - - ServiceController& service_controller_; - PresenceDevice device_; - std::string manager_app_id_; - const ConnectionAuthenticator& connection_authenticator_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_PROVIDER_H_ diff --git a/presence/presence_device_provider_test.cc b/presence/presence_device_provider_test.cc deleted file mode 100644 index a8985270..00000000 --- a/presence/presence_device_provider_test.cc +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright 2023 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. - -#include "presence/presence_device_provider.h" - -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "internal/crypto/ed25519.h" -#include "internal/interop/authentication_status.h" -#include "internal/interop/authentication_transport.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/implementation/connection_authenticator.h" -#include "presence/implementation/mock_connection_authenticator.h" -#include "presence/implementation/mock_service_controller.h" -#include "presence/presence_device.h" -#include "presence/proto/presence_frame.pb.h" - -namespace nearby { -namespace presence { -namespace { -using ::nearby::internal::DeviceIdentityMetaData; - -constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; -constexpr absl::string_view kManagerAppId = "test_app_id"; -constexpr char kUkey2Secret[] = {0x34, 0x56, 0x78, 0x90}; -constexpr char kKeySeed[] = {1, 2, 3, 4, 5, 6, 7, 8}; -constexpr int kPresenceVersion = 1; -constexpr absl::string_view kSharedCredentialHash = "shared_cred_hash"; -constexpr absl::string_view kPrivateKeySignature = "private_key_signature"; - -DeviceIdentityMetaData CreateTestDeviceIdentityMetaData() { - DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_device_type( - internal::DeviceType::DEVICE_TYPE_PHONE); - device_identity_metadata.set_device_name("NP test device"); - device_identity_metadata.set_bluetooth_mac_address(kMacAddr); - device_identity_metadata.set_device_id("\x12\xab\xcd"); - return device_identity_metadata; -} - -nearby::internal::LocalCredential CreateValidLocalCredential( - const crypto::Ed25519KeyPair& key_pair) { - nearby::internal::LocalCredential credential; - absl::Time now = SystemClock::ElapsedRealtime(); - credential.set_start_time_millis(absl::ToUnixMillis(now)); - credential.set_end_time_millis(absl::ToUnixMillis(now + absl::Minutes(10))); - credential.mutable_connection_signing_key()->set_key( - absl::StrCat(key_pair.private_key, key_pair.public_key)); - credential.set_key_seed(kKeySeed); - return credential; -} - -nearby::internal::LocalCredential CreateExpiredLocalCredential() { - nearby::internal::LocalCredential credential; - absl::Time now = SystemClock::ElapsedRealtime(); - credential.set_start_time_millis(absl::ToUnixMillis(now - absl::Minutes(30))); - credential.set_end_time_millis(absl::ToUnixMillis(now - absl::Minutes(10))); - return credential; -} - -internal::SharedCredential BuildSharedCredential( - const crypto::Ed25519KeyPair& key_pair) { - internal::SharedCredential shared_credential; - shared_credential.set_connection_signature_verification_key( - key_pair.public_key); - shared_credential.set_key_seed(kKeySeed); - return shared_credential; -} - -ConnectionAuthenticator::TwoWayInitiatorData BuildDefaultInitiatorData() { - ConnectionAuthenticator::TwoWayInitiatorData data; - data.shared_credential_hash = kSharedCredentialHash; - data.private_key_signature = kPrivateKeySignature; - return data; -} - -class MockAuthenticationTransport : public AuthenticationTransport { - public: - MOCK_METHOD(void, WriteMessage, (absl::string_view), (const, override)); - MOCK_METHOD(std::string, ReadMessage, (), (const, override)); -}; - -class PresenceDeviceProviderTest : public ::testing::Test { - public: - PresenceDeviceProviderTest() { - ON_CALL(mock_service_controller_, GetDeviceIdentityMetaData) - .WillByDefault(testing::Return(CreateTestDeviceIdentityMetaData())); - provider_ = std::make_unique( - &mock_service_controller_, &mock_connection_authenticator_); - } - - void SetUp() override { - auto key_pair_or_status = crypto::Ed25519Signer::CreateNewKeyPair(); - ASSERT_OK_AND_ASSIGN(key_pair_, key_pair_or_status); - } - - protected: - MockServiceController mock_service_controller_; - std::unique_ptr provider_; - crypto::Ed25519KeyPair key_pair_; - MockConnectionAuthenticator mock_connection_authenticator_; -}; - -TEST_F(PresenceDeviceProviderTest, ProviderIsNotTriviallyConstructible) { - EXPECT_FALSE(std::is_trivially_constructible::value); -} - -TEST_F(PresenceDeviceProviderTest, DeviceProviderWorks) { - auto device = provider_->GetLocalDevice(); - ASSERT_EQ(device->GetType(), NearbyDevice::Type::kPresenceDevice); - auto presence_device = static_cast(device); - EXPECT_EQ(presence_device->GetDeviceIdentityMetadata().SerializeAsString(), - CreateTestDeviceIdentityMetaData().SerializeAsString()); -} - -TEST_F(PresenceDeviceProviderTest, DeviceProviderCanUpdateDevice) { - auto device = provider_->GetLocalDevice(); - ASSERT_EQ(device->GetType(), NearbyDevice::Type::kPresenceDevice); - auto presence_device = static_cast(device); - EXPECT_EQ(presence_device->GetDeviceIdentityMetadata().SerializeAsString(), - CreateTestDeviceIdentityMetaData().SerializeAsString()); - auto new_metadata = CreateTestDeviceIdentityMetaData(); - new_metadata.set_device_name("NP interop device"); - provider_->UpdateDeviceIdentityMetaData(new_metadata); - EXPECT_EQ(presence_device->GetDeviceIdentityMetadata().SerializeAsString(), - new_metadata.SerializeAsString()); -} - -TEST_F(PresenceDeviceProviderTest, SetGetManagerAppId) { - provider_->SetManagerAppId(kManagerAppId); - EXPECT_EQ(provider_->GetManagerAppId(), kManagerAppId); -} - -TEST_F(PresenceDeviceProviderTest, - AuthenticateAsInitiatorFails_FailToFetchCredentials) { - EXPECT_CALL(mock_service_controller_, GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - std::move(callback.credentials_fetched_cb)( - absl::Status(absl::StatusCode::kCancelled, /*msg=*/std::string())); - }); - - PresenceDevice remote_device(CreateTestDeviceIdentityMetaData()); - MockAuthenticationTransport authentication_transport; - auto status = provider_->AuthenticateAsInitiator( - /*remote_device=*/remote_device, /*shared_secret=*/kUkey2Secret, - /*authentication_transport=*/authentication_transport); - EXPECT_EQ(AuthenticationStatus::kFailure, status); -} - -TEST_F(PresenceDeviceProviderTest, - AuthenticateAsInitiatorFails_NoValidCredentials) { - EXPECT_CALL(mock_service_controller_, GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(CreateExpiredLocalCredential()); - std::move(callback.credentials_fetched_cb)(credentials); - }); - - PresenceDevice remote_device(CreateTestDeviceIdentityMetaData()); - MockAuthenticationTransport authentication_transport; - auto status = provider_->AuthenticateAsInitiator( - /*remote_device=*/remote_device, /*shared_secret=*/kUkey2Secret, - /*authentication_transport=*/authentication_transport); - EXPECT_EQ(AuthenticationStatus::kFailure, status); -} - -TEST_F(PresenceDeviceProviderTest, - AuthenticateAsInitiator_NoRemoteSharedCredential) { - EXPECT_CALL(mock_service_controller_, GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(CreateValidLocalCredential(key_pair_)); - std::move(callback.credentials_fetched_cb)(credentials); - }); - - PresenceDevice remote_device(CreateTestDeviceIdentityMetaData()); - MockAuthenticationTransport authentication_transport; - auto status = provider_->AuthenticateAsInitiator( - /*remote_device=*/remote_device, /*shared_secret=*/kUkey2Secret, - /*authentication_transport=*/authentication_transport); - - EXPECT_EQ(AuthenticationStatus::kFailure, status); -} - -TEST_F(PresenceDeviceProviderTest, AuthenticateAsInitiator_FailureToVerify) { - EXPECT_CALL(mock_service_controller_, GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(CreateValidLocalCredential(key_pair_)); - std::move(callback.credentials_fetched_cb)(credentials); - }); - EXPECT_CALL(mock_service_controller_, GetLocalPublicCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(BuildSharedCredential(key_pair_)); - std::move(callback.credentials_fetched_cb)(credentials); - }); - - PresenceDevice remote_device(CreateTestDeviceIdentityMetaData()); - remote_device.SetDecryptSharedCredential(BuildSharedCredential(key_pair_)); - - MockAuthenticationTransport authentication_transport; - EXPECT_CALL(authentication_transport, WriteMessage) - .WillOnce([&](absl::string_view message) { - PresenceAuthenticationFrame authentication_frame; - EXPECT_TRUE(authentication_frame.ParseFromString(message)); - EXPECT_EQ(kPresenceVersion, authentication_frame.version()); - }); - EXPECT_CALL(authentication_transport, ReadMessage).WillOnce([&]() { - PresenceAuthenticationFrame authentication_frame; - return authentication_frame.SerializeAsString(); - }); - - EXPECT_CALL(mock_connection_authenticator_, BuildSignedMessageAsInitiator) - .WillOnce(testing::Return(BuildDefaultInitiatorData())); - EXPECT_CALL(mock_connection_authenticator_, VerifyMessageAsInitiator) - .WillOnce(testing::Return( - absl::Status(absl::StatusCode::kCancelled, /*msg=*/std::string()))); - - auto status = provider_->AuthenticateAsInitiator( - /*remote_device=*/remote_device, /*shared_secret=*/kUkey2Secret, - /*authentication_transport=*/authentication_transport); - EXPECT_EQ(AuthenticationStatus::kFailure, status); -} - -TEST_F(PresenceDeviceProviderTest, AuthenticateAsInitiator_Success) { - EXPECT_CALL(mock_service_controller_, GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(CreateValidLocalCredential(key_pair_)); - std::move(callback.credentials_fetched_cb)(credentials); - }); - EXPECT_CALL(mock_service_controller_, GetLocalPublicCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(BuildSharedCredential(key_pair_)); - std::move(callback.credentials_fetched_cb)(std::move(credentials)); - }); - - PresenceDevice remote_device(CreateTestDeviceIdentityMetaData()); - remote_device.SetDecryptSharedCredential(BuildSharedCredential(key_pair_)); - - ON_CALL(mock_connection_authenticator_, BuildSignedMessageAsInitiator) - .WillByDefault(testing::Return(BuildDefaultInitiatorData())); - - MockAuthenticationTransport authentication_transport; - EXPECT_CALL(authentication_transport, WriteMessage) - .WillOnce([&](absl::string_view message) { - PresenceAuthenticationFrame authentication_frame; - EXPECT_TRUE(authentication_frame.ParseFromString(message)); - EXPECT_EQ(kPresenceVersion, authentication_frame.version()); - }); - - auto status = provider_->AuthenticateAsInitiator( - /*remote_device=*/remote_device, /*shared_secret=*/kUkey2Secret, - /*authentication_transport=*/authentication_transport); - - EXPECT_EQ(AuthenticationStatus::kSuccess, status); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_device_test.cc b/presence/presence_device_test.cc deleted file mode 100644 index e567d749..00000000 --- a/presence/presence_device_test.cc +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2023 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. - -#include "presence/presence_device.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "connections/implementation/proto/offline_wire_formats.pb.h" -#include "internal/platform/ble_connection_info.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/data_element.h" -#include "presence/presence_action.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::internal::DeviceIdentityMetaData; -using ::testing::Contains; - -constexpr DeviceMotion::MotionType kDefaultMotionType = - DeviceMotion::MotionType::kPointAndHold; -constexpr float kDefaultConfidence = 0; -constexpr float kTestConfidence = 0.1; -constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; -constexpr int kDataElementType = DataElement::kBatteryFieldType; -constexpr absl::string_view kDataElementValue = "15"; -constexpr char kEndpointId[] = "endpoint_id"; -constexpr int kTestAction = 3; - -DeviceIdentityMetaData CreateTestDeviceIdentityMetaData() { - DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_device_type( - internal::DeviceType::DEVICE_TYPE_LAPTOP); - device_identity_metadata.set_device_name("NP test device"); - device_identity_metadata.set_bluetooth_mac_address(kMacAddr); - device_identity_metadata.set_device_id("\x12\xab\xcd"); - return device_identity_metadata; -} -TEST(PresenceDeviceTest, EndpointIdConstructor) { - PresenceDevice device(kEndpointId); - EXPECT_EQ(device.GetEndpointId(), kEndpointId); -} - -TEST(PresenceDeviceTest, DefaultMotionEquals) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device1(device_identity_metadata); - PresenceDevice device2(device_identity_metadata); - EXPECT_EQ(device1, device2); -} - -TEST(PresenceDeviceTest, ExplicitInitEquals) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - internal::SharedCredential shared_credential; - shared_credential.set_credential_type(internal::CREDENTIAL_TYPE_GAIA); - PresenceDevice device1 = - PresenceDevice({kDefaultMotionType, kTestConfidence}, - device_identity_metadata, internal::IDENTITY_TYPE_PUBLIC); - device1.SetDecryptSharedCredential(shared_credential); - PresenceDevice device2 = - PresenceDevice({kDefaultMotionType, kTestConfidence}, - device_identity_metadata, internal::IDENTITY_TYPE_PUBLIC); - device2.SetDecryptSharedCredential(shared_credential); - EXPECT_EQ(device1, device2); -} - -TEST(PresenceDeviceTest, ExplicitInitNotEquals) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device1 = - PresenceDevice({kDefaultMotionType}, device_identity_metadata, - internal::IDENTITY_TYPE_PUBLIC); - PresenceDevice device2 = PresenceDevice( - {kDefaultMotionType, kTestConfidence}, device_identity_metadata, - internal::IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_NE(device1, device2); -} - -TEST(PresenceDeviceTest, TestGetBleConnectionInfo) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - device.AddAction(PresenceAction(kTestAction)); - auto info = (device.GetConnectionInfos().at(0)); - ASSERT_TRUE(std::holds_alternative(info)); - auto ble_info = std::get(info); - EXPECT_EQ(ble_info.GetMacAddress(), kMacAddr); - EXPECT_EQ(ble_info.GetActions(), std::vector{kTestAction}); -} - -TEST(PresenceDeviceTest, TestGetAddExtendedProperties) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - device.AddExtendedProperty({kDataElementType, kDataElementValue}); - ASSERT_EQ(device.GetExtendedProperties().size(), 1); - EXPECT_EQ(device.GetExtendedProperties()[0], - DataElement(kDataElementType, kDataElementValue)); -} - -TEST(PresenceDeviceTest, TestGetAddExtendedPropertiesVector) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - device.AddExtendedProperties( - {DataElement(kDataElementType, kDataElementValue)}); - ASSERT_EQ(device.GetExtendedProperties().size(), 1); - EXPECT_EQ(device.GetExtendedProperties()[0], - DataElement(kDataElementType, kDataElementValue)); -} - -TEST(PresenceDeviceTest, TestAddGetActions) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - device.AddAction({kTestAction}); - ASSERT_EQ(device.GetActions().size(), 1); - EXPECT_EQ(device.GetActions()[0], PresenceAction(kTestAction)); -} - -TEST(PresenceDeviceTest, TestEndpointIdIsCorrectLength) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - EXPECT_EQ(device.GetEndpointId().length(), kEndpointIdLength); -} - -TEST(PresenceDeviceTest, TestEndpointIdIsRandom) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - EXPECT_EQ(device.GetEndpointId().length(), kEndpointIdLength); - EXPECT_NE(device.GetEndpointId(), std::string(kEndpointIdLength, 0)); -} - -TEST(PresenceDeviceTest, TestGetIdentityType) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = PresenceDevice( - DeviceMotion(), device_identity_metadata, internal::IDENTITY_TYPE_PUBLIC); - EXPECT_EQ(device.GetIdentityType(), internal::IDENTITY_TYPE_PUBLIC); -} - -TEST(PresenceDeviceTest, TestGetDecryptSharedCredential) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = PresenceDevice( - DeviceMotion(), device_identity_metadata, internal::IDENTITY_TYPE_PUBLIC); - EXPECT_EQ(device.GetDecryptSharedCredential(), std::nullopt); - internal::SharedCredential shared_credential; - shared_credential.set_credential_type(internal::CREDENTIAL_TYPE_GAIA); - device.SetDecryptSharedCredential(shared_credential); - EXPECT_EQ(device.GetDecryptSharedCredential()->SerializeAsString(), - shared_credential.SerializeAsString()); -} - -TEST(PresenceDeviceTest, TestToProtoBytes) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = PresenceDevice( - DeviceMotion(), device_identity_metadata, internal::IDENTITY_TYPE_PUBLIC); - std::string proto_bytes = device.ToProtoBytes(); - location::nearby::connections::PresenceDevice device_frame; - ASSERT_TRUE(device_frame.ParseFromString(proto_bytes)); - // Public identity. - EXPECT_THAT(device_frame.identity_type(), Contains(2)); - EXPECT_EQ(device_frame.endpoint_type(), - location::nearby::connections::PRESENCE_ENDPOINT); - EXPECT_EQ(device_frame.endpoint_id(), device.GetEndpointId()); - EXPECT_EQ(device_frame.device_type(), - location::nearby::connections::PresenceDevice::LAPTOP); - EXPECT_EQ(device_frame.device_name(), "NP test device"); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_identity_test.cc b/presence/presence_identity_test.cc deleted file mode 100644 index 5b45704d..00000000 --- a/presence/presence_identity_test.cc +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2020 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. - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "internal/proto/credential.pb.h" - -namespace nearby { -namespace presence { -namespace { -using ::nearby::internal::IdentityType; - -constexpr IdentityType kTestIdentityType = - IdentityType::IDENTITY_TYPE_CONTACTS_GROUP; - -TEST(PresenceIdentityTest, ExplicitInitEquals) { - IdentityType identity1 = {kTestIdentityType}; - IdentityType identity2 = {kTestIdentityType}; - EXPECT_EQ(identity1, identity2); - EXPECT_EQ(identity1, kTestIdentityType); -} - - -TEST(PresenceIdentityTest, CopyInitEquals) { - IdentityType identity1 = {kTestIdentityType}; - IdentityType identity2 = {identity1}; - EXPECT_EQ(identity1, identity2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_service.h b/presence/presence_service.h deleted file mode 100644 index 8fe11637..00000000 --- a/presence/presence_service.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2020-2023 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_PRESENCE_PRESENCE_SERVICE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_SERVICE_H_ - -#include -#include - -#include "internal/interop/device_provider.h" -#include "internal/proto/metadata.pb.h" -#include "presence/data_types.h" -#include "presence/presence_client.h" - -namespace nearby { -namespace presence { - -class PresenceService { - public: - virtual ~PresenceService() = default; - - virtual std::unique_ptr CreatePresenceClient() = 0; - - virtual absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) = 0; - virtual void StopScan(ScanSessionId session_id) = 0; - - virtual absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) = 0; - - virtual void StopBroadcast(BroadcastSessionId session_id) = 0; - - virtual void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) = 0; - - virtual NearbyDeviceProvider* GetLocalDeviceProvider() = 0; - - virtual void GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) = 0; - - virtual void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) = 0; - - // Testing only. - virtual ::nearby::internal::DeviceIdentityMetaData - GetDeviceIdentityMetaData() = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_SERVICE_H_ diff --git a/presence/presence_service_impl.cc b/presence/presence_service_impl.cc deleted file mode 100644 index d107e618..00000000 --- a/presence/presence_service_impl.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2020 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. - -#include "presence/presence_service_impl.h" - -#include -#include -#include - -#include "internal/platform/borrowable.h" -#include "presence/data_types.h" -#include "presence/presence_client_impl.h" -#include "presence/presence_device_provider.h" - -namespace nearby { -namespace presence { - -std::unique_ptr PresenceServiceImpl::CreatePresenceClient() { - return PresenceClientImpl::Factory::Create(lender_.GetBorrowable()); -} - -absl::StatusOr PresenceServiceImpl::StartScan( - ScanRequest scan_request, ScanCallback callback) { - return service_controller_.StartScan(scan_request, std::move(callback)); -} - -void PresenceServiceImpl::StopScan(ScanSessionId id) { - service_controller_.StopScan(id); -} - -absl::StatusOr PresenceServiceImpl::StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) { - return service_controller_.StartBroadcast(broadcast_request, - std::move(callback)); -} - -void PresenceServiceImpl::StopBroadcast(BroadcastSessionId session) { - service_controller_.StopBroadcast(session); -} - -void PresenceServiceImpl::UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) { - provider_.UpdateDeviceIdentityMetaData(device_identity_metadata); - provider_.SetManagerAppId(manager_app_id); - service_controller_.UpdateDeviceIdentityMetaData( - device_identity_metadata, regen_credentials, manager_app_id, - identity_types, credential_life_cycle_days, - contiguous_copy_of_credentials, std::move(credentials_generated_cb)); -} - -void PresenceServiceImpl::GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) { - service_controller_.GetLocalPublicCredentials(credential_selector, - std::move(callback)); -} - -void PresenceServiceImpl::UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) { - service_controller_.UpdateRemotePublicCredentials( - manager_app_id, account_name, remote_public_creds, - std::move(credentials_updated_cb)); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/presence_service_impl.h b/presence/presence_service_impl.h deleted file mode 100644 index a8d5a219..00000000 --- a/presence/presence_service_impl.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2023 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_PRESENCE_PRESENCE_SERVICE_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_SERVICE_IMPL_H_ - -#include -#include - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/borrowable.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/metadata.pb.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/implementation/broadcast_manager.h" -#include "presence/implementation/connection_authenticator_impl.h" -#include "presence/implementation/credential_manager_impl.h" -#include "presence/implementation/mediums/mediums.h" -#include "presence/implementation/scan_manager.h" -#include "presence/implementation/service_controller_impl.h" -#include "presence/presence_client.h" -#include "presence/presence_device_provider.h" -#include "presence/presence_service.h" -#include "presence/scan_request.h" -#include "internal/interop/device_provider.h" - -namespace nearby { -namespace presence { - -/* - * PresenceService hosts presence functions by routing invokes to the unique - * {@code ServiceController}. PresenceService should be initialized once and - * only once in the process that hosting presence functions. - */ -class PresenceServiceImpl : public PresenceService { - public: - PresenceServiceImpl() = default; - ~PresenceServiceImpl() override { lender_.Release(); } - - std::unique_ptr CreatePresenceClient() override; - - absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) override; - void StopScan(ScanSessionId session_id) override; - - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) override; - - void StopBroadcast(BroadcastSessionId session_id) override; - - void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override; - - NearbyDeviceProvider* GetLocalDeviceProvider() override { - return &provider_; - } - - ::nearby::internal::DeviceIdentityMetaData GetDeviceIdentityMetaData() - override { - return service_controller_.GetDeviceIdentityMetaData(); - } - - void GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) override; - - void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) override; - - private: - SingleThreadExecutor executor_; - Mediums mediums_; - CredentialManagerImpl credential_manager_{&executor_}; - ScanManager scan_manager_{mediums_, credential_manager_, executor_}; - BroadcastManager broadcast_manager_{mediums_, credential_manager_, executor_}; - ServiceControllerImpl service_controller_{ - &executor_, &credential_manager_, &scan_manager_, &broadcast_manager_}; - ConnectionAuthenticatorImpl connection_authenticator_; - ::nearby::Lender lender_{this}; - PresenceDeviceProvider provider_{&service_controller_, - &connection_authenticator_}; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_SERVICE_IMPL_H_ diff --git a/presence/presence_service_test.cc b/presence/presence_service_test.cc deleted file mode 100644 index 1f24275b..00000000 --- a/presence/presence_service_test.cc +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2020 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. - -#include "presence/presence_service.h" - -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" -#include "presence/presence_client.h" -#include "presence/presence_service_impl.h" - -namespace nearby { -namespace presence { -namespace { -using DeviceIdentityMetaData = ::nearby::internal::DeviceIdentityMetaData; - -constexpr absl::string_view kManagerAppId = "TEST_MANAGER_APP"; -constexpr absl::string_view kAccountName = "dummy account"; - -class PresenceServiceTest : public testing::Test { - protected: - nearby::MediumEnvironment& env_{nearby::MediumEnvironment::Instance()}; -}; - -DeviceIdentityMetaData CreateTestDeviceIdentityMetaData() { - DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_device_type( - internal::DeviceType::DEVICE_TYPE_PHONE); - device_identity_metadata.set_device_name("NP test device"); - device_identity_metadata.set_bluetooth_mac_address( - "\xFF\xFF\xFF\xFF\xFF\xFF"); - device_identity_metadata.set_device_id("\x12\xab\xcd"); - return device_identity_metadata; -} - -CredentialSelector BuildDefaultCredentialSelector() { - CredentialSelector credential_selector; - credential_selector.manager_app_id = std::string(kManagerAppId); - credential_selector.account_name = std::string(kAccountName); - credential_selector.identity_type = internal::IDENTITY_TYPE_PRIVATE_GROUP; - return credential_selector; -} - -TEST_F(PresenceServiceTest, DefaultConstructorWorks) { - PresenceServiceImpl presence_service; -} - -TEST_F(PresenceServiceTest, StartThenStopScan) { - env_.Start(); - absl::Status scan_result; - ScanCallback scan_callback = { - .start_scan_cb = [&](absl::Status status) { scan_result = status; }, - }; - PresenceServiceImpl presence_service; - std::unique_ptr client = - presence_service.CreatePresenceClient(); - - absl::StatusOr scan_session = client->StartScan( - {}, - { - .start_scan_cb = [&](absl::Status status) { scan_result = status; }, - }); - absl::StatusOr scan_session_with_default_params = - client->StartScan(ScanRequest(), ScanCallback()); - - ASSERT_OK(scan_session); - ASSERT_OK(scan_session_with_default_params); - EXPECT_NE(*scan_session, *scan_session_with_default_params); - - client->StopScan(*scan_session); - client->StopScan(*scan_session_with_default_params); - env_.Stop(); -} - -TEST_F(PresenceServiceTest, UpdatingDeviceIdentityMetaDataWorks) { - PresenceServiceImpl presence_service; - presence_service.UpdateDeviceIdentityMetaData( - CreateTestDeviceIdentityMetaData(), false, "Test app", {}, 3, 1, {}); - EXPECT_EQ(presence_service.GetDeviceIdentityMetaData().SerializeAsString(), - CreateTestDeviceIdentityMetaData().SerializeAsString()); -} - -TEST_F(PresenceServiceTest, TestGetDeviceProvider) { - PresenceServiceImpl presence_service; - EXPECT_NE(presence_service.GetLocalDeviceProvider(), nullptr); -} - -TEST_F(PresenceServiceTest, TestGetPublicCredentials) { - PresenceServiceImpl presence_service; - CredentialSelector selector = BuildDefaultCredentialSelector(); - absl::Status status; - nearby::CountDownLatch fetched_latch(1); - presence_service.GetLocalPublicCredentials( - selector, - {.credentials_fetched_cb = - [&status, &fetched_latch]( - absl::StatusOr> - result) { - status = result.status(); - fetched_latch.CountDown(); - }}); - EXPECT_TRUE(fetched_latch.Await().Ok()); - EXPECT_THAT(status, testing::status::StatusIs(absl::StatusCode::kNotFound)); -} - -TEST_F(PresenceServiceTest, TestUpdateRemotePublicCredentials) { - PresenceServiceImpl presence_service; - internal::SharedCredential public_credential_for_test; - public_credential_for_test.set_identity_type( - internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP); - std::vector public_credentials{ - {public_credential_for_test}}; - - nearby::CountDownLatch updated_latch(1); - UpdateRemotePublicCredentialsCallback update_credentials_cb{ - .credentials_updated_cb = - [&updated_latch](absl::Status status) { - if (status.ok()) { - updated_latch.CountDown(); - } - }, - }; - - presence_service.UpdateRemotePublicCredentials( - kManagerAppId, kAccountName, public_credentials, - std::move(update_credentials_cb)); - - EXPECT_TRUE(updated_latch.Await().Ok()); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_zone.cc b/presence/presence_zone.cc deleted file mode 100644 index 2fcdad45..00000000 --- a/presence/presence_zone.cc +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2020 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. - -#include "presence/presence_zone.h" - -namespace nearby { -namespace presence { - -PresenceZone::DistanceBoundary::DistanceBoundary(float min_distance_meters, - float max_distance_meters, - RangeType range_type) noexcept - : min_distance_meters_(min_distance_meters), - max_distance_meters_(max_distance_meters), - range_type_(range_type) {} - -float PresenceZone::DistanceBoundary::GetMinDistanceMeters() const { - return min_distance_meters_; -} - -float PresenceZone::DistanceBoundary::GetMaxDistanceMeters() const { - return max_distance_meters_; -} - -PresenceZone::DistanceBoundary::RangeType -PresenceZone::DistanceBoundary::GetRangeType() const { - return range_type_; -} - -PresenceZone::AngleOfArrivalBoundary::AngleOfArrivalBoundary( - float min_angle_degrees, float max_angle_degrees) noexcept - : min_angle_degrees_(min_angle_degrees), - max_angle_degrees_(max_angle_degrees) {} - -float PresenceZone::AngleOfArrivalBoundary::GetMinAngleDegrees() const { - return min_angle_degrees_; -} - -float PresenceZone::AngleOfArrivalBoundary::GetMaxAngleDegrees() const { - return max_angle_degrees_; -} - -PresenceZone::PresenceZone( - const DistanceBoundary& distance_boundary, - const AngleOfArrivalBoundary& azimuth_angle_boundary, - const AngleOfArrivalBoundary& elevation_angle_boundary, - const std::vector& device_motions) - : distance_boundary_(distance_boundary), - azimuth_angle_boundary_(azimuth_angle_boundary), - elevation_angle_boundary_(elevation_angle_boundary), - device_motions_(device_motions) {} - -PresenceZone::DistanceBoundary PresenceZone::GetDistanceBoundary() const { - return distance_boundary_; -} - -PresenceZone::AngleOfArrivalBoundary PresenceZone::GetAzimuthAngleBoundary() - const { - return azimuth_angle_boundary_; -} - -PresenceZone::AngleOfArrivalBoundary PresenceZone::GetElevationAngleBoundary() - const { - return elevation_angle_boundary_; -} - -std::vector PresenceZone::GetLocalDeviceMotions() const { - return device_motions_; -} - -} // namespace presence -} // namespace nearby diff --git a/presence/presence_zone.h b/presence/presence_zone.h deleted file mode 100644 index c2883100..00000000 --- a/presence/presence_zone.h +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2020 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_PRESENCE_PRESENCE_ZONE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_ZONE_H_ - -#include - -#include "presence/device_motion.h" -namespace nearby { -namespace presence { -class PresenceZone { - public: - class DistanceBoundary { - public: - enum class RangeType { - kRangeUnknown = 0, - kFar, // Distance is very far away from the peer device. - kWithinReach, // Distance is very close to the peer device, typically - // within one meter or less. - kWithinTap, // Distance is within tap range to the peer device, typically - // within ~0.127 meters. - }; - DistanceBoundary(float min_distance_meters = 0, - float max_distance_meters = 0, - RangeType range_type = RangeType::kRangeUnknown) noexcept; - float GetMinDistanceMeters() const; - float GetMaxDistanceMeters() const; - RangeType GetRangeType() const; - - private: - const float min_distance_meters_; - const float max_distance_meters_; - const RangeType range_type_; - }; - - class AngleOfArrivalBoundary { - public: - AngleOfArrivalBoundary(float min_angle_degrees = 0, - float max_angle_degrees = 0) noexcept; - float GetMinAngleDegrees() const; - float GetMaxAngleDegrees() const; - - private: - const float min_angle_degrees_; - const float max_angle_degrees_; - }; - - PresenceZone(const DistanceBoundary& = {}, const AngleOfArrivalBoundary& = {}, - const AngleOfArrivalBoundary& = {}, - const std::vector& = {}); - DistanceBoundary GetDistanceBoundary() const; - AngleOfArrivalBoundary GetAzimuthAngleBoundary() const; - AngleOfArrivalBoundary GetElevationAngleBoundary() const; - std::vector GetLocalDeviceMotions() const; - - private: - const DistanceBoundary distance_boundary_; - const AngleOfArrivalBoundary azimuth_angle_boundary_; - const AngleOfArrivalBoundary elevation_angle_boundary_; - const std::vector device_motions_; -}; - -inline bool operator==(const PresenceZone::DistanceBoundary& d1, - const PresenceZone::DistanceBoundary& d2) { - return d1.GetMinDistanceMeters() == d2.GetMinDistanceMeters() && - d1.GetMaxDistanceMeters() == d2.GetMaxDistanceMeters() && - d1.GetRangeType() == d2.GetRangeType(); -} -inline bool operator!=(const PresenceZone::DistanceBoundary& d1, - const PresenceZone::DistanceBoundary& d2) { - return !(d1 == d2); -} -inline bool operator==(const PresenceZone::AngleOfArrivalBoundary& a1, - const PresenceZone::AngleOfArrivalBoundary& a2) { - return a1.GetMinAngleDegrees() == a2.GetMinAngleDegrees() && - a1.GetMaxAngleDegrees() == a2.GetMaxAngleDegrees(); -} -inline bool operator!=(const PresenceZone::AngleOfArrivalBoundary& a1, - const PresenceZone::AngleOfArrivalBoundary& a2) { - return !(a1 == a2); -} - -inline bool operator==(const PresenceZone& z1, const PresenceZone& z2) { - return z1.GetDistanceBoundary() == z2.GetDistanceBoundary() && - z1.GetAzimuthAngleBoundary() == z2.GetAzimuthAngleBoundary() && - z1.GetElevationAngleBoundary() == z2.GetElevationAngleBoundary() && - z1.GetLocalDeviceMotions() == z2.GetLocalDeviceMotions(); -} -inline bool operator!=(const PresenceZone& z1, const PresenceZone& z2) { - return !(z1 == z2); -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_ZONE_H_ diff --git a/presence/presence_zone_test.cc b/presence/presence_zone_test.cc deleted file mode 100644 index e813bf48..00000000 --- a/presence/presence_zone_test.cc +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2020 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. - -#include "presence/presence_zone.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "presence/device_motion.h" - -namespace nearby { -namespace presence { -namespace { - -using DistanceBoundary = nearby::presence::PresenceZone::DistanceBoundary; -using RangeType = nearby::presence::PresenceZone::DistanceBoundary::RangeType; -using AngleOfArrivalBoundary = - nearby::presence::PresenceZone::AngleOfArrivalBoundary; - -static const float kDefaultDistanceMeters = 0; -static const float kTestMinDistanceMeters = 1; -static const float kTestMaxDistanceMeters = 2; - -static const float kDefaultDegrees = 0; -static const float kTestMinAngleDegrees = 10; -static const float kTestMaxAngleDegrees = 20; - -static const float kTestConfidence = 0.1; - -static const RangeType kDefaultRangeType = RangeType::kRangeUnknown; -static const RangeType kTestRangeType = RangeType::kFar; - -static const DistanceBoundary kDefaultDistanceBoundary; -static const DistanceBoundary kTestDistanceBoundary = { - kTestMinDistanceMeters, kTestMaxDistanceMeters, kTestRangeType}; -static const AngleOfArrivalBoundary kDefaultAngleBoundary; -static const AngleOfArrivalBoundary kTestAzimuthAngleBoundary = { - kTestMinAngleDegrees, kTestMaxAngleDegrees}; -static const AngleOfArrivalBoundary kTestElevationAngleBoundary = { - kTestMinAngleDegrees, kTestMaxAngleDegrees}; -static const DeviceMotion kTestDeviceMotion = { - DeviceMotion::MotionType::kPointAndHold, kTestConfidence}; - -TEST(DistanceBoundaryTest, DefaultConstructorWorks) { - DistanceBoundary boundary; - EXPECT_EQ(boundary.GetMinDistanceMeters(), kDefaultDistanceMeters); - EXPECT_EQ(boundary.GetMaxDistanceMeters(), kDefaultDistanceMeters); - EXPECT_EQ(boundary.GetRangeType(), kDefaultRangeType); -} - -TEST(DistanceBoundaryTest, DefaultEquals) { - DistanceBoundary boundary1; - DistanceBoundary boundary2; - EXPECT_EQ(boundary1, boundary2); -} - -TEST(DistanceBoundaryTest, PartiallyInitializationWorks) { - DistanceBoundary boundary1 = {kTestMinDistanceMeters, kTestMaxDistanceMeters}; - DistanceBoundary boundary2 = {kTestMinDistanceMeters}; - EXPECT_EQ(boundary1.GetMinDistanceMeters(), kTestMinDistanceMeters); - EXPECT_EQ(boundary1.GetMaxDistanceMeters(), kTestMaxDistanceMeters); - EXPECT_EQ(boundary1.GetRangeType(), kDefaultRangeType); - EXPECT_EQ(boundary2.GetMinDistanceMeters(), kTestMinDistanceMeters); - EXPECT_EQ(boundary2.GetMaxDistanceMeters(), kDefaultDistanceMeters); - EXPECT_EQ(boundary2.GetRangeType(), kDefaultRangeType); -} - -TEST(DistanceBoundaryTest, ExplicitInitEquals) { - DistanceBoundary boundary1 = {kTestMinDistanceMeters, kTestMaxDistanceMeters, - kTestRangeType}; - DistanceBoundary boundary2 = {kTestMinDistanceMeters, kTestMaxDistanceMeters, - kTestRangeType}; - EXPECT_EQ(boundary1.GetMinDistanceMeters(), kTestMinDistanceMeters); - EXPECT_EQ(boundary1.GetMaxDistanceMeters(), kTestMaxDistanceMeters); - EXPECT_EQ(boundary1.GetRangeType(), kTestRangeType); - EXPECT_EQ(boundary1, boundary2); -} - -TEST(DistanceBoundaryTest, ExplicitInitNotEquals) { - DistanceBoundary boundary1 = {kTestMinDistanceMeters, kTestMaxDistanceMeters, - kTestRangeType}; - DistanceBoundary boundary2 = {kTestMinDistanceMeters + 0.1f, - kTestMaxDistanceMeters, kTestRangeType}; - EXPECT_NE(boundary1, boundary2); -} - -TEST(DistanceBoundaryTest, CopyInitEquals) { - DistanceBoundary boundary1 = {kTestMinDistanceMeters, kTestMaxDistanceMeters, - kTestRangeType}; - DistanceBoundary boundary2 = {boundary1}; - EXPECT_EQ(boundary1, boundary2); -} - -TEST(AngleOfArrivalBoundaryTest, DefaultConstructorWorks) { - AngleOfArrivalBoundary aoa_boundary; - EXPECT_EQ(aoa_boundary.GetMinAngleDegrees(), kDefaultDegrees); - EXPECT_EQ(aoa_boundary.GetMaxAngleDegrees(), kDefaultDegrees); -} - -TEST(AngleOfArrivalBoundaryTest, DefaultEquals) { - AngleOfArrivalBoundary aoa_boundary1; - AngleOfArrivalBoundary aoa_boundary2; - EXPECT_EQ(aoa_boundary1, aoa_boundary2); -} - -TEST(AngleOfArrivalBoundaryTest, PartiallyInitializationWorks) { - AngleOfArrivalBoundary aoa_boundary = {kTestMinAngleDegrees}; - EXPECT_EQ(aoa_boundary.GetMinAngleDegrees(), kTestMinAngleDegrees); - EXPECT_EQ(aoa_boundary.GetMaxAngleDegrees(), kDefaultDegrees); -} - -TEST(AngleOfArrivalBoundaryTest, ExplicitInitEquals) { - AngleOfArrivalBoundary aoa_boundary1 = {kTestMinAngleDegrees, - kTestMaxAngleDegrees}; - AngleOfArrivalBoundary aoa_boundary2 = {kTestMinAngleDegrees, - kTestMaxAngleDegrees}; - EXPECT_EQ(aoa_boundary1.GetMinAngleDegrees(), kTestMinAngleDegrees); - EXPECT_EQ(aoa_boundary1.GetMaxAngleDegrees(), kTestMaxAngleDegrees); - EXPECT_EQ(aoa_boundary1, aoa_boundary2); -} - -TEST(AngleOfArrivalBoundaryTest, ExplicitInitNotEquals) { - AngleOfArrivalBoundary aoa_boundary1 = {kTestMinAngleDegrees, - kTestMaxAngleDegrees}; - AngleOfArrivalBoundary aoa_boundary2 = {kTestMinAngleDegrees, - kTestMaxAngleDegrees + 0.1f}; - EXPECT_NE(aoa_boundary1, aoa_boundary2); -} - -TEST(AngleOfArrivalBoundaryTest, CopyInitEquals) { - AngleOfArrivalBoundary aoa_boundary1 = {kTestMinAngleDegrees, - kTestMaxAngleDegrees}; - AngleOfArrivalBoundary aoa_boundary2 = {aoa_boundary1}; - EXPECT_EQ(aoa_boundary1, aoa_boundary2); -} - -TEST(PresenceZoneTest, DefaultConstructorWorks) { - PresenceZone zone; - EXPECT_EQ(zone.GetDistanceBoundary(), kDefaultDistanceBoundary); - EXPECT_EQ(zone.GetAzimuthAngleBoundary(), kDefaultAngleBoundary); - EXPECT_EQ(zone.GetElevationAngleBoundary(), kDefaultAngleBoundary); - EXPECT_EQ(zone.GetLocalDeviceMotions().capacity(), 0); -} - -TEST(PresenceZoneTest, DefaultEquals) { - PresenceZone zone1; - PresenceZone zone2; - EXPECT_EQ(zone1, zone2); -} - -TEST(PresenceZoneTest, PartiallyInitializationWorks) { - PresenceZone zone1 = {kTestDistanceBoundary, kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary}; - PresenceZone zone2 = {kTestDistanceBoundary, kTestAzimuthAngleBoundary}; - PresenceZone zone3 = {kTestDistanceBoundary}; - EXPECT_EQ(zone1.GetDistanceBoundary(), kTestDistanceBoundary); - EXPECT_EQ(zone1.GetAzimuthAngleBoundary(), kTestAzimuthAngleBoundary); - EXPECT_EQ(zone1.GetElevationAngleBoundary(), kTestElevationAngleBoundary); - EXPECT_EQ(zone1.GetLocalDeviceMotions().capacity(), 0); - EXPECT_EQ(zone2.GetDistanceBoundary(), kTestDistanceBoundary); - EXPECT_EQ(zone2.GetAzimuthAngleBoundary(), kTestAzimuthAngleBoundary); - EXPECT_EQ(zone2.GetElevationAngleBoundary(), kDefaultAngleBoundary); - EXPECT_EQ(zone2.GetLocalDeviceMotions().capacity(), 0); - EXPECT_EQ(zone3.GetDistanceBoundary(), kTestDistanceBoundary); - EXPECT_EQ(zone3.GetAzimuthAngleBoundary(), kDefaultAngleBoundary); - EXPECT_EQ(zone3.GetElevationAngleBoundary(), kDefaultAngleBoundary); - EXPECT_EQ(zone3.GetLocalDeviceMotions().capacity(), 0); -} - -TEST(PresenceZoneTest, ExplicitInitEquals) { - PresenceZone zone1 = {kTestDistanceBoundary, - kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary, - {kTestDeviceMotion}}; - PresenceZone zone2 = {kTestDistanceBoundary, - kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary, - {kTestDeviceMotion}}; - EXPECT_EQ(zone1.GetDistanceBoundary(), kTestDistanceBoundary); - EXPECT_EQ(zone1.GetAzimuthAngleBoundary(), kTestAzimuthAngleBoundary); - EXPECT_EQ(zone1.GetElevationAngleBoundary(), kTestElevationAngleBoundary); - EXPECT_EQ(zone1.GetLocalDeviceMotions().size(), 1); - EXPECT_EQ(zone1.GetLocalDeviceMotions()[0], kTestDeviceMotion); - EXPECT_EQ(zone1, zone2); -} - -TEST(PresenceZoneTest, ExplicitInitNotEquals) { - PresenceZone zone1 = {kTestDistanceBoundary, - kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary, - {kTestDeviceMotion}}; - PresenceZone zone2 = {kTestDistanceBoundary, - kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary, - {}}; - EXPECT_NE(zone1, zone2); -} - -TEST(PresenceZoneTest, CopyInitEquals) { - PresenceZone zone1 = {kTestDistanceBoundary, - kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary, - {kTestDeviceMotion}}; - PresenceZone zone2 = {zone1}; - EXPECT_EQ(zone1, zone2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/proto/BUILD b/presence/proto/BUILD deleted file mode 100644 index 6351491c..00000000 --- a/presence/proto/BUILD +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2022 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. - -load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library") -load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") - -proto_library( - name = "presence_frame_proto", - srcs = ["presence_frame.proto"], -) - -cc_proto_library( - name = "presence_frame_cc_proto", - visibility = [ - "//presence:__subpackages__", - ], - deps = [":presence_frame_proto"], -) diff --git a/presence/proto/presence_frame.proto b/presence/proto/presence_frame.proto deleted file mode 100644 index 1f18cbcd..00000000 --- a/presence/proto/presence_frame.proto +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2023 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. - -syntax = "proto2"; - -package nearby.presence; - -// import "storage/datapol/annotations/proto/semantic_annotations.proto"; - -option optimize_for = LITE_RUNTIME; -option java_package = "com.google.android.gms.nearby.presence"; -option java_outer_classname = "PresenceFrameProtocol"; - -/** - * Nearby Presence’s wire frame format - */ -message PresenceFrame { - /** The version of the frame. */ - enum Version { - UNKNOWN_VERSION = 0; - VERSION_1 = 1; - } - - /** The version 1 frame for Nearby Presence. */ - optional V1Frame v1_frame = 1; -} - -/** - * Nearby Presence’s v1 wire frame format - */ -message V1Frame { - oneof Message { - // Control messages for connection status update. - ControlFrame control_frame = 1; - - // This frame will be shared by public and provisioned identities - DeviceIdentityFrame device_identity_frame = 2; - - // First message from discovery device to broadcaster. - ConnectionInitFrame connection_init_frame = 3; - - // Sent by broadcaster to notify discoverer its UWB capability. - UwbControleeCapabilities uwb_controlee_capabilities_frame = 4; - - // Sent by discoverer to notify broadcaster the UWB ranging parameters. - UwbConnectionInfo uwb_connection_info = 5; - - // Used for identity authentication. - PresenceAuthenticationFrame authentication_frame = 6; - } -} - -/** - * A frame contains the local device’s information, shared by public and - * provisioned identities. - */ -message DeviceIdentityFrame { - optional string device_name = 1; - - // Without this field, the device will not be connectable. - optional bytes bluetooth_mac_address = 2; // deprecated - - optional string device_image_url = 3; - - optional string model_id = 4; - - repeated int32 action = 5 [packed = true]; // deprecated - - optional string device_model_name = 6; - - optional int32 device_type = 7; -} - -/** - * A frame sent from discovery device to broadcast device when connection - * initialized, or when UWB needs to be restarted, or when dedup hint rotates. - */ -message ConnectionInitFrame { - // Discovery-side action list - repeated int32 actions = 1 [packed = true]; - - // Discovery-side identity type - optional int32 identity_type = 2; - - // Should the broadcaster (re)-start UWB OOB process or not. - optional bool uwb_enable = 3; - - // Used for device de-duplicate. Same device ID means the same physical - // device. When dedup hint rotates, this will be updated and send again. - optional int64 device_unique_id = 4; -} - -/** - * A frame that describes the controlee's UWB capabilities. - */ -message UwbControleeCapabilities { - optional bytes controlee_address = 1; - - repeated int32 supported_config_ids = 2 [packed = true]; - - repeated int32 supported_channels = 3 [packed = true]; - - optional int32 min_ranging_interval_ms = 4; - - optional bytes sub_session_id = 5 /* type = ST_SESSION_ID */; - - optional bytes sub_session_key = 6 - /* type = ST_SECURITY_MATERIAL */; - - optional bool ranging_disabled = 7; - - // Used for device de-duplicate. Same device ID means the same physical - // device. - optional int64 device_unique_id = 8; - - optional bool is_distance_supported = 9 [default = true]; - optional bool is_azimuth_supported = 10 [default = true]; - optional bool is_elevation_supported = 11 [default = false]; - optional float min_slot_duration_ms = 12 [default = 2.0]; - repeated int32 supported_ntf_configs = 13 [packed = true]; - optional bool is_ranging_interval_reconfigure_supported = 14 - [default = false]; - repeated int32 supported_slot_durations = 15 [packed = true]; - repeated int32 supported_ranging_update_rates = 16 [packed = true]; - optional int32 chip_count = 17 [default = 1]; - repeated UwbMultiChipInfo multi_chip_info = 18; - optional bool is_background_ranging_supported = 19 [default = false]; -} - -/* A frame containing info needed per chip in a multi-chip environment. */ -message UwbMultiChipInfo { - optional bytes controlee_address = 1; - optional string chip_id = 2; -} - -/** - * A frame that describes the connection info of the UWB ranging session. - */ -message UwbConnectionInfo { - optional bytes controller_address = 1; - - optional int32 channel = 2; - - optional int32 preamble_index = 3; - - optional int32 config_id = 4; - - optional int32 ranging_interval_ms = 5; - - optional int32 session_id = 6 /* type = ST_SESSION_ID */; - - optional bytes vendor_id = 7; - - optional bytes static_sts_iv = 8; - - optional bytes session_key = 9 - /* type = ST_SECURITY_MATERIAL */; - - optional bool ranging_disabled = 10; -} - -/** - * Control frames that used for connection status update. - */ -message ControlFrame { - /** The defined Control type of the frame. */ - enum ControlType { - UNKNOWN_TYPE = 0; - - // Keeps the connection alive. - KEEP_ALIVE = 1; - - // Notifies the peer that the connection will be closed immediately. - DISCONNECT = 2; - } - - optional ControlType type = 1; -} - -message PresenceAuthenticationFrame { - // The version of this frame and protocol. - optional int32 version = 1; - - // A signature signed by the private key in the LocalCredential. - optional bytes private_key_signature = 2; - - // A hash of a shared credential's id. Used to prove ownership of shared - // credentials used in discovery. - optional bytes shared_credential_id_hash = 3; - - // A hash of a local credential's id. Used to expedite local credential - // verification. - optional bytes credential_id_hash = 4 [deprecated = true]; -} diff --git a/presence/rust/README b/presence/rust/README deleted file mode 100644 index 9ca03064..00000000 --- a/presence/rust/README +++ /dev/null @@ -1 +0,0 @@ -This directory contains Rust implementation of Nearby Presence. diff --git a/presence/scan_request.h b/presence/scan_request.h deleted file mode 100644 index 69aaad01..00000000 --- a/presence/scan_request.h +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2020 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_PRESENCE_SCAN_REQUEST_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_SCAN_REQUEST_H_ - -#include -#include - -#include "absl/types/variant.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/power_mode.h" - -namespace nearby { -namespace presence { - -constexpr char kPresenceScanFilterName[] = "PresenceScanFilter"; -constexpr char kLegacyPresenceScanFilterName[] = "LegacyPresenceScanFilter"; - -enum class ScanType { - kUnspecifiedScan = 0, - kFastPairScan = 1, - kPresenceScan = 2, -}; - -/** - * Filter for scanning a nearby presence device. - * Supports Android U and above. - */ -struct PresenceScanFilter { - ScanType scan_type; - // A bundle of extended properties for matching. - std::vector extended_properties; -}; - -/** - * Used to support legacy Android T. Filter for scanning a nearby presence - * device. - */ -struct LegacyPresenceScanFilter { - ScanType scan_type; - // Minimum path loss threshold of the received scan result. - int path_loss_threshold; - - // Android T needs clients to provide remote public credentials in scan - // requests. - std::vector remote_public_credentials; - - // A list of presence actions for matching. Matching condition is met as - // long as there’s one or more equal actions between Scan actions and - // Broadcast actions. - // Considered to use enum, and team agreed to use int to support potential - // un-reserved values. Already existing reserved interger values are defined - // in {@code ActionFactory}. - std::vector actions; - - // A bundle of extended properties for matching. - std::vector extended_properties; -}; - -inline bool operator==(const PresenceScanFilter& a, - const PresenceScanFilter& b) { - return a.scan_type == b.scan_type && - a.extended_properties == b.extended_properties; -} - -inline bool operator!=(const PresenceScanFilter& a, - const PresenceScanFilter& b) { - return !(a == b); -} - -inline bool operator==(const LegacyPresenceScanFilter& a, - const LegacyPresenceScanFilter& b) { - if (a.scan_type != b.scan_type || - a.path_loss_threshold != b.path_loss_threshold || - a.actions != b.actions || - a.remote_public_credentials.size() != - b.remote_public_credentials.size() || - a.extended_properties != b.extended_properties) - return false; - for (size_t i = 0; i < a.remote_public_credentials.size(); ++i) { - if (a.remote_public_credentials[i].SerializeAsString() != - b.remote_public_credentials[i].SerializeAsString()) - return false; - } - return true; -} - -inline bool operator!=(const LegacyPresenceScanFilter& a, - const LegacyPresenceScanFilter& b) { - return !(a == b); -} - -/** - * An encapsulation of various parameters for requesting nearby scans. - */ -struct ScanRequest { - // Same as Metadata.account_name, to fetch private credential - // to broadcast. - std::string account_name; - - // Specifies which manager app to use to get credendentials for scan. - std::string manager_app_id; - - // Used to specify which types of remote SharedCredential to use during the - // scan. If empty, use all available types of remote SharedCredential. - std::vector identity_types; - - // For new Nearby SDK client (like chromeOs and Android U), use - // PresenceScanFilter; for Android T, use LegacyPresenceScanFilter. - std::vector > - scan_filters; - - // Whether to use BLE in the scan. - bool use_ble = false; - - ScanType scan_type = ScanType::kUnspecifiedScan; - PowerMode power_mode = PowerMode::kNoPower; - bool scan_only_when_screen_on = false; -}; - -inline bool operator==(const ScanRequest& a, const ScanRequest& b) { - if (a.identity_types != b.identity_types) return false; - if (a.scan_filters != b.scan_filters) return false; - return a.scan_only_when_screen_on == b.scan_only_when_screen_on && - a.power_mode == b.power_mode && a.scan_type == b.scan_type && - a.use_ble == b.use_ble && a.account_name == b.account_name && - a.identity_types == b.identity_types && - a.manager_app_id == b.manager_app_id; -} - -inline bool operator!=(const ScanRequest& a, const ScanRequest& b) { - return !(a == b); -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_SCAN_REQUEST_H_ diff --git a/presence/scan_request_builder.cc b/presence/scan_request_builder.cc deleted file mode 100644 index 2d9b5740..00000000 --- a/presence/scan_request_builder.cc +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2020 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. -#include "presence/scan_request_builder.h" - -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/types/variant.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -using ::nearby::internal::IdentityType; - -ScanRequestBuilder& ScanRequestBuilder::SetAccountName( - absl::string_view account_name) { - request_.account_name = std::string(account_name); - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetPowerMode(PowerMode power_mode) { - request_.power_mode = power_mode; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetScanType(ScanType scan_type) { - request_.scan_type = scan_type; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::AddIdentityType( - IdentityType identity_type) { - request_.identity_types.push_back(identity_type); - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetIdentityTypes( - std::vector types) { - request_.identity_types = types; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::AddScanFilter( - absl::variant scan_filter) { - request_.scan_filters.push_back(scan_filter); - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetScanFilters( - std::vector> - filters) { - request_.scan_filters = filters; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetUseBle(bool use_ble) { - request_.use_ble = use_ble; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetOnlyScreenOnScan( - bool screen_on_only_scan) { - request_.scan_only_when_screen_on = screen_on_only_scan; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetManagerAppId( - absl::string_view manager_app_id) { - request_.manager_app_id = std::string(manager_app_id); - return *this; -} - -ScanRequest ScanRequestBuilder::Build() { return this->request_; } - -} // namespace presence -} // namespace nearby diff --git a/presence/scan_request_builder.h b/presence/scan_request_builder.h deleted file mode 100644 index 80bf770d..00000000 --- a/presence/scan_request_builder.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2020 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_PRESENCE_SCAN_REQUEST_BUILDER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_SCAN_REQUEST_BUILDER_H_ - -#include - -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "presence/power_mode.h" -#include "presence/presence_zone.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { -class ScanRequestBuilder { - private: - ScanRequest request_; - - public: - ScanRequestBuilder& SetAccountName(absl::string_view account_name); - ScanRequestBuilder& SetPowerMode(PowerMode power_mode); - ScanRequestBuilder& SetScanType(ScanType scan_type); - ScanRequestBuilder& AddIdentityType( - nearby::internal::IdentityType identity_type); - ScanRequestBuilder& SetIdentityTypes( - std::vector types); - ScanRequestBuilder& AddScanFilter( - absl::variant scan_filter); - ScanRequestBuilder& SetScanFilters( - std::vector> - scan_filters); - ScanRequestBuilder& SetUseBle(bool use_ble); - ScanRequestBuilder& SetOnlyScreenOnScan(bool screen_on_only_scan); - ScanRequestBuilder& SetManagerAppId(absl::string_view manager_app_id); - ScanRequest Build(); - inline bool operator==(const ScanRequestBuilder& other) const { - return request_ == other.request_; - } -}; -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_SCAN_REQUEST_BUILDER_H_ diff --git a/presence/scan_request_builder_test.cc b/presence/scan_request_builder_test.cc deleted file mode 100644 index 1d0fd6be..00000000 --- a/presence/scan_request_builder_test.cc +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2020 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. - -#include "presence/scan_request_builder.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "presence/power_mode.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::internal::IdentityType; - -constexpr absl::string_view kAccountName = "Google User"; -constexpr bool kUseBle = true; -constexpr bool kOnlyScreenOnScan = true; -const IdentityType kIdentity = IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; -const ScanType kScanType = ScanType::kPresenceScan; -const PowerMode powerMode = PowerMode::kLowLatency; -constexpr absl::string_view kManagerAppId = "Google App Manager"; -DataElement CreateTestDataElement() { - return {DataElement::kTxPowerFieldType, "1"}; -} -PresenceScanFilter CreateTestPresenceScanFilter() { - return {.scan_type = kScanType, - .extended_properties = {CreateTestDataElement()}}; -} -LegacyPresenceScanFilter CreateTestLegacyPresenceScanFilter() { - return {.scan_type = kScanType}; -} - -TEST(ScanRequestBuilderTest, TestConstructor) { - EXPECT_FALSE(std::is_trivially_constructible::value); -} - -TEST(ScanRequestBuilderTest, TestSetAccountName) { - ScanRequestBuilder builder; - builder.SetAccountName(kAccountName); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.account_name, kAccountName); -} - -TEST(ScanRequestBuilderTest, TestSetPowerMode) { - ScanRequestBuilder builder; - builder.SetPowerMode(powerMode); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.power_mode, powerMode); -} - -TEST(ScanRequestBuilderTest, TestSetScanType) { - ScanRequestBuilder builder; - builder.SetScanType(kScanType); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.scan_type, kScanType); -} - -TEST(ScanRequestBuilderTest, TestAddIdentityType) { - ScanRequestBuilder builder; - builder.AddIdentityType(kIdentity); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.identity_types.size(), 1); - EXPECT_EQ(sr.identity_types[0], kIdentity); -} - -TEST(ScanRequestBuilderTest, TestSetIdentityTypes) { - ScanRequestBuilder builder; - std::vector types = {kIdentity}; - builder.SetIdentityTypes(types); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.identity_types.size(), 1); - EXPECT_EQ(sr.identity_types, types); -} - -TEST(ScanRequestBuilderTest, TestAddScanFilter) { - ScanRequestBuilder builder; - PresenceScanFilter presenceScanFilter = CreateTestPresenceScanFilter(); - LegacyPresenceScanFilter legacyPresenceScanFilter = - CreateTestLegacyPresenceScanFilter(); - builder.AddScanFilter(presenceScanFilter); - builder.AddScanFilter(legacyPresenceScanFilter); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.scan_filters.size(), 2); - EXPECT_TRUE(absl::holds_alternative(sr.scan_filters[0])); - EXPECT_NE(&absl::get(sr.scan_filters[0]), - &presenceScanFilter); - EXPECT_EQ(absl::get(sr.scan_filters[0]), - presenceScanFilter); - EXPECT_TRUE( - absl::holds_alternative(sr.scan_filters[1])); - EXPECT_NE(&absl::get(sr.scan_filters[1]), - &legacyPresenceScanFilter); - EXPECT_EQ(absl::get(sr.scan_filters[1]), - legacyPresenceScanFilter); -} - -TEST(ScanRequestBuilderTest, TestSetScanFilters) { - PresenceScanFilter presenceScanFilter = CreateTestPresenceScanFilter(); - LegacyPresenceScanFilter legacyPresenceScanFilter = - CreateTestLegacyPresenceScanFilter(); - std::vector> - filterList = {presenceScanFilter, legacyPresenceScanFilter}; - ScanRequestBuilder builder; - builder.SetScanFilters(filterList); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.scan_filters.size(), 2); - EXPECT_TRUE(absl::holds_alternative(sr.scan_filters[0])); - EXPECT_NE(&absl::get(sr.scan_filters[0]), - &presenceScanFilter); - EXPECT_EQ(absl::get(sr.scan_filters[0]), - presenceScanFilter); - EXPECT_TRUE( - absl::holds_alternative(sr.scan_filters[1])); - EXPECT_NE(&absl::get(sr.scan_filters[1]), - &legacyPresenceScanFilter); - EXPECT_EQ(absl::get(sr.scan_filters[1]), - legacyPresenceScanFilter); -} - -TEST(ScanRequestBuilderTest, TestNotEqualScanFilter) { - ScanRequestBuilder builderLegacy, builderModern; - ScanRequest legacy = - builderLegacy.AddScanFilter(LegacyPresenceScanFilter{}).Build(); - ScanRequest modern = - builderModern.AddScanFilter(PresenceScanFilter{}).Build(); - EXPECT_NE(legacy, modern); -} - -TEST(ScanRequestBuilderTest, TestSetUseBle) { - ScanRequestBuilder builder; - builder.SetUseBle(kUseBle); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.use_ble, kUseBle); -} - -TEST(ScanRequestBuilderTest, TestSetManagerAppId) { - ScanRequestBuilder builder; - builder.SetManagerAppId(kManagerAppId); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.manager_app_id, kManagerAppId); -} - -TEST(ScanRequestBuilderTest, TestSetOnlyScreenOnScan) { - ScanRequestBuilder builder; - builder.SetOnlyScreenOnScan(kOnlyScreenOnScan); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.scan_only_when_screen_on, kOnlyScreenOnScan); -} - -TEST(ScanRequestBuilderTest, TestChainCalls) { - ScanRequestBuilder builder; - ScanRequest sr = builder.SetAccountName(kAccountName) - .SetPowerMode(powerMode) - .SetOnlyScreenOnScan(kOnlyScreenOnScan) - .SetUseBle(kUseBle) - .SetManagerAppId(kManagerAppId) - .Build(); - EXPECT_EQ(sr.account_name, kAccountName); - EXPECT_EQ(sr.scan_only_when_screen_on, kOnlyScreenOnScan); - EXPECT_EQ(sr.power_mode, powerMode); - EXPECT_EQ(sr.use_ble, kUseBle); - EXPECT_EQ(sr.manager_app_id, kManagerAppId); -} - -TEST(ScanRequestBuilderTest, TestCopy) { - ScanRequestBuilder builder1; - builder1.SetOnlyScreenOnScan(kOnlyScreenOnScan).SetUseBle(kUseBle); - ScanRequestBuilder builder2 = {builder1}; - EXPECT_EQ(builder1, builder2); - ScanRequest s1 = builder1.Build(); - ScanRequest s2 = builder2.Build(); - EXPECT_EQ(s1, s2); -} -} // namespace -} // namespace presence -} // namespace nearby From 1346571e4f3e7c4a68e92d3c72797022320cc39e Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 7 May 2026 10:16:42 -0700 Subject: [PATCH 074/151] Fix UAF in WorkerQueue.Stop(). PiperOrigin-RevId: 912027304 --- sharing/BUILD | 1 + sharing/worker_queue.h | 50 ++++++++++++++++++++++++++++-------- sharing/worker_queue_test.cc | 43 ++++++++++++++++++++++++++----- 3 files changed, 76 insertions(+), 18 deletions(-) diff --git a/sharing/BUILD b/sharing/BUILD index d2c16191..ee2baf42 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -1014,6 +1014,7 @@ cc_test( "//internal/test", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], ) diff --git a/sharing/worker_queue.h b/sharing/worker_queue.h index 0fe8a928..b9c4d958 100644 --- a/sharing/worker_queue.h +++ b/sharing/worker_queue.h @@ -16,6 +16,7 @@ #define THIRD_PARTY_NEARBY_SHARING_WORKER_QUEUE_H_ #include +#include #include #include @@ -38,7 +39,11 @@ namespace nearby::sharing { template class WorkerQueue { public: - explicit WorkerQueue(TaskRunner* task_runner) : task_runner_(task_runner) {} + explicit WorkerQueue(TaskRunner* task_runner) + : task_runner_(task_runner), + run_data_(std::make_shared()) { + run_data_->is_stopped = false; + } ~WorkerQueue() { Stop(); } @@ -52,11 +57,11 @@ class WorkerQueue { LOG(ERROR) << "WorkerQueue is already started."; return false; } - if (is_stopped_) { + if (run_data_->is_stopped) { LOG(ERROR) << "WorkerQueue is already stopped, cannot restart."; return false; } - callback_ = std::move(callback); + run_data_->callback = std::move(callback); { absl::MutexLock lock(mutex_); if (!queue_.empty()) { @@ -67,12 +72,22 @@ class WorkerQueue { } // Stops the queue. No new callback will be scheduled. + // This method will block until the callback finishes if it is currently + // running. void Stop() { - bool already_stopped = is_stopped_.exchange(true); + bool already_stopped = run_data_->is_stopped.exchange(true); if (already_stopped || !is_started_) { return; } + // Prevent new callbacks from being scheduled. is_scheduled_ = true; + // Wait for inflight callback to finish. + absl::MutexLock lock(run_data_->running_mutex); + auto stopped_running = + [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(run_data_->running_mutex) { + return !run_data_->is_running; + }; + run_data_->running_mutex.Await(absl::Condition(&stopped_running)); } // Queues an item to be processed by the callback. @@ -95,9 +110,16 @@ class WorkerQueue { } private: + struct RunData { + std::atomic is_stopped; + absl::AnyInvocable callback; + absl::Mutex running_mutex; + bool is_running ABSL_GUARDED_BY(running_mutex) = false; + }; + void ScheduleCallback() { // Skip if not started or stopped - if (!is_started_ || is_stopped_) { + if (!is_started_ || run_data_->is_stopped) { return; } if (is_scheduled_.exchange(true)) { @@ -106,20 +128,26 @@ class WorkerQueue { return; } VLOG(1) << "Scheduling callback"; - task_runner_->PostTask([this]() { - if (is_stopped_) { - return; + task_runner_->PostTask([run_data = run_data_]() { + { + absl::MutexLock lock(run_data->running_mutex); + run_data->is_running = true; + } + if (!run_data->is_stopped) { + run_data->callback(); + } + { + absl::MutexLock lock(run_data->running_mutex); + run_data->is_running = false; } - callback_(); }); } TaskRunner* const task_runner_ = nullptr; - absl::AnyInvocable callback_; + std::shared_ptr run_data_; // Tracks whether Start() has been called. std::atomic is_started_ = false; // Tracks whether Stop() has been called. - std::atomic is_stopped_ = false; absl::Mutex mutex_; std::queue queue_ ABSL_GUARDED_BY(mutex_); // This is used track whether the callback is already scheduled so as to avoid diff --git a/sharing/worker_queue_test.cc b/sharing/worker_queue_test.cc index e9b6e3b0..a3671d61 100644 --- a/sharing/worker_queue_test.cc +++ b/sharing/worker_queue_test.cc @@ -14,10 +14,12 @@ #include "sharing/worker_queue.h" +#include #include #include "gtest/gtest.h" #include "absl/synchronization/notification.h" +#include "absl/time/time.h" #include "internal/test/fake_clock.h" #include "internal/test/fake_task_runner.h" @@ -91,12 +93,13 @@ TEST(WorkerQueueTest, QueueItemsWhileCallbackRunning) { TEST(WorkerQueueTest, StopStopsCallback) { FakeClock fake_clock; FakeTaskRunner task_runner(&fake_clock, 1); - WorkerQueue queue(&task_runner); - queue.Queue(1); - queue.Queue(2); + auto queue = std::make_unique>(&task_runner); + queue->Queue(1); + queue->Queue(2); absl::Notification notification; - EXPECT_TRUE(queue.Start([&queue, ¬ification]() { - std::queue items = queue.ReadAll(); + auto queue_ptr = queue.get(); + EXPECT_TRUE(queue->Start([queue_ptr, ¬ification]() { + std::queue items = queue_ptr->ReadAll(); EXPECT_EQ(items.size(), 2); EXPECT_EQ(items.front(), 1); EXPECT_EQ(items.back(), 2); @@ -104,8 +107,34 @@ TEST(WorkerQueueTest, StopStopsCallback) { })); // Wait for the callback to start. notification.WaitForNotification(); - queue.Stop(); - queue.Queue(3); + queue->Stop(); + queue->Queue(3); + queue.reset(); + task_runner.Sync(); + // No more callbacks. +} + +TEST(WorkerQueueTest, StopWaitsForInFlightCallback) { + FakeClock fake_clock; + FakeTaskRunner task_runner(&fake_clock, 1); + auto queue = std::make_unique>(&task_runner); + absl::Notification notification1; + absl::Notification notification2; + auto queue_ptr = queue.get(); + EXPECT_TRUE(queue->Start([queue_ptr, ¬ification1, ¬ification2]() { + std::queue items = queue_ptr->ReadAll(); + notification1.Notify(); + notification2.WaitForNotificationWithTimeout(absl::Milliseconds(500)); + EXPECT_EQ(items.size(), 2); + EXPECT_EQ(items.front(), 1); + EXPECT_EQ(items.back(), 2); + })); + queue->Queue(1); + queue->Queue(2); + // Wait for the callback to start. + notification1.WaitForNotification(); + queue->Queue(3); + queue.reset(); task_runner.Sync(); // No more callbacks. } From 313efed9c9dc95b610a4a933ba7faf487de1ea0f Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 7 May 2026 22:17:02 -0700 Subject: [PATCH 075/151] Fix unprotected multi-threaded access to list. PiperOrigin-RevId: 912324436 --- internal/platform/implementation/windows/wifi_hotspot.h | 2 +- .../platform/implementation/windows/wifi_hotspot_medium.cc | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/platform/implementation/windows/wifi_hotspot.h b/internal/platform/implementation/windows/wifi_hotspot.h index c6b4c34a..b68926ec 100644 --- a/internal/platform/implementation/windows/wifi_hotspot.h +++ b/internal/platform/implementation/windows/wifi_hotspot.h @@ -111,7 +111,7 @@ class WifiHotspotMedium : public api::WifiHotspotMedium { WiFiDirectConnectionListener listener_{nullptr}; // The list of WiFiDirectDevice is used to keep hotspot connection alive. - std::list wifi_direct_devices_; + std::list wifi_direct_devices_ ABSL_GUARDED_BY(mutex_); fire_and_forget OnStatusChanged( WiFiDirectAdvertisementPublisher sender, diff --git a/internal/platform/implementation/windows/wifi_hotspot_medium.cc b/internal/platform/implementation/windows/wifi_hotspot_medium.cc index 288efe14..e6ca86bd 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_medium.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_medium.cc @@ -349,7 +349,10 @@ fire_and_forget WifiHotspotMedium::OnConnectionRequested( auto wifi_direct_device = WiFiDirectDevice::FromIdAsync( connection_request.DeviceInformation().Id()) .get(); - wifi_direct_devices_.push_back(wifi_direct_device); + { + absl::MutexLock lock(mutex_); + wifi_direct_devices_.push_back(wifi_direct_device); + } LOG(INFO) << "Registered the device " << winrt::to_string(device_name) << " in WLAN-AutoConfig"; } catch (...) { From fc0fb02fee0b6442c1f2bf0632cf2ae4efbfd0f2 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 7 May 2026 22:18:49 -0700 Subject: [PATCH 076/151] Make sure timer is destroyed on the same thread callback is scheduled on. PiperOrigin-RevId: 912325093 --- sharing/internal/api/mock_sharing_platform.h | 2 - sharing/internal/api/sharing_platform.h | 2 - sharing/internal/public/context.h | 3 -- sharing/internal/public/context_impl.cc | 4 -- sharing/internal/public/context_impl.h | 1 - sharing/internal/test/fake_context.cc | 5 +-- sharing/internal/test/fake_context.h | 5 --- sharing/internal/test/fake_context_test.cc | 16 ------- sharing/nearby_connections_manager_impl.cc | 4 +- sharing/nearby_sharing_service_impl.cc | 5 ++- sharing/nearby_sharing_settings.cc | 15 ++++--- sharing/nearby_sharing_settings.h | 9 ++-- sharing/nearby_sharing_settings_test.cc | 36 ++++++++------- sharing/transfer_manager.cc | 17 ++++---- sharing/transfer_manager.h | 8 ++-- sharing/transfer_manager_test.cc | 46 +++++++++++--------- 16 files changed, 77 insertions(+), 101 deletions(-) diff --git a/sharing/internal/api/mock_sharing_platform.h b/sharing/internal/api/mock_sharing_platform.h index 34dbe0cf..c19adcc8 100644 --- a/sharing/internal/api/mock_sharing_platform.h +++ b/sharing/internal/api/mock_sharing_platform.h @@ -24,7 +24,6 @@ #include "absl/strings/string_view.h" #include "internal/base/file_path.h" #include "internal/platform/implementation/device_info.h" -#include "internal/platform/task_runner.h" #include "sharing/internal/api/app_info.h" #include "sharing/internal/api/bluetooth_adapter.h" #include "sharing/internal/api/fast_init_ble_beacon.h" @@ -71,7 +70,6 @@ class MockSharingPlatform : public SharingPlatform { MOCK_METHOD(PreferenceManager&, GetPreferenceManager, (), (override)); MOCK_METHOD(AccountManager&, GetAccountManager, (), (override)); - MOCK_METHOD(TaskRunner&, GetDefaultTaskRunner, (), (override)); MOCK_METHOD(nearby::api::DeviceInfo&, GetDeviceInfo, (), (override)); MOCK_METHOD(std::unique_ptr, CreatePublicCertificateDatabase, (const FilePath& database_path), diff --git a/sharing/internal/api/sharing_platform.h b/sharing/internal/api/sharing_platform.h index c795002e..9aefd967 100644 --- a/sharing/internal/api/sharing_platform.h +++ b/sharing/internal/api/sharing_platform.h @@ -23,7 +23,6 @@ #include "absl/strings/string_view.h" #include "internal/base/file_path.h" #include "internal/platform/implementation/device_info.h" -#include "internal/platform/task_runner.h" #include "sharing/internal/api/app_info.h" #include "sharing/internal/api/bluetooth_adapter.h" #include "sharing/internal/api/fast_init_ble_beacon.h" @@ -64,7 +63,6 @@ class SharingPlatform { virtual PreferenceManager& GetPreferenceManager() = 0; virtual AccountManager& GetAccountManager() = 0; - virtual TaskRunner& GetDefaultTaskRunner() = 0; virtual nearby::api::DeviceInfo& GetDeviceInfo() = 0; virtual std::unique_ptr CreatePublicCertificateDatabase(const FilePath& database_path) = 0; diff --git a/sharing/internal/public/context.h b/sharing/internal/public/context.h index 23c8de03..05b3d25f 100644 --- a/sharing/internal/public/context.h +++ b/sharing/internal/public/context.h @@ -49,9 +49,6 @@ class Context { // count of tasks running at the same time. virtual std::unique_ptr CreateConcurrentTaskRunner( uint32_t concurrent_count) const = 0; - - // Provides the API to retrieve TaskRunner to run a task globally. - virtual TaskRunner* GetTaskRunner() = 0; }; } // namespace nearby diff --git a/sharing/internal/public/context_impl.cc b/sharing/internal/public/context_impl.cc index b439cefa..7aefa05c 100644 --- a/sharing/internal/public/context_impl.cc +++ b/sharing/internal/public/context_impl.cc @@ -70,8 +70,4 @@ std::unique_ptr ContextImpl::CreateConcurrentTaskRunner( return task_runner; } -TaskRunner* ContextImpl::GetTaskRunner() { - return &platform_.GetDefaultTaskRunner(); -} - } // namespace nearby diff --git a/sharing/internal/public/context_impl.h b/sharing/internal/public/context_impl.h index 9775228d..a9078a6a 100644 --- a/sharing/internal/public/context_impl.h +++ b/sharing/internal/public/context_impl.h @@ -43,7 +43,6 @@ class ContextImpl : public Context { std::unique_ptr CreateSequencedTaskRunner() const override; std::unique_ptr CreateConcurrentTaskRunner( uint32_t concurrent_count) const override; - TaskRunner* GetTaskRunner() override; private: nearby::sharing::api::SharingPlatform& platform_; diff --git a/sharing/internal/test/fake_context.cc b/sharing/internal/test/fake_context.cc index 35605bca..37557c15 100644 --- a/sharing/internal/test/fake_context.cc +++ b/sharing/internal/test/fake_context.cc @@ -38,8 +38,7 @@ FakeContext::FakeContext() fake_connectivity_manager_(std::make_unique()), fake_bluetooth_adapter_(std::make_unique()), fake_fast_initiation_manager_( - std::make_unique()), - executor_(std::make_unique(fake_clock_.get(), 5)) {} + std::make_unique()) {} Clock* FakeContext::GetClock() const { return fake_clock_.get(); } @@ -70,6 +69,4 @@ std::unique_ptr FakeContext::CreateConcurrentTaskRunner( return std::make_unique(fake_clock_.get(), concurrent_count); } -TaskRunner* FakeContext::GetTaskRunner() { return executor_.get(); } - } // namespace nearby diff --git a/sharing/internal/test/fake_context.h b/sharing/internal/test/fake_context.h index c637dbf2..5a59879a 100644 --- a/sharing/internal/test/fake_context.h +++ b/sharing/internal/test/fake_context.h @@ -47,7 +47,6 @@ class FakeContext : public Context { std::unique_ptr CreateSequencedTaskRunner() const override; std::unique_ptr CreateConcurrentTaskRunner( uint32_t concurrent_count) const override; - TaskRunner* GetTaskRunner() override; FakeClock* fake_clock() const { return fake_clock_.get(); } FakeConnectivityManager* fake_connectivity_manager() const { @@ -59,9 +58,6 @@ class FakeContext : public Context { FakeFastInitiationManager* fake_fast_initiation_manager() const { return fake_fast_initiation_manager_.get(); } - FakeTaskRunner* fake_task_runner() const { - return executor_.get(); - } FakeTaskRunner* last_sequenced_task_runner() const { return last_sequenced_task_runner_; @@ -72,7 +68,6 @@ class FakeContext : public Context { std::unique_ptr fake_connectivity_manager_; std::unique_ptr fake_bluetooth_adapter_; std::unique_ptr fake_fast_initiation_manager_; - std::unique_ptr executor_; mutable FakeTaskRunner* last_sequenced_task_runner_ = nullptr; }; diff --git a/sharing/internal/test/fake_context_test.cc b/sharing/internal/test/fake_context_test.cc index 0b0c3152..03179926 100644 --- a/sharing/internal/test/fake_context_test.cc +++ b/sharing/internal/test/fake_context_test.cc @@ -15,9 +15,6 @@ #include "sharing/internal/test/fake_context.h" #include "gtest/gtest.h" -#include "absl/synchronization/notification.h" -#include "absl/time/time.h" -#include "internal/platform/task_runner.h" namespace nearby { namespace { @@ -31,18 +28,5 @@ TEST(FakeContext, TestAccessMockContext) { EXPECT_NE(context.CreateConcurrentTaskRunner(5), nullptr); } -TEST(FakeContext, ExecuteTask) { - FakeContext context; - absl::Notification notification; - bool is_called = false; - context.GetTaskRunner()->PostTask([&]() { - is_called = true; - notification.Notify(); - }); - - EXPECT_TRUE(notification.WaitForNotificationWithTimeout(absl::Seconds(1))); - EXPECT_TRUE(is_called); -} - } // namespace } // namespace nearby diff --git a/sharing/nearby_connections_manager_impl.cc b/sharing/nearby_connections_manager_impl.cc index f7154f69..78d1b9db 100644 --- a/sharing/nearby_connections_manager_impl.cc +++ b/sharing/nearby_connections_manager_impl.cc @@ -423,8 +423,8 @@ void NearbyConnectionsManagerImpl::Connect( // Setup transfer manager. if (IsTransportTypeFlagsSet(transport_type, TransportType::kHighQuality)) { - transfer_managers_[endpoint_id] = - std::make_unique(context_, endpoint_id); + transfer_managers_[endpoint_id] = std::make_unique( + connections_callback_task_runner_, endpoint_id); } } diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index bba46979..a999d629 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -259,8 +259,9 @@ NearbySharingServiceImpl::NearbySharingServiceImpl( nearby_fast_initiation_( NearbyFastInitiationImpl::Factory::Create(context_)), settings_(std::make_unique( - context_, context_->GetClock(), device_info_, preference_manager_, - local_device_data_manager_.get(), &analytics_recorder_)), + service_thread_.get(), context_->GetClock(), device_info_, + preference_manager_, local_device_data_manager_.get(), + &analytics_recorder_)), service_extension_(std::make_unique()), file_handler_(sharing_platform), app_info_(sharing_platform.CreateAppInfo()), diff --git a/sharing/nearby_sharing_settings.cc b/sharing/nearby_sharing_settings.cc index baf1118e..8d915aa9 100644 --- a/sharing/nearby_sharing_settings.cc +++ b/sharing/nearby_sharing_settings.cc @@ -22,17 +22,18 @@ #include #include +#include "absl/base/nullability.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "absl/time/time.h" #include "internal/platform/clock.h" #include "internal/platform/implementation/device_info.h" +#include "internal/platform/task_runner.h" #include "proto/sharing_enums.pb.h" #include "sharing/analytics/analytics_recorder.h" #include "sharing/common/nearby_share_enums.h" #include "sharing/common/nearby_share_prefs.h" #include "sharing/internal/api/preference_manager.h" -#include "sharing/internal/public/context.h" #include "sharing/internal/public/logging.h" #include "sharing/internal/public/pref_names.h" #include "sharing/local_device_data/nearby_share_local_device_data_manager.h" @@ -70,12 +71,12 @@ ShowNotificationStatus GetNotificationStatus( } // namespace NearbyShareSettings::NearbyShareSettings( - Context* context, nearby::Clock* clock, + TaskRunner* absl_nonnull task_runner, nearby::Clock* absl_nonnull clock, nearby::api::DeviceInfo& device_info, PreferenceManager& preference_manager, NearbyShareLocalDeviceDataManager* local_device_data_manager, analytics::AnalyticsRecorder* analytics_recorder) - : context_(context), - clock_(clock), + : task_runner_(*task_runner), + clock_(*clock), device_info_(device_info), preference_manager_(preference_manager), local_device_data_manager_(local_device_data_manager), @@ -143,7 +144,7 @@ void NearbyShareSettings::StartVisibilityTimer( LOG(INFO) << __func__ << ": start visibility timer. expiration=" << expiration; visibility_expiration_timer_ = std::make_unique( - *context_->GetTaskRunner(), "nearby_share_settings_visibility_timer", + task_runner_, "nearby_share_settings_visibility_timer", expiration, [this]() { LOG(INFO) << __func__ << ": visibility timer expired."; proto::DeviceVisibility visibility; @@ -164,7 +165,7 @@ void NearbyShareSettings::RestoreFallbackVisibility() { static_cast(prefs::kDefaultFallbackVisibility)); fallback_visibility_ = static_cast(fallback_visibility); - int64_t now_seconds = absl::ToUnixSeconds(clock_->Now()); + int64_t now_seconds = absl::ToUnixSeconds(clock_.Now()); int64_t remaining_seconds = expiration_seconds - now_seconds; int64_t diff = kMaxVisibilityExpirationSeconds - remaining_seconds; LOG(INFO) << __func__ << ": diff=" << diff << ", now=" << now_seconds @@ -276,7 +277,7 @@ void NearbyShareSettings::SetVisibility(DeviceVisibility visibility, visibility_expiration_timer_.reset(); SetFallbackVisibility(last_visibility); - absl::Time now = clock_->Now(); + absl::Time now = clock_.Now(); if (expiration != absl::ZeroDuration()) { VLOG(1) << __func__ << ": temporary visibility timer starts."; absl::Time fallback_visibility_timestamp = now + expiration; diff --git a/sharing/nearby_sharing_settings.h b/sharing/nearby_sharing_settings.h index f0793bae..8e40847e 100644 --- a/sharing/nearby_sharing_settings.h +++ b/sharing/nearby_sharing_settings.h @@ -23,6 +23,7 @@ #include #include "location/nearby/sharing/lib/sync/sync_binding_prefs.pb.h" +#include "absl/base/nullability.h" #include "absl/base/thread_annotations.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" @@ -30,11 +31,11 @@ #include "internal/base/observer_list.h" #include "internal/platform/clock.h" #include "internal/platform/implementation/device_info.h" +#include "internal/platform/task_runner.h" #include "proto/sharing_enums.pb.h" #include "sharing/analytics/analytics_recorder.h" #include "sharing/common/nearby_share_enums.h" #include "sharing/internal/api/preference_manager.h" -#include "sharing/internal/public/context.h" #include "sharing/internal/public/logging.h" #include "sharing/local_device_data/nearby_share_local_device_data_manager.h" #include "sharing/proto/settings_observer_data.pb.h" @@ -139,7 +140,7 @@ class NearbyShareSettings }; NearbyShareSettings( - Context* context, nearby::Clock* clock, + TaskRunner* absl_nonnull task_runner, nearby::Clock* absl_nonnull clock, nearby::api::DeviceInfo& device_info, nearby::sharing::api::PreferenceManager& preference_manager, NearbyShareLocalDeviceDataManager* local_device_data_manager, @@ -224,8 +225,8 @@ class NearbyShareSettings // Make sure thread safe to access Nearby settings mutable absl::Mutex mutex_; - Context* context_; - nearby::Clock* const clock_; + TaskRunner& task_runner_; + nearby::Clock& clock_; nearby::api::DeviceInfo& device_info_; nearby::sharing::api::PreferenceManager& preference_manager_; NearbyShareLocalDeviceDataManager* const local_device_data_manager_; diff --git a/sharing/nearby_sharing_settings_test.cc b/sharing/nearby_sharing_settings_test.cc index e11e22a1..4e6f029f 100644 --- a/sharing/nearby_sharing_settings_test.cc +++ b/sharing/nearby_sharing_settings_test.cc @@ -29,12 +29,12 @@ #include "absl/time/clock.h" #include "absl/time/time.h" #include "internal/base/files.h" +#include "internal/test/fake_clock.h" #include "internal/test/fake_device_info.h" #include "internal/test/fake_task_runner.h" #include "sharing/common/nearby_share_enums.h" #include "sharing/common/nearby_share_prefs.h" #include "sharing/internal/public/pref_names.h" -#include "sharing/internal/test/fake_context.h" #include "sharing/internal/test/fake_preference_manager.h" #include "sharing/local_device_data/fake_nearby_share_local_device_data_manager.h" #include "sharing/proto/enums.pb.h" @@ -120,11 +120,12 @@ class FakeNearbyShareSettingsObserver : public NearbyShareSettings::Observer { class NearbyShareSettingsTest : public ::testing::Test { public: NearbyShareSettingsTest() - : local_device_data_manager_(kDefaultDeviceName) { + : local_device_data_manager_(kDefaultDeviceName), + fake_task_runner_(&fake_clock_, /*count=*/1) { prefs::RegisterNearbySharingPrefs(preference_manager_); nearby_share_settings_ = std::make_unique( - &context_, context_.GetClock(), fake_device_info_, preference_manager_, - &local_device_data_manager_); + &fake_task_runner_, &fake_clock_, fake_device_info_, + preference_manager_, &local_device_data_manager_); nearby_share_settings_->AddSettingsObserver(&observer_); } @@ -147,11 +148,11 @@ class NearbyShareSettingsTest : public ::testing::Test { // Waits for running tasks to complete. void Flush() { absl::SleepFor(absl::Seconds(1)); - context_.fake_task_runner()->SyncWithTimeout(absl::Milliseconds(200)); + fake_task_runner_.SyncWithTimeout(absl::Milliseconds(200)); } void FastForward(absl::Duration duration) { - context_.fake_clock()->FastForward(duration); + fake_clock_.FastForward(duration); } bool Contains(std::vector v, std::string val) { @@ -164,8 +165,9 @@ class NearbyShareSettingsTest : public ::testing::Test { protected: nearby::FakeDeviceInfo fake_device_info_; nearby::FakePreferenceManager preference_manager_; - FakeContext context_; FakeNearbyShareLocalDeviceDataManager local_device_data_manager_; + FakeClock fake_clock_; + FakeTaskRunner fake_task_runner_; FakeNearbyShareSettingsObserver observer_; std::unique_ptr nearby_share_settings_; }; @@ -301,7 +303,7 @@ TEST_F(NearbyShareSettingsTest, // Set our initial visibility to self share. settings()->SetVisibility(DeviceVisibility::DEVICE_VISIBILITY_SELF_SHARE); // Set everyone mode temporarily. - absl::Time now = context_.GetClock()->Now(); + absl::Time now = fake_clock_.Now(); settings()->SetVisibility( DeviceVisibility::DEVICE_VISIBILITY_EVERYONE, absl::Seconds(prefs::kDefaultMaxVisibilityExpirationSeconds)); @@ -357,7 +359,7 @@ TEST_F(NearbyShareSettingsTest, TemporaryVisibilityIsCorrect) { DeviceVisibility::DEVICE_VISIBILITY_UNSPECIFIED); EXPECT_EQ(fallback_visibility.fallback_time, absl::UnixEpoch()); // Transition to temporary everyone mode. - absl::Time now = context_.GetClock()->Now(); + absl::Time now = fake_clock_.Now(); settings()->SetVisibility( DeviceVisibility::DEVICE_VISIBILITY_EVERYONE, absl::Seconds(prefs::kDefaultMaxVisibilityExpirationSeconds)); @@ -378,7 +380,7 @@ TEST_F(NearbyShareSettingsTest, SetVisibilityWithExpirationTooLong) { absl::Hours(1)); // Expiration capped at 10minutes. absl::Time expected_fallback_time = - context_.GetClock()->Now() + absl::Minutes(10); + fake_clock_.Now() + absl::Minutes(10); NearbyShareSettings::FallbackVisibilityInfo fallback_visibility = settings()->GetFallbackVisibility(); // default visibility was hidden. @@ -420,7 +422,8 @@ TEST_F(NearbyShareSettingsTest, SetSyncBindingPerfs_Success) { TEST(NearbyShareVisibilityTest, RestoresFallbackVisibility_ExpiredTimer) { // Create Nearby Share settings dependencies. - FakeContext context; + FakeClock fake_clock; + FakeTaskRunner fake_task_runner(&fake_clock, /*count=*/1); FakeDeviceInfo fake_device_info; FakePreferenceManager preference_manager; FakeNearbyShareLocalDeviceDataManager local_device_data_manager( @@ -432,13 +435,13 @@ TEST(NearbyShareVisibilityTest, RestoresFallbackVisibility_ExpiredTimer) { // Set expiration to 10 seconds ago. preference_manager.SetInteger( PrefNames::kVisibilityExpirationSeconds, - absl::ToUnixSeconds(context.GetClock()->Now() - absl::Seconds(10))); + absl::ToUnixSeconds(fake_clock.Now() - absl::Seconds(10))); // Set fallback visibility to self share. preference_manager.SetInteger( PrefNames::kFallbackVisibility, static_cast(DeviceVisibility::DEVICE_VISIBILITY_SELF_SHARE)); // Create a Nearby Share settings instance. - NearbyShareSettings settings(&context, context.GetClock(), fake_device_info, + NearbyShareSettings settings(&fake_task_runner, &fake_clock, fake_device_info, preference_manager, &local_device_data_manager); // Make sure we restore the correct visibility. @@ -448,7 +451,8 @@ TEST(NearbyShareVisibilityTest, RestoresFallbackVisibility_ExpiredTimer) { TEST(NearbyShareVisibilityTest, RestoresFallbackVisibility_FutureTimer) { // Create Nearby Share settings dependencies. - FakeContext context; + FakeClock fake_clock; + FakeTaskRunner fake_task_runner(&fake_clock, /*count=*/1); FakeDeviceInfo fake_device_info; FakePreferenceManager preference_manager; FakeNearbyShareLocalDeviceDataManager local_device_data_manager( @@ -460,13 +464,13 @@ TEST(NearbyShareVisibilityTest, RestoresFallbackVisibility_FutureTimer) { // Set expiration to 10 seconds in the future. preference_manager.SetInteger( PrefNames::kVisibilityExpirationSeconds, - absl::ToUnixSeconds(context.GetClock()->Now() + absl::Seconds(10))); + absl::ToUnixSeconds(fake_clock.Now() + absl::Seconds(10))); // Set fallback visibility to self share. preference_manager.SetInteger( PrefNames::kFallbackVisibility, static_cast(DeviceVisibility::DEVICE_VISIBILITY_SELF_SHARE)); // Create a Nearby Share settings instance. - NearbyShareSettings settings(&context, context.GetClock(), fake_device_info, + NearbyShareSettings settings(&fake_task_runner, &fake_clock, fake_device_info, preference_manager, &local_device_data_manager); // Make sure we restore the correct visibility. diff --git a/sharing/transfer_manager.cc b/sharing/transfer_manager.cc index dede2870..863c970e 100644 --- a/sharing/transfer_manager.cc +++ b/sharing/transfer_manager.cc @@ -19,10 +19,10 @@ #include #include +#include "absl/base/nullability.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" -#include "absl/time/time.h" -#include "sharing/internal/public/context.h" +#include "internal/platform/task_runner.h" #include "sharing/internal/public/logging.h" #include "sharing/nearby_connections_types.h" #include "sharing/thread_timer.h" @@ -43,9 +43,9 @@ bool IsHighQualityMedium(Medium medium) { } // namespace -TransferManager::TransferManager(Context* context, +TransferManager::TransferManager(TaskRunner* absl_nonnull runner, absl::string_view endpoint_id) - : context_(context), endpoint_id_(endpoint_id) {} + : runner_(*runner), endpoint_id_(endpoint_id) {} TransferManager::~TransferManager() { absl::MutexLock lock(mutex_); @@ -101,8 +101,8 @@ bool TransferManager::StartTransfer() { } timeout_timer_ = std::make_unique( - *context_->GetTaskRunner(), "transfer_manager_timeout_timer", - kMediumUpgradeTimeout, [this]() { + runner_, "transfer_manager_timeout_timer", kMediumUpgradeTimeout, + [this]() { absl::MutexLock lock(mutex_); LOG(INFO) << "Timed out for endpoint " << endpoint_id_ << " after " @@ -113,8 +113,7 @@ bool TransferManager::StartTransfer() { LOG(INFO) << "Attempting to upgrade the bandwidth for endpoint " + endpoint_id_ + ". Large payloads will be delayed" + " until either bandwidth is upgraded or a timeout of " - << (kMediumUpgradeTimeout / absl::Milliseconds(1)) - << " milliseconds is reached"; + << kMediumUpgradeTimeout << " is reached"; return true; } @@ -132,6 +131,7 @@ bool TransferManager::CancelTransfer() { } void TransferManager::StopWaitingForHighQualityMedium() { + timeout_timer_.reset(); is_waiting_for_high_quality_medium_ = false; for (const auto& task : pending_tasks_) { @@ -140,7 +140,6 @@ void TransferManager::StopWaitingForHighQualityMedium() { } pending_tasks_.clear(); - timeout_timer_.reset(); } } // namespace sharing diff --git a/sharing/transfer_manager.h b/sharing/transfer_manager.h index e33d1f33..e19f248c 100644 --- a/sharing/transfer_manager.h +++ b/sharing/transfer_manager.h @@ -20,11 +20,12 @@ #include #include +#include "absl/base/nullability.h" #include "absl/base/thread_annotations.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "absl/time/time.h" -#include "sharing/internal/public/context.h" +#include "internal/platform/task_runner.h" #include "sharing/nearby_connections_types.h" #include "sharing/thread_timer.h" @@ -39,7 +40,8 @@ class TransferManager { // Used to wait for the medium upgrade. static constexpr absl::Duration kMediumUpgradeTimeout = absl::Seconds(10); - TransferManager(Context* context, absl::string_view endpoint_id); + TransferManager(TaskRunner* absl_nonnull runner, + absl::string_view endpoint_id); ~TransferManager(); @@ -52,7 +54,7 @@ class TransferManager { private: void StopWaitingForHighQualityMedium() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - Context* context_; + TaskRunner& runner_; std::string endpoint_id_; absl::Mutex mutex_; bool is_waiting_for_high_quality_medium_ ABSL_GUARDED_BY(mutex_) = true; diff --git a/sharing/transfer_manager_test.cc b/sharing/transfer_manager_test.cc index f6ed6fc0..f46869f5 100644 --- a/sharing/transfer_manager_test.cc +++ b/sharing/transfer_manager_test.cc @@ -21,7 +21,7 @@ #include "absl/synchronization/notification.h" #include "absl/time/time.h" #include "internal/test/fake_clock.h" -#include "sharing/internal/test/fake_context.h" +#include "internal/test/fake_task_runner.h" #include "sharing/nearby_connections_types.h" namespace nearby { @@ -32,11 +32,12 @@ constexpr absl::string_view kEndpointId = "endpoint"; constexpr absl::Duration kNotificationTimeout = absl::Milliseconds(200); TEST(TransferManager, MediumUpgradeSuccess) { - FakeContext context; + FakeClock fake_clock; + FakeTaskRunner executor(&fake_clock, /*concurrent_count=*/1); absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&context, kEndpointId}; + TransferManager transfer_manager{&executor, kEndpointId}; transfer_manager.Send([&]() { is_called = true; notification.Notify(); @@ -53,11 +54,12 @@ TEST(TransferManager, MediumUpgradeSuccess) { } TEST(TransferManager, SendAfterMediumUpgradeSuccess) { - FakeContext context; + FakeClock fake_clock; + FakeTaskRunner executor(&fake_clock, /*concurrent_count=*/1); absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&context, kEndpointId}; + TransferManager transfer_manager{&executor, kEndpointId}; transfer_manager.Send([&]() { is_called = true; notification.Notify(); @@ -75,11 +77,12 @@ TEST(TransferManager, SendAfterMediumUpgradeSuccess) { } TEST(TransferManager, MediumUpgradeFailed) { - FakeContext context; + FakeClock fake_clock; + FakeTaskRunner executor(&fake_clock, /*concurrent_count=*/1); absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&context, kEndpointId}; + TransferManager transfer_manager{&executor, kEndpointId}; transfer_manager.Send([&]() { is_called = true; notification.Notify(); @@ -94,11 +97,12 @@ TEST(TransferManager, MediumUpgradeFailed) { } TEST(TransferManager, MediumUpgradeTimeout) { - FakeContext context; + FakeClock fake_clock; + FakeTaskRunner executor(&fake_clock, /*concurrent_count=*/1); absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&context, kEndpointId}; + TransferManager transfer_manager{&executor, kEndpointId}; transfer_manager.Send([&]() { is_called = true; notification.Notify(); @@ -106,8 +110,7 @@ TEST(TransferManager, MediumUpgradeTimeout) { ASSERT_FALSE(is_called); ASSERT_TRUE(transfer_manager.StartTransfer()); - FakeClock* clock = static_cast(context.GetClock()); - clock->FastForward(TransferManager::kMediumUpgradeTimeout); + fake_clock.FastForward(TransferManager::kMediumUpgradeTimeout); ASSERT_TRUE( notification.WaitForNotificationWithTimeout(kNotificationTimeout)); @@ -115,11 +118,12 @@ TEST(TransferManager, MediumUpgradeTimeout) { } TEST(TransferManager, CancelStartedTransfer) { - FakeContext context; + FakeClock fake_clock; + FakeTaskRunner executor(&fake_clock, /*concurrent_count=*/1); absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&context, kEndpointId}; + TransferManager transfer_manager{&executor, kEndpointId}; transfer_manager.Send([&]() { is_called = true; notification.Notify(); @@ -127,8 +131,7 @@ TEST(TransferManager, CancelStartedTransfer) { ASSERT_FALSE(is_called); ASSERT_TRUE(transfer_manager.StartTransfer()); - FakeClock* clock = static_cast(context.GetClock()); - clock->FastForward(absl::Seconds(5)); + fake_clock.FastForward(absl::Seconds(5)); ASSERT_TRUE(transfer_manager.CancelTransfer()); ASSERT_FALSE( @@ -137,11 +140,12 @@ TEST(TransferManager, CancelStartedTransfer) { } TEST(TransferManager, CancelTimedOutMediumUpgrade) { - FakeContext context; + FakeClock fake_clock; + FakeTaskRunner executor(&fake_clock, /*concurrent_count=*/1); absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&context, kEndpointId}; + TransferManager transfer_manager{&executor, kEndpointId}; transfer_manager.Send([&]() { is_called = true; notification.Notify(); @@ -149,8 +153,7 @@ TEST(TransferManager, CancelTimedOutMediumUpgrade) { ASSERT_FALSE(is_called); ASSERT_TRUE(transfer_manager.StartTransfer()); - FakeClock* clock = static_cast(context.GetClock()); - clock->FastForward(TransferManager::kMediumUpgradeTimeout); + fake_clock.FastForward(TransferManager::kMediumUpgradeTimeout); ASSERT_TRUE( notification.WaitForNotificationWithTimeout(kNotificationTimeout)); @@ -159,11 +162,12 @@ TEST(TransferManager, CancelTimedOutMediumUpgrade) { } TEST(TransferManager, MediumUpgradeBeforeStartTransfer) { - FakeContext context; + FakeClock fake_clock; + FakeTaskRunner executor(&fake_clock, /*concurrent_count=*/1); absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&context, kEndpointId}; + TransferManager transfer_manager{&executor, kEndpointId}; transfer_manager.Send([&]() { is_called = true; notification.Notify(); From c1e933e6d8590e03a5ea7776d68d209a2f8d426d Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 8 May 2026 10:21:44 -0700 Subject: [PATCH 077/151] Simple optimization of TransferManager PiperOrigin-RevId: 912585846 --- sharing/nearby_connections_manager_impl.cc | 43 +++++---- sharing/transfer_manager.cc | 33 ++++--- sharing/transfer_manager.h | 19 ++-- sharing/transfer_manager_test.cc | 101 +++++++++++++-------- 4 files changed, 118 insertions(+), 78 deletions(-) diff --git a/sharing/nearby_connections_manager_impl.cc b/sharing/nearby_connections_manager_impl.cc index 78d1b9db..8339895f 100644 --- a/sharing/nearby_connections_manager_impl.cc +++ b/sharing/nearby_connections_manager_impl.cc @@ -424,7 +424,9 @@ void NearbyConnectionsManagerImpl::Connect( // Setup transfer manager. if (IsTransportTypeFlagsSet(transport_type, TransportType::kHighQuality)) { transfer_managers_[endpoint_id] = std::make_unique( - connections_callback_task_runner_, endpoint_id); + connections_callback_task_runner_, endpoint_id, + absl::bind_front(&NearbyConnectionsManagerImpl::SendWithoutDelay, + this)); } } @@ -499,23 +501,18 @@ void NearbyConnectionsManagerImpl::Send( RegisterPayloadStatusListener(payload->id, listener); } - if (transfer_managers_.contains(endpoint_id) && payload->content.is_file()) { - VLOG(1) << __func__ << ": Send payload " << payload->id << " to " - << endpoint_id << " to transfer manager. payload is file: " - << payload->content.is_file() << ", is bytes " - << payload->content.is_bytes(); - transfer_managers_.at(endpoint_id) - ->Send([&, endpoint_id = std::string(endpoint_id), - payload_copy = *payload]() { - VLOG(1) << __func__ << ": Send payload " << payload_copy.id << " to " - << endpoint_id; - auto sent_payload = std::make_unique(payload_copy); - SendWithoutDelay(endpoint_id, std::move(sent_payload)); - }); - transfer_managers_.at(endpoint_id)->StartTransfer(); - return; + if (payload->content.is_file()) { + const auto& it = transfer_managers_.find(endpoint_id); + if (it != transfer_managers_.end()) { + VLOG(1) << __func__ << ": Send payload " << payload->id << " to " + << endpoint_id << " to transfer manager. payload is file: " + << payload->content.is_file() << ", is bytes " + << payload->content.is_bytes(); + it->second->Send(std::move(payload)); + it->second->StartTransfer(); + return; + } } - SendWithoutDelay(endpoint_id, std::move(payload)); } @@ -740,9 +737,10 @@ void NearbyConnectionsManagerImpl::OnDisconnected( absl::string_view endpoint_id) { MutexLock lock(&mutex_); // Remove transfer manager. - if (transfer_managers_.contains(endpoint_id)) { - transfer_managers_[endpoint_id]->CancelTransfer(); - transfer_managers_.erase(endpoint_id); + const auto& transfer_manager_it = transfer_managers_.find(endpoint_id); + if (transfer_manager_it != transfer_managers_.end()) { + transfer_manager_it->second->CancelTransfer(); + transfer_managers_.erase(transfer_manager_it); } Status connection_layer_status = Status::kUnknown; @@ -772,8 +770,9 @@ void NearbyConnectionsManagerImpl::OnBandwidthChanged( << ": Bandwidth changed to medium=" << static_cast(medium) << "; endpoint_id=" << endpoint_id; - if (transfer_managers_.contains(endpoint_id)) { - transfer_managers_[endpoint_id]->OnMediumQualityChanged(medium); + const auto& transfer_manager_it = transfer_managers_.find(endpoint_id); + if (transfer_manager_it != transfer_managers_.end()) { + transfer_manager_it->second->OnMediumQualityChanged(medium); } current_upgraded_mediums_.insert_or_assign(endpoint_id, medium); diff --git a/sharing/transfer_manager.cc b/sharing/transfer_manager.cc index 863c970e..fa38384b 100644 --- a/sharing/transfer_manager.cc +++ b/sharing/transfer_manager.cc @@ -14,12 +14,12 @@ #include "sharing/transfer_manager.h" -#include #include #include -#include +#include #include "absl/base/nullability.h" +#include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "internal/platform/task_runner.h" @@ -43,28 +43,32 @@ bool IsHighQualityMedium(Medium medium) { } // namespace -TransferManager::TransferManager(TaskRunner* absl_nonnull runner, - absl::string_view endpoint_id) - : runner_(*runner), endpoint_id_(endpoint_id) {} +TransferManager::TransferManager( + TaskRunner* absl_nonnull runner, absl::string_view endpoint_id, + absl::AnyInvocable payload)> + deferred_send_function) + : runner_(*runner), + endpoint_id_(endpoint_id), + deferred_send_function_(std::move(deferred_send_function)) {} TransferManager::~TransferManager() { absl::MutexLock lock(mutex_); timeout_timer_.reset(); - pending_tasks_.clear(); } -void TransferManager::Send(std::function task) { +void TransferManager::Send(std::unique_ptr payload) { absl::MutexLock lock(mutex_); if (is_waiting_for_high_quality_medium_) { LOG(INFO) << "Connection to endpoint " << endpoint_id_ << " is waiting for a high quality medium, delaying payload transfer."; - pending_tasks_.push_back(task); + pending_payloads_.push(std::move(payload)); return; } - task(); + deferred_send_function_(endpoint_id_, std::move(payload)); } void TransferManager::OnMediumQualityChanged(Medium current_medium) { @@ -134,12 +138,13 @@ void TransferManager::StopWaitingForHighQualityMedium() { timeout_timer_.reset(); is_waiting_for_high_quality_medium_ = false; - for (const auto& task : pending_tasks_) { - LOG(INFO) << "Sending delayed payload to endpoint " << endpoint_id_; - task(); + LOG(INFO) << "Sending " << pending_payloads_.size() + << " delayed payloads to endpoint " << endpoint_id_; + while (!pending_payloads_.empty()) { + auto payload = std::move(pending_payloads_.front()); + pending_payloads_.pop(); + deferred_send_function_(endpoint_id_, std::move(payload)); } - - pending_tasks_.clear(); } } // namespace sharing diff --git a/sharing/transfer_manager.h b/sharing/transfer_manager.h index e19f248c..619b2b0e 100644 --- a/sharing/transfer_manager.h +++ b/sharing/transfer_manager.h @@ -15,13 +15,13 @@ #ifndef THIRD_PARTY_NEARBY_SHARING_TRANSFER_MANAGER_H_ #define THIRD_PARTY_NEARBY_SHARING_TRANSFER_MANAGER_H_ -#include #include +#include #include -#include #include "absl/base/nullability.h" #include "absl/base/thread_annotations.h" +#include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "absl/time/time.h" @@ -41,11 +41,14 @@ class TransferManager { static constexpr absl::Duration kMediumUpgradeTimeout = absl::Seconds(10); TransferManager(TaskRunner* absl_nonnull runner, - absl::string_view endpoint_id); + absl::string_view endpoint_id, + absl::AnyInvocable payload)> + deferred_send_function); ~TransferManager(); - void Send(std::function task) ABSL_LOCKS_EXCLUDED(mutex_); + void Send(std::unique_ptr payload) ABSL_LOCKS_EXCLUDED(mutex_); void OnMediumQualityChanged(Medium current_medium) ABSL_LOCKS_EXCLUDED(mutex_); bool StartTransfer() ABSL_LOCKS_EXCLUDED(mutex_); @@ -55,10 +58,14 @@ class TransferManager { void StopWaitingForHighQualityMedium() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); TaskRunner& runner_; - std::string endpoint_id_; + const std::string endpoint_id_; + absl::AnyInvocable payload)> + deferred_send_function_; absl::Mutex mutex_; bool is_waiting_for_high_quality_medium_ ABSL_GUARDED_BY(mutex_) = true; - std::vector> pending_tasks_ ABSL_GUARDED_BY(mutex_); + std::queue> pending_payloads_ + ABSL_GUARDED_BY(mutex_); std::unique_ptr timeout_timer_ ABSL_GUARDED_BY(mutex_) = nullptr; }; diff --git a/sharing/transfer_manager_test.cc b/sharing/transfer_manager_test.cc index f46869f5..63f0616c 100644 --- a/sharing/transfer_manager_test.cc +++ b/sharing/transfer_manager_test.cc @@ -14,6 +14,7 @@ #include "sharing/transfer_manager.h" +#include #include #include "gtest/gtest.h" @@ -37,11 +38,15 @@ TEST(TransferManager, MediumUpgradeSuccess) { absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&executor, kEndpointId}; - transfer_manager.Send([&]() { - is_called = true; - notification.Notify(); - }); + TransferManager transfer_manager{ + &executor, kEndpointId, + [&](absl::string_view endpoint_id, std::unique_ptr payload) { + is_called = true; + if (!notification.HasBeenNotified()) { + notification.Notify(); + } + }}; + transfer_manager.Send(std::make_unique()); ASSERT_FALSE(is_called); ASSERT_TRUE(transfer_manager.StartTransfer()); @@ -59,11 +64,15 @@ TEST(TransferManager, SendAfterMediumUpgradeSuccess) { absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&executor, kEndpointId}; - transfer_manager.Send([&]() { - is_called = true; - notification.Notify(); - }); + TransferManager transfer_manager{ + &executor, kEndpointId, + [&](absl::string_view endpoint_id, std::unique_ptr payload) { + is_called = true; + if (!notification.HasBeenNotified()) { + notification.Notify(); + } + }}; + transfer_manager.Send(std::make_unique()); ASSERT_FALSE(is_called); ASSERT_TRUE(transfer_manager.StartTransfer()); @@ -72,7 +81,7 @@ TEST(TransferManager, SendAfterMediumUpgradeSuccess) { notification.WaitForNotificationWithTimeout(kNotificationTimeout)); ASSERT_TRUE(is_called); is_called = false; - transfer_manager.Send([&]() { is_called = true; }); + transfer_manager.Send(std::make_unique()); ASSERT_TRUE(is_called); } @@ -82,11 +91,15 @@ TEST(TransferManager, MediumUpgradeFailed) { absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&executor, kEndpointId}; - transfer_manager.Send([&]() { - is_called = true; - notification.Notify(); - }); + TransferManager transfer_manager{ + &executor, kEndpointId, + [&](absl::string_view endpoint_id, std::unique_ptr payload) { + is_called = true; + if (!notification.HasBeenNotified()) { + notification.Notify(); + } + }}; + transfer_manager.Send(std::make_unique()); ASSERT_FALSE(is_called); ASSERT_TRUE(transfer_manager.StartTransfer()); @@ -102,11 +115,15 @@ TEST(TransferManager, MediumUpgradeTimeout) { absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&executor, kEndpointId}; - transfer_manager.Send([&]() { - is_called = true; - notification.Notify(); - }); + TransferManager transfer_manager{ + &executor, kEndpointId, + [&](absl::string_view endpoint_id, std::unique_ptr payload) { + is_called = true; + if (!notification.HasBeenNotified()) { + notification.Notify(); + } + }}; + transfer_manager.Send(std::make_unique()); ASSERT_FALSE(is_called); ASSERT_TRUE(transfer_manager.StartTransfer()); @@ -123,11 +140,15 @@ TEST(TransferManager, CancelStartedTransfer) { absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&executor, kEndpointId}; - transfer_manager.Send([&]() { - is_called = true; - notification.Notify(); - }); + TransferManager transfer_manager{ + &executor, kEndpointId, + [&](absl::string_view endpoint_id, std::unique_ptr payload) { + is_called = true; + if (!notification.HasBeenNotified()) { + notification.Notify(); + } + }}; + transfer_manager.Send(std::make_unique()); ASSERT_FALSE(is_called); ASSERT_TRUE(transfer_manager.StartTransfer()); @@ -145,11 +166,15 @@ TEST(TransferManager, CancelTimedOutMediumUpgrade) { absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&executor, kEndpointId}; - transfer_manager.Send([&]() { - is_called = true; - notification.Notify(); - }); + TransferManager transfer_manager{ + &executor, kEndpointId, + [&](absl::string_view endpoint_id, std::unique_ptr payload) { + is_called = true; + if (!notification.HasBeenNotified()) { + notification.Notify(); + } + }}; + transfer_manager.Send(std::make_unique()); ASSERT_FALSE(is_called); ASSERT_TRUE(transfer_manager.StartTransfer()); @@ -167,11 +192,15 @@ TEST(TransferManager, MediumUpgradeBeforeStartTransfer) { absl::Notification notification; bool is_called = false; - TransferManager transfer_manager{&executor, kEndpointId}; - transfer_manager.Send([&]() { - is_called = true; - notification.Notify(); - }); + TransferManager transfer_manager{ + &executor, kEndpointId, + [&](absl::string_view endpoint_id, std::unique_ptr payload) { + is_called = true; + if (!notification.HasBeenNotified()) { + notification.Notify(); + } + }}; + transfer_manager.Send(std::make_unique()); transfer_manager.OnMediumQualityChanged(Medium::kWifiLan); From 87c6ad999ec898156ce463f220e1fceef2708534 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 8 May 2026 13:18:43 -0700 Subject: [PATCH 078/151] Deprecate enable_hotspot_address_candidates flag. PiperOrigin-RevId: 912663559 --- .../flags/nearby_platform_feature_flags.h | 4 - .../windows/wifi_hotspot_server_socket.cc | 96 ------------------- .../windows/wifi_hotspot_server_socket.h | 2 - 3 files changed, 102 deletions(-) diff --git a/internal/platform/flags/nearby_platform_feature_flags.h b/internal/platform/flags/nearby_platform_feature_flags.h index 924d80f7..35c2ebcf 100644 --- a/internal/platform/flags/nearby_platform_feature_flags.h +++ b/internal/platform/flags/nearby_platform_feature_flags.h @@ -53,10 +53,6 @@ constexpr auto kWifiHotspotConnectionIntervalMillis = constexpr auto kWifiHotspotConnectionTimeoutMillis = flags::Flag(kConfigPackage, "45415888", 10000); -// Enable/Disable use of address candidates for hotspot upgrade in Windows. -constexpr auto kEnableHotspotAddressCandidates = - flags::Flag(kConfigPackage, "45739567", false); - // Enable/Disable Intel PIe SDK to query/set WIFI feature. constexpr auto kEnableIntelPieSdk = flags::Flag(kConfigPackage, "45428547", false); diff --git a/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc b/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc index 4482e122..700e5f2f 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc @@ -15,28 +15,16 @@ #include #include -#include -#include #include -#include #include #include -// ABSL headers -#include "absl/functional/any_invocable.h" -#include "absl/strings/match.h" - // Nearby connections headers -#include "absl/synchronization/mutex.h" #include "internal/flags/nearby_flags.h" #include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/implementation/wifi_hotspot.h" -#include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.Collections.h" -#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Connectivity.h" -#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Sockets.h" #include "internal/platform/implementation/windows/network_info.h" #include "internal/platform/implementation/windows/socket_address.h" -#include "internal/platform/implementation/windows/utils.h" #include "internal/platform/implementation/windows/wifi_hotspot_server_socket.h" #include "internal/platform/implementation/windows/wifi_hotspot_socket.h" #include "internal/platform/logging.h" @@ -44,11 +32,6 @@ #include "internal/platform/wifi_credential.h" namespace nearby::windows { -namespace { -using ::winrt::Windows::Networking::Connectivity::NetworkInformation; -using ::winrt::Windows::Networking::HostNameType; -using ::winrt::Windows::Networking::Sockets::SocketQualityOfService; -} // namespace std::unique_ptr WifiHotspotServerSocket::Accept() { auto client_socket = server_socket_.Accept(); @@ -62,9 +45,6 @@ std::unique_ptr WifiHotspotServerSocket::Accept() { void WifiHotspotServerSocket::PopulateHotspotCredentials( HotspotCredentials& hotspot_credentials) { - bool use_address_candidates = NearbyFlags::GetInstance().GetBoolFlag( - platform::config_package_nearby::nearby_platform_feature:: - kEnableHotspotAddressCandidates); int64_t ip_address_max_retries = NearbyFlags::GetInstance().GetInt64Flag( platform::config_package_nearby::nearby_platform_feature:: kWifiHotspotCheckIpMaxRetries); @@ -72,43 +52,6 @@ void WifiHotspotServerSocket::PopulateHotspotCredentials( NearbyFlags::GetInstance().GetInt64Flag( platform::config_package_nearby::nearby_platform_feature:: kWifiHotspotCheckIpIntervalMillis); - if (!use_address_candidates) { - // Get current IP addresses of the device. - VLOG(1) << "maximum IP check retries=" << ip_address_max_retries - << ", IP check interval=" << ip_address_retry_interval_millis - << "ms"; - std::string hotspot_ipaddr; - for (int i = 0; i < ip_address_max_retries; i++) { - hotspot_ipaddr = GetHotspotIpAddress(); - if (hotspot_ipaddr.empty()) { - LOG(WARNING) << "Failed to find Hotspot's IP addr for the try: " - << i + 1 << ". Wait " << ip_address_retry_interval_millis - << "ms snd try again"; - Sleep(ip_address_retry_interval_millis); - } else { - break; - } - } - if (hotspot_ipaddr.empty()) { - LOG(WARNING) << "Failed to start accepting connection without IP " - "addresses configured on computer."; - return; - } - - std::vector hotspot_ipaddr_bytes; - uint32_t address_int = inet_addr(hotspot_ipaddr.c_str()); - if (address_int != INADDR_NONE) { - hotspot_ipaddr_bytes.resize(4); - std::memcpy(hotspot_ipaddr_bytes.data(), - reinterpret_cast(&address_int), 4); - } - ServiceAddress service_address = { - .address = hotspot_ipaddr_bytes, - .port = static_cast(GetPort()), - }; - hotspot_credentials.SetAddressCandidates({service_address}); - return; - } std::vector service_addresses; bool has_ipv4_address = false; for (int i = 0; i < ip_address_max_retries; i++) { @@ -170,43 +113,4 @@ bool WifiHotspotServerSocket::Listen(int port) { return true; } -std::string WifiHotspotServerSocket::GetHotspotIpAddress() const { - try { - auto host_names = NetworkInformation::GetHostNames(); - std::vector ip_candidates; - for (auto host_name : host_names) { - if (host_name.IPInformation() != nullptr && - host_name.IPInformation().NetworkAdapter() != nullptr && - host_name.Type() == HostNameType::Ipv4) { - std::string ipv4_s = winrt::to_string(host_name.ToString()); - if (absl::EndsWith(ipv4_s, ".1")) { - ip_candidates.push_back(ipv4_s); - } - } - } - if (ip_candidates.empty()) { - return ""; - } - // Windows always creates Hotspot at address "192.168.137.1". - for (auto &ip_candidate : ip_candidates) { - if (ip_candidate == "192.168.137.1") { - LOG(INFO) << "Found Hotspot IP: " << ip_candidate; - return ip_candidate; - } - } - LOG(INFO) << "Found Hotspot IP: " << ip_candidates.front(); - return ip_candidates.front(); - } catch (std::exception exception) { - LOG(ERROR) << __func__ << ": Exception: " << exception.what(); - return {}; - } catch (const winrt::hresult_error &error) { - LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": " - << winrt::to_string(error.message()); - return ""; - } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exception."; - return ""; - } -} - } // namespace nearby::windows diff --git a/internal/platform/implementation/windows/wifi_hotspot_server_socket.h b/internal/platform/implementation/windows/wifi_hotspot_server_socket.h index 61d4fa0d..8878d2f9 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_server_socket.h +++ b/internal/platform/implementation/windows/wifi_hotspot_server_socket.h @@ -79,8 +79,6 @@ class WifiHotspotServerSocket : public api::WifiHotspotServerSocket { bool Listen(int port); private: - // Retrieves hotspot IP address from local machine - std::string GetHotspotIpAddress() const; NearbyServerSocket server_socket_; }; From d41eff045cec81a356e50b78d5adfc30f6d4c6db Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 8 May 2026 20:23:09 -0700 Subject: [PATCH 079/151] Automated Code Change PiperOrigin-RevId: 912819296 --- internal/platform/implementation/apple/BUILD | 2 +- internal/platform/implementation/apple/atomic_boolean_test.cc | 2 +- internal/platform/implementation/apple/atomic_uint32_test.cc | 2 +- .../platform/implementation/apple/condition_variable_test.cc | 2 +- internal/platform/implementation/apple/count_down_latch_test.cc | 2 +- internal/platform/implementation/apple/mutex_test.cc | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/platform/implementation/apple/BUILD b/internal/platform/implementation/apple/BUILD index 496e5b7d..55875c7b 100644 --- a/internal/platform/implementation/apple/BUILD +++ b/internal/platform/implementation/apple/BUILD @@ -346,11 +346,11 @@ cc_test( deps = [ ":Platform_cc", "//internal/platform/implementation/g3:crypto", + "//third_party/gloop/thread/fiber", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", - "@com_google_nisaba//nisaba/port:thread_pool/fiber", ], ) diff --git a/internal/platform/implementation/apple/atomic_boolean_test.cc b/internal/platform/implementation/apple/atomic_boolean_test.cc index 26c6b4f7..cd86bf4d 100644 --- a/internal/platform/implementation/apple/atomic_boolean_test.cc +++ b/internal/platform/implementation/apple/atomic_boolean_test.cc @@ -15,7 +15,7 @@ #include "internal/platform/implementation/apple/atomic_boolean.h" #include "gtest/gtest.h" -#include "thread/fiber/fiber.h" +#include "third_party/gloop/thread/fiber/fiber.h" namespace nearby { namespace apple { diff --git a/internal/platform/implementation/apple/atomic_uint32_test.cc b/internal/platform/implementation/apple/atomic_uint32_test.cc index 54c2ac79..5fe2917f 100644 --- a/internal/platform/implementation/apple/atomic_uint32_test.cc +++ b/internal/platform/implementation/apple/atomic_uint32_test.cc @@ -15,7 +15,7 @@ #include "internal/platform/implementation/apple/atomic_uint32.h" #include "gtest/gtest.h" -#include "thread/fiber/fiber.h" +#include "third_party/gloop/thread/fiber/fiber.h" namespace nearby { namespace apple { diff --git a/internal/platform/implementation/apple/condition_variable_test.cc b/internal/platform/implementation/apple/condition_variable_test.cc index 846ad438..4b7af71b 100644 --- a/internal/platform/implementation/apple/condition_variable_test.cc +++ b/internal/platform/implementation/apple/condition_variable_test.cc @@ -16,8 +16,8 @@ #include "gtest/gtest.h" #include "absl/time/clock.h" +#include "third_party/gloop/thread/fiber/fiber.h" #include "internal/platform/implementation/apple/mutex.h" -#include "thread/fiber/fiber.h" namespace nearby { namespace apple { diff --git a/internal/platform/implementation/apple/count_down_latch_test.cc b/internal/platform/implementation/apple/count_down_latch_test.cc index 3b26af10..0f164f7a 100644 --- a/internal/platform/implementation/apple/count_down_latch_test.cc +++ b/internal/platform/implementation/apple/count_down_latch_test.cc @@ -18,7 +18,7 @@ #include "gtest/gtest.h" #include "absl/time/time.h" -#include "thread/fiber/fiber.h" +#include "third_party/gloop/thread/fiber/fiber.h" namespace nearby { namespace apple { diff --git a/internal/platform/implementation/apple/mutex_test.cc b/internal/platform/implementation/apple/mutex_test.cc index 4ebadce0..2ad2fce0 100644 --- a/internal/platform/implementation/apple/mutex_test.cc +++ b/internal/platform/implementation/apple/mutex_test.cc @@ -18,7 +18,7 @@ #include "absl/base/thread_annotations.h" #include "absl/synchronization/notification.h" #include "absl/time/time.h" -#include "thread/fiber/fiber.h" +#include "third_party/gloop/thread/fiber/fiber.h" namespace nearby { namespace apple { From 049a7466646911680c79295c4577b278da2e4287 Mon Sep 17 00:00:00 2001 From: hai007 Date: Sun, 10 May 2026 09:43:08 -0700 Subject: [PATCH 080/151] Automated Code Change PiperOrigin-RevId: 913320328 --- internal/platform/connection_info.cc | 2 +- internal/platform/connection_info_test.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/platform/connection_info.cc b/internal/platform/connection_info.cc index eaa745cc..24d4c082 100644 --- a/internal/platform/connection_info.cc +++ b/internal/platform/connection_info.cc @@ -42,6 +42,6 @@ ConnectionInfoVariant ConnectionInfo::FromDataElementBytes( return result.value(); } } - return absl::monostate(); + return std::monostate(); } } // namespace nearby diff --git a/internal/platform/connection_info_test.cc b/internal/platform/connection_info_test.cc index 972456c7..2272f15a 100644 --- a/internal/platform/connection_info_test.cc +++ b/internal/platform/connection_info_test.cc @@ -104,7 +104,7 @@ TEST(ConnectionInfoTest, TestMonostate) { auto serialized = info->ToDataElementBytes(); auto connection_info = ConnectionInfo::FromDataElementBytes(serialized.substr(0, 10)); - EXPECT_TRUE(absl::holds_alternative(connection_info)); + EXPECT_TRUE(absl::holds_alternative(connection_info)); } } From 1d6cc1e50e0c9a231bffe6870bff6ba142e14e07 Mon Sep 17 00:00:00 2001 From: hai007 Date: Sun, 10 May 2026 09:45:57 -0700 Subject: [PATCH 081/151] Automated Code Change PiperOrigin-RevId: 913320890 --- connections/v3/connections_device.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connections/v3/connections_device.cc b/connections/v3/connections_device.cc index 402f5a0a..e32202e6 100644 --- a/connections/v3/connections_device.cc +++ b/connections/v3/connections_device.cc @@ -31,7 +31,7 @@ std::string ConnectionsDevice::ToProtoBytes() const { // Bytes holding the connection info data elements. std::string connection_info_string; for (const auto& connection_info : connection_infos_) { - if (absl::holds_alternative(connection_info)) { + if (absl::holds_alternative(connection_info)) { continue; } if (absl::holds_alternative(connection_info)) { From 24c6dd901536f385c8085ef168e37b05af7a01f7 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 11 May 2026 10:07:23 -0700 Subject: [PATCH 082/151] Fix UAF in transfer_manager.cc PiperOrigin-RevId: 913757006 --- sharing/nearby_connections_manager_impl.cc | 22 +++++++++++++++++++--- sharing/nearby_connections_manager_impl.h | 3 +++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/sharing/nearby_connections_manager_impl.cc b/sharing/nearby_connections_manager_impl.cc index 8339895f..0b57e8c0 100644 --- a/sharing/nearby_connections_manager_impl.cc +++ b/sharing/nearby_connections_manager_impl.cc @@ -334,6 +334,12 @@ void NearbyConnectionsManagerImpl::StopDiscovery() { }); } +void NearbyConnectionsManagerImpl::RemoveTransferManagerOnCallbackThread( + std::unique_ptr transfer_manager) const { + connections_callback_task_runner_->PostTask( + [transfer_manager = std::move(transfer_manager)]() {}); +} + void NearbyConnectionsManagerImpl::Connect( std::vector endpoint_info, absl::string_view endpoint_id, std::optional> bluetooth_mac_address, @@ -416,7 +422,10 @@ void NearbyConnectionsManagerImpl::Connect( [this, endpoint_id = std::string(endpoint_id)](ConnectionsStatus status) { MutexLock lock(&mutex_); if (status != ConnectionsStatus::kSuccess) { - transfer_managers_.erase(endpoint_id); + auto node = transfer_managers_.extract(endpoint_id); + if (!node.empty()) { + RemoveTransferManagerOnCallbackThread(std::move(node.mapped())); + } } OnConnectionRequested(endpoint_id, status); }); @@ -740,7 +749,10 @@ void NearbyConnectionsManagerImpl::OnDisconnected( const auto& transfer_manager_it = transfer_managers_.find(endpoint_id); if (transfer_manager_it != transfer_managers_.end()) { transfer_manager_it->second->CancelTransfer(); - transfer_managers_.erase(transfer_manager_it); + auto node = transfer_managers_.extract(transfer_manager_it); + if (!node.empty()) { + RemoveTransferManagerOnCallbackThread(std::move(node.mapped())); + } } Status connection_layer_status = Status::kUnknown; @@ -907,7 +919,11 @@ void NearbyConnectionsManagerImpl::Reset() { for (auto& transfer_manager : transfer_managers_) { transfer_manager.second->CancelTransfer(); } - transfer_managers_.clear(); + absl::flat_hash_map> + transfer_managers; + transfer_managers.swap(transfer_managers_); + connections_callback_task_runner_->PostTask( + [transfer_managers = std::move(transfer_managers)]() {}); for (auto& entry : pending_outgoing_connections_) std::move(entry.second)(entry.first, /*connection=*/nullptr, diff --git a/sharing/nearby_connections_manager_impl.h b/sharing/nearby_connections_manager_impl.h index bf9ce1e8..174f83f8 100644 --- a/sharing/nearby_connections_manager_impl.h +++ b/sharing/nearby_connections_manager_impl.h @@ -143,6 +143,9 @@ class NearbyConnectionsManagerImpl : public NearbyConnectionsManager { void SendWithoutDelay(absl::string_view endpoint_id, std::unique_ptr payload); + void RemoveTransferManagerOnCallbackThread( + std::unique_ptr transfer_manager) const; + nearby::TaskRunner* const connections_callback_task_runner_; Context* const context_; nearby::ConnectivityManager& connectivity_manager_; From 3dae0f119e63c928f9a8be1f8a765a1015ad2fc0 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 12 May 2026 14:21:30 -0700 Subject: [PATCH 083/151] Delete unused code. PiperOrigin-RevId: 914475976 --- Package.swift | 4 - connections/implementation/BUILD | 1 - connections/implementation/mediums/BUILD | 1 - .../implementation/mediums/multiplex/BUILD | 73 -- .../mediums/multiplex/multiplex_frames.cc | 215 ----- .../mediums/multiplex/multiplex_frames.h | 112 --- .../multiplex/multiplex_frames_test.cc | 170 ---- .../multiplex/multiplex_output_stream.cc | 360 -------- .../multiplex/multiplex_output_stream.h | 209 ----- .../multiplex/multiplex_output_stream_test.cc | 253 ------ .../mediums/multiplex/multiplex_socket.cc | 818 ------------------ .../mediums/multiplex/multiplex_socket.h | 223 ----- .../multiplex/multiplex_socket_test.cc | 463 ---------- 13 files changed, 2902 deletions(-) delete mode 100644 connections/implementation/mediums/multiplex/BUILD delete mode 100644 connections/implementation/mediums/multiplex/multiplex_frames.cc delete mode 100644 connections/implementation/mediums/multiplex/multiplex_frames.h delete mode 100644 connections/implementation/mediums/multiplex/multiplex_frames_test.cc delete mode 100644 connections/implementation/mediums/multiplex/multiplex_output_stream.cc delete mode 100644 connections/implementation/mediums/multiplex/multiplex_output_stream.h delete mode 100644 connections/implementation/mediums/multiplex/multiplex_output_stream_test.cc delete mode 100644 connections/implementation/mediums/multiplex/multiplex_socket.cc delete mode 100644 connections/implementation/mediums/multiplex/multiplex_socket.h delete mode 100644 connections/implementation/mediums/multiplex/multiplex_socket_test.cc diff --git a/Package.swift b/Package.swift index 6ac9729b..c0736224 100644 --- a/Package.swift +++ b/Package.swift @@ -321,7 +321,6 @@ let package = Package( "connections/implementation/flags/BUILD", "connections/implementation/mediums/advertisements/BUILD", "connections/implementation/mediums/ble/BUILD", - "connections/implementation/mediums/multiplex/BUILD", "connections/implementation/mediums/BUILD", "connections/implementation/BUILD", "connections/implementation/fuzzers", @@ -392,9 +391,6 @@ let package = Package( "connections/implementation/mediums/ble/discovered_peripheral_tracker_test.cc", "connections/implementation/mediums/ble/instant_on_lost_advertisement_test.cc", "connections/implementation/mediums/ble/instant_on_lost_manager_test.cc", - "connections/implementation/mediums/multiplex/multiplex_frames_test.cc", - "connections/implementation/mediums/multiplex/multiplex_socket_test.cc", - "connections/implementation/mediums/multiplex/multiplex_output_stream_test.cc", "connections/implementation/mediums/webrtc_peer_id_test.cc", "connections/implementation/mediums/wifi_lan_test.cc", "connections/implementation/mediums/bluetooth_classic_test.cc", diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index edc8fd47..61c37dc0 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -145,7 +145,6 @@ cc_library( "//connections:__pkg__", "//connections:partners", "//connections/implementation/fuzzers:__pkg__", - "//connections/implementation/mediums/multiplex:__pkg__", "//sharing:__subpackages__", ], deps = [ diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index df6b27fe..ad7736f8 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -135,7 +135,6 @@ cc_library( "//connections/implementation:__pkg__", "//connections/implementation/mediums/advertisements:__pkg__", "//connections/implementation/mediums/ble:__subpackages__", - "//connections/implementation/mediums/multiplex:__pkg__", "//internal/platform/implementation/windows:__pkg__", ], deps = [ diff --git a/connections/implementation/mediums/multiplex/BUILD b/connections/implementation/mediums/multiplex/BUILD deleted file mode 100644 index 63c05094..00000000 --- a/connections/implementation/mediums/multiplex/BUILD +++ /dev/null @@ -1,73 +0,0 @@ -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -# Copyright 2024 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. -licenses(["notice"]) - -cc_library( - name = "multiplex", - srcs = [ - "multiplex_frames.cc", - "multiplex_output_stream.cc", - "multiplex_socket.cc", - ], - hdrs = [ - "multiplex_frames.h", - "multiplex_output_stream.h", - "multiplex_socket.h", - ], - visibility = [ - "//connections/implementation:__subpackages__", - ], - deps = [ - "//connections:core_types", - "//connections/implementation/mediums:utils", - "//internal/platform:base", - "//internal/platform:logging", - "//internal/platform:types", - "//proto:connections_enums_cc_proto", - "//proto/mediums:multiplex_frames_cc_proto", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - ], -) - -cc_test( - name = "multiplex_test", - srcs = [ - "multiplex_frames_test.cc", - "multiplex_output_stream_test.cc", - "multiplex_socket_test.cc", - ], - tags = ["notap"], - deps = [ - ":multiplex", - "//connections/implementation:internal", - "//internal/platform:base", - "//internal/platform:logging", - "//internal/platform:types", - "//internal/platform/implementation/g3", # buildcleaner: keep - "//proto:connections_enums_cc_proto", - "//proto/mediums:multiplex_frames_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/strings:string_view", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/connections/implementation/mediums/multiplex/multiplex_frames.cc b/connections/implementation/mediums/multiplex/multiplex_frames.cc deleted file mode 100644 index 3eea2aa1..00000000 --- a/connections/implementation/mediums/multiplex/multiplex_frames.cc +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2024 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. - -#include "connections/implementation/mediums/multiplex/multiplex_frames.h" - -#include -#include - -#include "absl/strings/string_view.h" -#include "connections/implementation/mediums/utils.h" -#include "internal/platform/base64_utils.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/exception.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace multiplex { - -using ::location::nearby::mediums::ConnectionResponseFrame; -using ::location::nearby::mediums::MultiplexControlFrame; -using ::location::nearby::mediums::MultiplexFrame; - -ByteArray GenerateServiceIdHash(const std::string& service_id) { - return Utils::Sha256Hash(service_id, kServiceIdHashLength); -} - -ByteArray GenerateServiceIdHashWithSalt(const std::string& service_id, - std::string salt) { - if (salt.empty()) { - return GenerateServiceIdHash(service_id); - } - - return Utils::Sha256Hash(service_id + salt, kServiceIdHashLength); -} - -std::string GenerateServiceIdHashKey(const ByteArray& service_id_hash) { - return Base64Utils::Encode(service_id_hash); -} - -std::string GenerateServiceIdHashKey(const std::string& service_id) { - return GenerateServiceIdHashKey(GenerateServiceIdHash(service_id)); -} - -std::string GenerateServiceIdHashKeyWithSalt(const std::string& service_id, - std::string salt) { - return GenerateServiceIdHashKey( - GenerateServiceIdHashWithSalt(service_id, salt)); -} - -ByteArray ToBytes(MultiplexFrame&& frame) { - ByteArray bytes(frame.ByteSizeLong()); - frame.SerializeToArray(bytes.data(), bytes.size()); - return bytes; -} - -ByteArray ForConnectionRequest(const std::string& service_id, - const std::string& service_id_hash_salt) { - MultiplexFrame frame; - - frame.set_frame_type(MultiplexFrame::CONTROL_FRAME); - auto* header = frame.mutable_header(); - header->set_salted_service_id_hash(std::string( - GenerateServiceIdHashWithSalt(service_id, service_id_hash_salt))); - header->set_service_id_hash_salt(service_id_hash_salt); - - auto* control_frame = frame.mutable_control_frame(); - control_frame->set_control_frame_type( - MultiplexControlFrame::CONNECTION_REQUEST); - - return ToBytes(std::move(frame)); -} - -ByteArray ForConnectionResponse( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt, - ConnectionResponseFrame::ConnectionResponseCode response_code) { - MultiplexFrame frame; - - frame.set_frame_type(MultiplexFrame::CONTROL_FRAME); - auto* header = frame.mutable_header(); - header->set_salted_service_id_hash(std::string(salted_service_id_hash)); - header->set_service_id_hash_salt(service_id_hash_salt); - - auto* control_frame = frame.mutable_control_frame(); - control_frame->set_control_frame_type( - MultiplexControlFrame::CONNECTION_RESPONSE); - - auto* response_frame = control_frame->mutable_connection_response_frame(); - response_frame->set_connection_response_code(response_code); - - return ToBytes(std::move(frame)); -} - -ByteArray ForDisconnection(const std::string& service_id, - const std::string& service_id_hash_salt) { - MultiplexFrame frame; - - frame.set_frame_type(MultiplexFrame::CONTROL_FRAME); - auto* header = frame.mutable_header(); - header->set_salted_service_id_hash(std::string( - GenerateServiceIdHashWithSalt(service_id, service_id_hash_salt))); - header->set_service_id_hash_salt(service_id_hash_salt); - - auto* control_frame = frame.mutable_control_frame(); - control_frame->set_control_frame_type(MultiplexControlFrame::DISCONNECTION); - - return ToBytes(std::move(frame)); -} - -ByteArray ForData(const std::string& service_id, - const std::string& service_id_hash_salt, - bool should_pass_salt, absl::string_view data) { - MultiplexFrame frame; - - frame.set_frame_type(MultiplexFrame::DATA_FRAME); - auto* header = frame.mutable_header(); - header->set_salted_service_id_hash(std::string( - GenerateServiceIdHashWithSalt(service_id, service_id_hash_salt))); - if (should_pass_salt) { - header->set_service_id_hash_salt(service_id_hash_salt); - } - - auto* data_frame = frame.mutable_data_frame(); - data_frame->set_data(data); - - return ToBytes(std::move(frame)); -} - -ExceptionOr FromBytes(const ByteArray& multiplex_frame_bytes) { - MultiplexFrame frame; - - if (frame.ParseFromString(std::string(multiplex_frame_bytes))) { - if (!IsValid(frame)) { - return ExceptionOr(Exception::kInvalidProtocolBuffer); - } - return ExceptionOr(std::move(frame)); - } else { - return ExceptionOr(Exception::kInvalidProtocolBuffer); - } -} - -bool IsControlFrame(MultiplexFrame::MultiplexFrameType frame_type) { - return frame_type == MultiplexFrame::CONTROL_FRAME; -} - -bool IsDataFrame(MultiplexFrame::MultiplexFrameType frame_type) { - return frame_type == MultiplexFrame::DATA_FRAME; -} - -bool IsValid(const MultiplexFrame& frame) { - switch (frame.frame_type()) { - case MultiplexFrame::CONTROL_FRAME: - return IsValidControlFrame(frame); - case MultiplexFrame::DATA_FRAME: - return IsValidDataFrame(frame); - default: - return false; - } -} - -bool IsValidControlFrame(const MultiplexFrame& frame) { - if (!frame.has_control_frame()) { - return false; - } - - switch (frame.control_frame().control_frame_type()) { - case MultiplexControlFrame::CONNECTION_REQUEST: - case MultiplexControlFrame::CONNECTION_RESPONSE: - case MultiplexControlFrame::DISCONNECTION: - if (frame.header().salted_service_id_hash().size() == - kServiceIdHashLength) { - return true; - } - break; - default: - break; - } - - return false; -} - -bool IsValidDataFrame(const MultiplexFrame& frame) { - return frame.has_data_frame() && - frame.header().salted_service_id_hash().size() == kServiceIdHashLength; -} - -bool IsMultiplexFrame(const ByteArray& data) { - ExceptionOr frame = FromBytes(data); - if (!frame.ok()) { - return false; - } else { - LOG(INFO) << "Checked data is a multiplex frame. Is Control ? " - << frame.result().has_control_frame() << ", is data ? " - << frame.result().has_data_frame(); - return true; - } -} - -} // namespace multiplex -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/multiplex/multiplex_frames.h b/connections/implementation/mediums/multiplex/multiplex_frames.h deleted file mode 100644 index 283697a4..00000000 --- a/connections/implementation/mediums/multiplex/multiplex_frames.h +++ /dev/null @@ -1,112 +0,0 @@ - -// Copyright 2024 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 CORE_INTERNAL_MEDIUMS_MULTIPLEX_MULTIPLEX_FRAMES_H_ -#define CORE_INTERNAL_MEDIUMS_MULTIPLEX_MULTIPLEX_FRAMES_H_ - -#include - -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/exception.h" -#include "proto/mediums/multiplex_frames.pb.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace multiplex { - -constexpr int kServiceIdHashLength = 4; - -// Serialize/Deserialize MultiplexFrame messages. - -// Parses incoming MultiplexFrame message. -// Returns MultiplexFrame if parser was able to understand it, or -// Exception::kInvalidProtocolBuffer, if parser failed. - -// Generates a service ID hash bytes with {@link -// MultiplexFrames#SERVICE_ID_HASH_LENGTH}. -ByteArray GenerateServiceIdHash(const std::string& service_id); - -// Generates a service ID hash bytes with salt and {@link -// MultiplexFrames#SERVICE_ID_HASH_LENGTH}. -ByteArray GenerateServiceIdHashWithSalt(const std::string& service_id, - std::string salt); - -// Converts the service Id hash bytes to a Base64 encoded string to be used as a -// {@code Map} key. -std::string GenerateServiceIdHashKey(const ByteArray& service_id_hash); - -// Generates a service ID hash bytes with {@link -// MultiplexFrames#SERVICE_ID_HASH_LENGTH} and converts to a Base64 encoded -// string to be used as a {@code Map} key. -std::string GenerateServiceIdHashKey(const std::string& service_id); - -// Generates a service ID hash bytes with salt and {@link -// MultiplexFrames#SERVICE_ID_HASH_LENGTH} and converts to a Base64 encoded -// string to be used as a { @code Map } key. -std::string GenerateServiceIdHashKeyWithSalt(const std::string& service_id, - std::string salt); - -// Build a MultiplexFrame Connection Request frame Bytes stream. -// @param service_id The service ID of the connection. -// @param service_id_hash_salt The salt used to generate the service ID hash. -ByteArray ForConnectionRequest(const std::string& service_id, - const std::string& service_id_hash_salt); - -// Build a MultiplexFrame Connection Response frame Bytes stream. -// @param salted_service_id_hash The salted service ID hash. -// @param service_id_hash_salt The salt used to generate the service ID hash. -// @param response_code The response code of the connection. -ByteArray ForConnectionResponse( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt, - location::nearby::mediums::ConnectionResponseFrame::ConnectionResponseCode - response_code); - -// Build a MultiplexFrame Disconnection frame Bytes stream. -// @param service_id The service ID of the connection. -// @param service_id_hash_salt The salt used to generate the service ID hash. -ByteArray ForDisconnection(const std::string& service_id, - const std::string& service_id_hash_salt); - -// Build a MultiplexFrame Data frame Bytes stream. -// @param service_id The service ID of the connection. -// @param service_id_hash_salt The salt used to generate the service ID hash. -// @param should_pass_salt Whether to pass the salt in the data frame. -// @param data The data to send. -ByteArray ForData(const std::string& service_id, - const std::string& service_id_hash_salt, - bool should_pass_salt, absl::string_view data); - -ExceptionOr FromBytes( - const ByteArray& multiplex_frame_bytes); - -bool IsControlFrame( - location::nearby::mediums::MultiplexFrame::MultiplexFrameType frame_type); -bool IsDataFrame( - location::nearby::mediums::MultiplexFrame::MultiplexFrameType frame_type); -bool IsValid(const location::nearby::mediums::MultiplexFrame& frame); -bool IsValidControlFrame( - const location::nearby::mediums::MultiplexFrame& frame); -bool IsValidDataFrame(const location::nearby::mediums::MultiplexFrame& frame); -bool IsMultiplexFrame(const ByteArray& data); - -} // namespace multiplex -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_MULTIPLEX_MULTIPLEX_FRAMES_H_ diff --git a/connections/implementation/mediums/multiplex/multiplex_frames_test.cc b/connections/implementation/mediums/multiplex/multiplex_frames_test.cc deleted file mode 100644 index 95a66803..00000000 --- a/connections/implementation/mediums/multiplex/multiplex_frames_test.cc +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2024 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. - -#include "connections/implementation/mediums/multiplex/multiplex_frames.h" -#include -#include - -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace multiplex { - -using ::location::nearby::mediums::MultiplexFrame; -using ::location::nearby::mediums::MultiplexControlFrame; -using ::location::nearby::mediums::ConnectionResponseFrame; - -constexpr absl::string_view kServiceId_1 = "serviceId_1"; -constexpr absl::string_view kServiceId_2 = "serviceId_2"; - -TEST(MultiplexFrameTest, FrameValidation) { - const ByteArray data("abcdefghijklmnopqrstuvwxyz"); - MultiplexFrame frame; - EXPECT_FALSE(IsValid(frame)); - frame.set_frame_type(MultiplexFrame::CONTROL_FRAME); - EXPECT_FALSE(IsValidControlFrame(frame)); - - auto* control_frame = frame.mutable_control_frame(); - control_frame->set_control_frame_type( - MultiplexControlFrame::UNKNOWN_CONTROL_FRAME_TYPE); - EXPECT_FALSE(IsValidControlFrame(frame)); - auto* header = frame.mutable_header(); - header->set_salted_service_id_hash(std::string( - GenerateServiceIdHashWithSalt(std::string(kServiceId_1), "1234"))); - control_frame->set_control_frame_type( - MultiplexControlFrame::CONNECTION_REQUEST); - EXPECT_TRUE(IsValidControlFrame(frame)); - EXPECT_TRUE(IsValid(frame)); - control_frame->set_control_frame_type( - MultiplexControlFrame::CONNECTION_RESPONSE); - EXPECT_TRUE(IsValidControlFrame(frame)); - EXPECT_TRUE(IsValid(frame)); - control_frame->set_control_frame_type( - MultiplexControlFrame::DISCONNECTION); - EXPECT_TRUE(IsValidControlFrame(frame)); - EXPECT_TRUE(IsValid(frame)); - - EXPECT_FALSE(IsValidDataFrame(frame)); - frame.set_frame_type(MultiplexFrame::DATA_FRAME); - auto* data_frame = frame.mutable_data_frame(); - data_frame->set_data(std::string(std::move(data))); - EXPECT_TRUE(IsValidDataFrame(frame)); - EXPECT_TRUE(IsValid(frame)); - - frame.set_frame_type(MultiplexFrame::UNKNOWN_FRAME_TYPE); - EXPECT_FALSE(IsValid(frame)); - - frame.set_frame_type(MultiplexFrame::DATA_FRAME); - auto serialized_bytes = ByteArray(frame.SerializeAsString()); - EXPECT_TRUE(IsMultiplexFrame(std::move(serialized_bytes))); - - EXPECT_TRUE(IsControlFrame(MultiplexFrame::CONTROL_FRAME)); - EXPECT_FALSE(IsControlFrame(MultiplexFrame::DATA_FRAME)); - EXPECT_TRUE(IsDataFrame(MultiplexFrame::DATA_FRAME)); - EXPECT_FALSE(IsDataFrame(MultiplexFrame::UNKNOWN_FRAME_TYPE)); -} - -TEST(MultiplexFrameTest, HashValidtion) { - auto service_id_hash_1 = GenerateServiceIdHash(std::string(kServiceId_1)); - EXPECT_EQ(service_id_hash_1.size(), kServiceIdHashLength); - auto service_id_hash_2 = GenerateServiceIdHash(std::string(kServiceId_2)); - EXPECT_NE(service_id_hash_1, service_id_hash_2); - - auto hash_key_1 = GenerateServiceIdHashKey(service_id_hash_1); - auto hash_key_2 = GenerateServiceIdHashKey(service_id_hash_2); - EXPECT_NE(hash_key_1, hash_key_2); - - auto service_id_hash_with_salt_1 = - GenerateServiceIdHashWithSalt(std::string(kServiceId_1), "1234"); - EXPECT_EQ(service_id_hash_with_salt_1.size(), kServiceIdHashLength); - auto service_id_hash_with_salt_2 = - GenerateServiceIdHashWithSalt(std::string(kServiceId_2), "1234"); - EXPECT_NE(service_id_hash_with_salt_1, service_id_hash_with_salt_2); - service_id_hash_with_salt_2 = - GenerateServiceIdHashWithSalt(std::string(kServiceId_1), "abcd"); - EXPECT_NE(service_id_hash_with_salt_1, service_id_hash_with_salt_2); - - auto hash_key_with_salt_1 = - GenerateServiceIdHashKeyWithSalt(std::string(kServiceId_1), "1234"); - auto hash_key_with_salt_2 = - GenerateServiceIdHashKeyWithSalt(std::string(kServiceId_2), "1234"); - EXPECT_NE(hash_key_with_salt_1, hash_key_with_salt_2); -} - -TEST(MultiplexFrameTest, CanGenerateConnectionRequest) { - ByteArray bytes = ForConnectionRequest(std::string(kServiceId_1), "1234"); - auto request = FromBytes(bytes); - ASSERT_TRUE(request.ok()); - auto frame = request.result(); - EXPECT_EQ(frame.control_frame().control_frame_type(), - MultiplexControlFrame::CONNECTION_REQUEST); - EXPECT_EQ(frame.header().salted_service_id_hash(), - std::string(GenerateServiceIdHashWithSalt(std::string(kServiceId_1), - "1234"))); -} - -TEST(MultiplexFrameTest, CanGenerateConnectionRespons) { - auto service_id_hash_with_salt_2 = - GenerateServiceIdHashWithSalt(std::string(kServiceId_2), "1234"); - ByteArray bytes = - ForConnectionResponse(service_id_hash_with_salt_2, "1234", - ConnectionResponseFrame::CONNECTION_ACCEPTED); - auto response = FromBytes(bytes); - ASSERT_TRUE(response.ok()); - auto frame = response.result(); - EXPECT_EQ(frame.control_frame().control_frame_type(), - MultiplexControlFrame::CONNECTION_RESPONSE); - EXPECT_EQ(frame.header().salted_service_id_hash(), - std::string(service_id_hash_with_salt_2)); - EXPECT_EQ(frame.control_frame() - .connection_response_frame() - .connection_response_code(), - ConnectionResponseFrame::CONNECTION_ACCEPTED); -} - -TEST(MultiplexFrameTest, CanGenerateDisconnection) { - ByteArray bytes = ForDisconnection(std::string(kServiceId_1), "1234"); - auto response = FromBytes(bytes); - ASSERT_TRUE(response.ok()); - auto frame = response.result(); - EXPECT_EQ(frame.control_frame().control_frame_type(), - MultiplexControlFrame::DISCONNECTION); - EXPECT_EQ(frame.header().salted_service_id_hash(), - std::string(GenerateServiceIdHashWithSalt(std::string(kServiceId_1), - "1234"))); -} - -TEST(MultiplexFrameTest, CanGenerateData) { - absl::string_view data = "abcdefghijklmnopqrstuvwxyz"; - ByteArray bytes = - ForData(std::string(kServiceId_1), "1234", true, data); - auto response = FromBytes(bytes); - ASSERT_TRUE(response.ok()); - auto frame = response.result(); - EXPECT_EQ(frame.frame_type(), MultiplexFrame::DATA_FRAME); - EXPECT_EQ(frame.header().salted_service_id_hash(), - std::string(GenerateServiceIdHashWithSalt(std::string(kServiceId_1), - "1234"))); - EXPECT_EQ(frame.data_frame().data(), - std::string("abcdefghijklmnopqrstuvwxyz")); -} - -} // namespace multiplex -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/multiplex/multiplex_output_stream.cc b/connections/implementation/mediums/multiplex/multiplex_output_stream.cc deleted file mode 100644 index 0cdc2d52..00000000 --- a/connections/implementation/mediums/multiplex/multiplex_output_stream.cc +++ /dev/null @@ -1,360 +0,0 @@ -// Copyright 2024 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. - -#include "connections/implementation/mediums/multiplex/multiplex_output_stream.h" - -#include -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "connections/implementation/mediums/multiplex/multiplex_frames.h" -#include "internal/platform/array_blocking_queue.h" -#include "internal/platform/atomic_boolean.h" -#include "internal/platform/base64_utils.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/exception.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/future.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex_lock.h" -#include "internal/platform/output_stream.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace multiplex { -namespace { -using ::location::nearby::mediums::ConnectionResponseFrame; - -constexpr absl::string_view kFakeSalt = "RECEIVER_CONDIMENT"; -} // namespace - -// Implementation for class MultiplexOutputStream -MultiplexOutputStream::MultiplexOutputStream(OutputStream* physical_writer, - AtomicBoolean& is_enabled) - : is_enabled_(is_enabled), - physical_writer_(physical_writer), - multiplex_writer_{physical_writer} {} - -Exception MultiplexOutputStream::WaitForResult(const std::string& method_name, - Future* future) { - if (!future) { - LOG(INFO) << "No future to wait for; return with error."; - return {Exception::kFailed}; - } - LOG(INFO) << "Waiting for future to complete: " << method_name; - ExceptionOr result = - future->Get(FeatureFlags::GetInstance() - .GetFlags() - .mediums_frame_write_timeout_millis); - if (!result.ok()) { - LOG(INFO) << "Future:[" << method_name - << "] completed with exception:" << result.exception(); - return {Exception::kFailed}; - } - if (result.result()) { - LOG(INFO) << "Future:[" << method_name << "] completed with success."; - return {Exception::kSuccess}; - } - LOG(INFO) << "Future:[" << method_name << "] completed with failure."; - return {Exception::kFailed}; -} - -bool MultiplexOutputStream::WriteConnectionRequestFrame( - const std::string& service_id, const std::string& service_id_hash_salt) { - if (!is_enabled_.Get()) { - return false; - } - Future future; - multiplex_writer_.EnqueueToSend( - &future, ForConnectionRequest(service_id, service_id_hash_salt), - "MultiplexFrame::CONNECTION_REQUEST"); - if (WaitForResult("MultiplexFrame::CONNECTION_REQUEST", &future).Ok()) - return true; - return false; -} - -bool MultiplexOutputStream::WriteConnectionResponseFrame( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt, - ConnectionResponseFrame::ConnectionResponseCode response_code) { - if (!is_enabled_.Get()) { - return false; - } - Future future; - multiplex_writer_.EnqueueToSend( - &future, - ForConnectionResponse(salted_service_id_hash, service_id_hash_salt, - response_code), - "MultiplexFrame::CONNECTION_RESPONSE"); - if (WaitForResult("MultiplexFrame::CONNECTION_RESPONSE", &future).Ok()) - return true; - return false; -} - -bool MultiplexOutputStream::Close(const std::string& service_id) { - auto item = virtual_output_streams_.find(service_id); - if (item == virtual_output_streams_.end()) { - LOG(INFO) << "Don't need to close VirtualOutputStream(" << service_id - << ") because it's already gone."; - return false; - } - - item->second->Close(); - if (is_enabled_.Get()) { - Future future; - multiplex_writer_.EnqueueToSend( - &future, - ForDisconnection(service_id, item->second->GetServiceIdHashSalt()), - "MultiplexFrame::DISCONNECTION"); - WaitForResult("MultiplexFrame::DISCONNECTION", &future); - } - virtual_output_streams_.erase(service_id); - if (virtual_output_streams_.empty()) { - physical_writer_->Close(); - multiplex_writer_.Close(); - } - return true; -} - -void MultiplexOutputStream::CloseAll() { - for (auto& [service_id, virtual_output_stream] : virtual_output_streams_) { - if (is_enabled_.Get()) { - Future future; - multiplex_writer_.EnqueueToSend( - &future, - ForDisconnection(service_id, - virtual_output_stream->GetServiceIdHashSalt()), - "MultiplexFrame::DISCONNECTION"); - WaitForResult("MultiplexFrame::DISCONNECTION", &future); - } - virtual_output_stream->Close(); - } - virtual_output_streams_.clear(); - physical_writer_->Close(); - multiplex_writer_.Close(); -} - -OutputStream* -MultiplexOutputStream::CreateVirtualOutputStreamForFirstVirtualSocket( - const std::string& service_id, const std::string& service_id_hash_salt) { - return virtual_output_streams_ - .emplace(service_id, - std::make_unique( - service_id, service_id_hash_salt, physical_writer_, - multiplex_writer_, - VirtualOutputStreamType::kFirstVirtualSocket, *this)) - .first->second.get(); -} - -OutputStream* MultiplexOutputStream::CreateVirtualOutputStream( - const std::string& service_id, const std::string& service_id_hash_salt) { - return virtual_output_streams_ - .emplace(service_id, - std::make_unique( - service_id, service_id_hash_salt, physical_writer_, - multiplex_writer_, - VirtualOutputStreamType::kNormalVirtualSocket, *this)) - .first->second.get(); -} - -std::string MultiplexOutputStream::GetServiceIdHashSalt( - const std::string& service_id) { - auto item = virtual_output_streams_.find(service_id); - if (item != virtual_output_streams_.end()) { - return item->second->GetServiceIdHashSalt(); - } - return {}; -} - -void MultiplexOutputStream::Shutdown() { - physical_writer_->Close(); - multiplex_writer_.Close(); -} - -// Implementation for class MultiplexOutputStream::MultiplexWriter -MultiplexOutputStream::MultiplexWriter::MultiplexWriter( - OutputStream* physical_writer) - : physical_writer_(physical_writer) {} - -MultiplexOutputStream::MultiplexWriter::~MultiplexWriter() { - Close(); - physical_writer_ = nullptr; -} - -void MultiplexOutputStream::MultiplexWriter::EnqueueToSend( - Future* future, const ByteArray& data, - const std::string& frame_name) { - MutexLock lock(&writing_mutex_); - data_queue_.Put(EnqueuedFrame(future, data)); - - if (is_writing_) { - return; - } - is_writing_ = true; - is_writing_cond_.Notify(); - if (!is_write_loop_running_) { - is_write_loop_running_ = true; - writer_thread_.Execute("Start writing", [this] { StartWriting(); }); - } -} - -void MultiplexOutputStream::MultiplexWriter::StartWriting() { - LOG(INFO) << "Writing loop started."; - while (true) { - auto enqueued_frame = data_queue_.TryTake(); - if (enqueued_frame != std::nullopt) { - Write(enqueued_frame.value()); - continue; - } - { - MutexLock lock(&writing_mutex_); - if (data_queue_.Empty() && is_writing_ && !is_closed_) { - is_writing_ = false; - LOG(INFO) << "Waiting for data_queue_ has data."; - Exception wait_succeeded = is_writing_cond_.Wait(); - if (!wait_succeeded.Ok()) { - LOG(WARNING) << "Failure waiting to wait: " << wait_succeeded.value; - return; - } - } - if (is_closed_) { - LOG(INFO) << "Notify to close_writing_thread"; - MutexLock lock(&close_writing_thread_mutex_); - close_writing_thread_cond_.Notify(); - break; - } - } - } - LOG(INFO) << "Writing loop stopped."; -} - -void MultiplexOutputStream::MultiplexWriter::Write( - EnqueuedFrame& enqueued_frame) { - MutexLock lock(&writer_mutex_); - if (!Base64Utils::WriteInt(physical_writer_, enqueued_frame.data_.size()) - .Ok()) { - enqueued_frame.future_->SetException({Exception::kIo}); - return; - }; - if (!physical_writer_->Write(enqueued_frame.data_.AsStringView()).Ok()) { - enqueued_frame.future_->SetException({Exception::kIo}); - return; - }; - if (!physical_writer_->Flush().Ok()) { - enqueued_frame.future_->SetException({Exception::kIo}); - return; - }; - enqueued_frame.future_->Set(true); -} - -void MultiplexOutputStream::MultiplexWriter::Close() { - if (is_closed_) { - LOG(INFO) << "MultiplexWriter is already closed."; - return; - } - LOG(INFO) << "Stop writing loop and Shutdown writer thread."; - { - MutexLock lock(&writing_mutex_); - is_closed_ = true; - if (!is_write_loop_running_) { - writer_thread_.Shutdown(); - return; - } - is_write_loop_running_ = false; - is_writing_cond_.Notify(); - } - LOG(INFO) << "Wait to close_writing_thread"; - { - MutexLock lock(&close_writing_thread_mutex_); - close_writing_thread_cond_.Wait(absl::Milliseconds(20)); - LOG(INFO) << "Shutdown writer thread."; - writer_thread_.Shutdown(); - } -} - -MultiplexOutputStream::VirtualOutputStream::VirtualOutputStream( - std::string service_id, std::string service_id_hash_salt, - OutputStream* physical_writer, MultiplexWriter& multiplex_writer, - VirtualOutputStreamType virtual_output_stream_type, - MultiplexOutputStream& multiplex_output_stream) - : service_id_(service_id), - service_id_hash_salt_(service_id_hash_salt), - physical_writer_(physical_writer), - multiplex_writer_(multiplex_writer), - virtual_output_stream_type_(virtual_output_stream_type), - multiplex_output_stream_(multiplex_output_stream) {} - -Exception MultiplexOutputStream::VirtualOutputStream::Write( - absl::string_view data) { - if (is_closed_.Get()) { - LOG(WARNING) << "Failed to write data because the VirtualOutputStream for " - << service_id_ << " closed"; - return {Exception::kIo}; - } - if (multiplex_output_stream_.is_enabled_.Get()) { - bool should_pass_salt = false; - if (IsFirstVirtualOutputStream()) { - if (!first_frame_sent_for_first_virtual_output_stream_) { - first_frame_sent_for_first_virtual_output_stream_ = true; - should_pass_salt = true; - } - // Fixes b/290724590, b/290983930 which can't get the correct socket - // from the virtualSockets map. NS receiver side will pass 2 - // DATA_FRAMEs continuously to the remote sender side but originally - // impl will only consider the 1st one. Add below fix to handle 2nd - // frame which the salt is still fake one and change shouldPassSalt to - // true to let the remote handle correctly. - if ((service_id_hash_salt_ == kFakeSalt) && !should_pass_salt) { - should_pass_salt = true; - LOG(INFO) << "service_idHashSalt is still a fake one and " - "not changed yet; continue to pass salt."; - } - } - ByteArray data_frame = - ForData(service_id_, service_id_hash_salt_, should_pass_salt, data); - Future future; - multiplex_writer_.EnqueueToSend(&future, data_frame, - "MultiplexFrame::DATA_FRAME"); - return multiplex_output_stream_.WaitForResult("MultiplexFrame::DATA_FRAME", - &future); - } else { - if (!physical_writer_->Write(data).Ok()) { - return {Exception::kIo}; - }; - if (!physical_writer_->Flush().Ok()) { - return {Exception::kIo}; - }; - } - - return {Exception::kSuccess}; -} - -Exception MultiplexOutputStream::VirtualOutputStream::Flush() { - return {Exception::kSuccess}; -} - -Exception MultiplexOutputStream::VirtualOutputStream::Close() { - LOG(INFO) << "MultiplexOutputStream::VirtualOutputStream::Close"; - is_closed_.Set(true); - return {Exception::kSuccess}; -} - -} // namespace multiplex -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/multiplex/multiplex_output_stream.h b/connections/implementation/mediums/multiplex/multiplex_output_stream.h deleted file mode 100644 index 22067d71..00000000 --- a/connections/implementation/mediums/multiplex/multiplex_output_stream.h +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright 2024 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 CORE_INTERNAL_MEDIUMS_MULTIPLEX_MULTIPLEX_OUTPUT_STREAM_H_ -#define CORE_INTERNAL_MEDIUMS_MULTIPLEX_MULTIPLEX_OUTPUT_STREAM_H_ - -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/container/flat_hash_map.h" -#include "absl/strings/string_view.h" -#include "internal/platform/array_blocking_queue.h" -#include "internal/platform/atomic_boolean.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/exception.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/future.h" -#include "internal/platform/mutex.h" -#include "internal/platform/output_stream.h" -#include "internal/platform/single_thread_executor.h" -#include "proto/mediums/multiplex_frames.pb.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace multiplex { -/** - * A helper class to send out the {@code MultiplexControlFrame} and the outgoing - * data from clients. It schedules control and data frames with priority below - * - *

{@link MultiplexControlFrameType#CONNECTION_REQUEST} and {@link - * MultiplexControlFrameType#CONNECTION_RESPONSE} have the highest priority - * - *

All {@link MultiplexDataFrame} has the medium priority. If there's - * multiple clients send data at the same time, should poll every client's - * outgoing data in sequence. For example, client A and B send data at the same - * time, the outgoing data sequence should like A-Frame-1, B-Frame-1, A-Frame-2, - * B-Frame-2,... - * - *

{@link MultiplexControlFrameType#DISCONNECTION} has the same priority with - * {@link MultiplexDataFrame} because the disconnect should not make the already - * enqueued data failed to send out, so put it in the same priority queue with - * the MultiplexDataFrame. - */ -class MultiplexOutputStream { - public: - enum class VirtualOutputStreamType { - // The type of virtual socket established for the physical socket is - // created. - kFirstVirtualSocket = 0, - // The others except FIRST_VIRTUAL_SCOKET type. - kNormalVirtualSocket = 1, - }; - - MultiplexOutputStream(OutputStream* physical_writer, - AtomicBoolean& is_enabled); - ~MultiplexOutputStream() = default; - - // Writes the connection request frame to the physical output stream. - bool WriteConnectionRequestFrame(const std::string& service_id, - const std::string& service_id_hash_salt); - - // Writes the connection response frame to the physical output stream. - bool WriteConnectionResponseFrame( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt, - ::location::nearby::mediums::ConnectionResponseFrame:: - ConnectionResponseCode response_code); - - // Closes the virtual output stream. - bool Close(const std::string& service_id); - - // Closes all virtual output streams. - void CloseAll(); - - // Waits for the result of the future. - Exception WaitForResult(const std::string& method_name, Future* future); - - // Creates the virtual output stream for the first virtual socket. - OutputStream* CreateVirtualOutputStreamForFirstVirtualSocket( - const std::string& service_id, const std::string& service_id_hash_salt); - - // Creates the virtual output stream. - OutputStream* CreateVirtualOutputStream( - const std::string& service_id, const std::string& service_id_hash_salt); - - // Gets the service id hash salt. - std::string GetServiceIdHashSalt(const std::string& service_id); - - // Shuts down the multiplex output stream. - void Shutdown(); - - class EnqueuedFrame { - public: - EnqueuedFrame(Future* future, ByteArray data) - : future_(future), data_(data) {} - ~EnqueuedFrame() = default; - - Future* future_; - ByteArray data_; - }; - - class MultiplexWriter { - public: - explicit MultiplexWriter(OutputStream* physical_writer); - ~MultiplexWriter(); - - // Enqueues the frame to be sent out. - void EnqueueToSend(Future* future, const ByteArray& data, - const std::string& frame_name); - // Closes the writer. - void Close(); - - private: - // Starts the writer thread. - void StartWriting(); - - // Writes the enqueued frame. - void Write(EnqueuedFrame& enqueued_frame); - - Mutex writer_mutex_; - OutputStream* physical_writer_ ABSL_PT_GUARDED_BY(writer_mutex_); - - ArrayBlockingQueue data_queue_{ - FeatureFlags::GetInstance() - .GetFlags() - .multiplex_socket_middle_priority_queue_capacity}; - mutable Mutex writing_mutex_; - ConditionVariable is_writing_cond_{&writing_mutex_}; - bool is_writing_ ABSL_GUARDED_BY(writing_mutex_) = false; - bool is_closed_ = false; - mutable Mutex close_writing_thread_mutex_; - ConditionVariable close_writing_thread_cond_{&close_writing_thread_mutex_}; - - // The single thread to write all enqueued frames. - SingleThreadExecutor writer_thread_; - bool is_write_loop_running_ = false; - }; - - class VirtualOutputStream : public OutputStream { - public: - VirtualOutputStream(std::string service_id, - std::string service_id_hash_salt, - OutputStream* physical_writer, - MultiplexWriter& multiplex_writer, - VirtualOutputStreamType virtual_output_stream_type, - MultiplexOutputStream& multiplex_output_stream); - ~VirtualOutputStream() override = default; - - // Returns true if the virtual output stream is the first virtual output - // stream. - bool IsFirstVirtualOutputStream() { - return virtual_output_stream_type_ == - VirtualOutputStreamType::kFirstVirtualSocket; - } - - // Returns the service id hash salt. - std::string GetServiceIdHashSalt() { return service_id_hash_salt_; } - - // Sets the service id hash salt. - void SetserviceIdHashSalt(std::string service_id_hash_salt) { - service_id_hash_salt_ = service_id_hash_salt; - } - - // Writes the data to the physical output stream. - Exception Write(absl::string_view data) override; - // Flushes the physical output stream. - Exception Flush() override; - // Closes the virtual output stream. - Exception Close() override; - - private: - AtomicBoolean is_closed_{false}; - - std::string service_id_; - std::string service_id_hash_salt_; - OutputStream* physical_writer_; - MultiplexWriter& multiplex_writer_; - VirtualOutputStreamType virtual_output_stream_type_; - bool first_frame_sent_for_first_virtual_output_stream_ = false; - MultiplexOutputStream& multiplex_output_stream_; - }; - - private: - AtomicBoolean& is_enabled_; - OutputStream* physical_writer_; - absl::flat_hash_map> - virtual_output_streams_; - MultiplexWriter multiplex_writer_; -}; - -} // namespace multiplex -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_MULTIPLEX_MULTIPLEX_OUTPUT_STREAM_H_ diff --git a/connections/implementation/mediums/multiplex/multiplex_output_stream_test.cc b/connections/implementation/mediums/multiplex/multiplex_output_stream_test.cc deleted file mode 100644 index 4a5ae130..00000000 --- a/connections/implementation/mediums/multiplex/multiplex_output_stream_test.cc +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright 2024 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. - -#include "connections/implementation/mediums/multiplex/multiplex_output_stream.h" - -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "connections/implementation/mediums/multiplex/multiplex_frames.h" -#include "internal/platform/atomic_boolean.h" -#include "internal/platform/base64_utils.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/exception.h" -#include "internal/platform/input_stream.h" -#include "internal/platform/logging.h" -#include "internal/platform/multi_thread_executor.h" -#include "internal/platform/output_stream.h" -#include "internal/platform/pipe.h" -#include "proto/mediums/multiplex_frames.pb.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace multiplex { - -constexpr absl::string_view kServiceId_1 = "serviceId_1"; -constexpr absl::string_view kServiceId_2 = "serviceId_2"; -constexpr absl::string_view kNoSalt = ""; -constexpr absl::string_view kSalt_1 = "DNFG"; -constexpr absl::string_view kSalt_2 = "YFRT"; - -using ::location::nearby::mediums::ConnectionResponseFrame; -using ::location::nearby::mediums::MultiplexControlFrame; -using ::location::nearby::mediums::MultiplexFrame; - -class MultiplexOutputStreamTest : public ::testing::Test { - protected: - ExceptionOr ReadFrame() { - ExceptionOr read_int = Base64Utils::ReadInt(reader_.get()); - if (!read_int.ok()) return read_int.GetException(); - if (read_int.result() <= 0) return {Exception::kFailed}; - - ExceptionOr received_data = - reader_->ReadExactly(read_int.result()); - if (!received_data.ok()) return received_data.GetException(); - auto bytes = std::move(received_data.result()); - return FromBytes(bytes); - } - - AtomicBoolean enabled_{true}; - std::pair, std::unique_ptr> pipe_ = - CreatePipe(); - - std::unique_ptr reader_ = std::move(pipe_.first); - std::unique_ptr writer_ = std::move(pipe_.second); - std::unique_ptr multiplex_output_stream_; -}; - -TEST_F(MultiplexOutputStreamTest, SendConnectionRequestFrame) { - multiplex_output_stream_ = - std::make_unique(writer_.get(), enabled_); - EXPECT_TRUE(multiplex_output_stream_->WriteConnectionRequestFrame( - std::string(kServiceId_1), std::string(kNoSalt))); - - auto request = ReadFrame(); - ASSERT_TRUE(request.ok()); - auto frame = request.result(); - EXPECT_EQ(frame.control_frame().control_frame_type(), - MultiplexControlFrame::CONNECTION_REQUEST); - EXPECT_EQ(frame.header().salted_service_id_hash(), - std::string(GenerateServiceIdHashWithSalt(std::string(kServiceId_1), - std::string(kNoSalt)))); - - multiplex_output_stream_->Shutdown(); -} - -TEST_F(MultiplexOutputStreamTest, SendConnectionRequestFrameDisabled) { - enabled_.Set(false); - multiplex_output_stream_ = - std::make_unique(writer_.get(), enabled_); - EXPECT_FALSE(multiplex_output_stream_->WriteConnectionRequestFrame( - std::string(kServiceId_1), std::string(kNoSalt))); - - multiplex_output_stream_->Shutdown(); -} - -TEST_F(MultiplexOutputStreamTest, SendConnectionResponseFrame) { - multiplex_output_stream_ = - std::make_unique(writer_.get(), enabled_); - EXPECT_TRUE(multiplex_output_stream_->WriteConnectionResponseFrame( - GenerateServiceIdHash(std::string(kServiceId_1)), std::string(kNoSalt), - ConnectionResponseFrame::CONNECTION_ACCEPTED)); - - auto response = ReadFrame(); - ASSERT_TRUE(response.ok()); - auto frame = response.result(); - EXPECT_EQ(frame.control_frame().control_frame_type(), - MultiplexControlFrame::CONNECTION_RESPONSE); - EXPECT_EQ(frame.header().salted_service_id_hash(), - std::string(GenerateServiceIdHashWithSalt(std::string(kServiceId_1), - std::string(kNoSalt)))); - EXPECT_EQ(frame.control_frame() - .connection_response_frame() - .connection_response_code(), - ConnectionResponseFrame::CONNECTION_ACCEPTED); - - multiplex_output_stream_->Shutdown(); -} - -TEST_F(MultiplexOutputStreamTest, SendConnectionResponseFrameDisabled) { - enabled_.Set(false); - multiplex_output_stream_ = - std::make_unique(writer_.get(), enabled_); - EXPECT_FALSE(multiplex_output_stream_->WriteConnectionResponseFrame( - GenerateServiceIdHash(std::string(kServiceId_1)), std::string(kNoSalt), - ConnectionResponseFrame::CONNECTION_ACCEPTED)); - - multiplex_output_stream_->Shutdown(); -} - -TEST_F(MultiplexOutputStreamTest, CloseVirtualStreamFailed) { - multiplex_output_stream_ = - std::make_unique(writer_.get(), enabled_); - EXPECT_FALSE(multiplex_output_stream_->Close(std::string(kServiceId_1))); - - multiplex_output_stream_->Shutdown(); -} - -TEST_F(MultiplexOutputStreamTest, CloseVirtualStreamSuccess) { - multiplex_output_stream_ = - std::make_unique(writer_.get(), enabled_); - EXPECT_FALSE(multiplex_output_stream_->Close(std::string(kServiceId_1))); - - multiplex_output_stream_->CreateVirtualOutputStream(std::string(kServiceId_1), - std::string(kNoSalt)); - EXPECT_TRUE(multiplex_output_stream_->Close(std::string(kServiceId_1))); - - auto request = ReadFrame(); - ASSERT_TRUE(request.ok()); - auto frame = request.result(); - EXPECT_EQ(frame.control_frame().control_frame_type(), - MultiplexControlFrame::DISCONNECTION); - EXPECT_EQ(frame.header().salted_service_id_hash(), - std::string(GenerateServiceIdHashWithSalt(std::string(kServiceId_1), - std::string(kNoSalt)))); - - multiplex_output_stream_->Shutdown(); -} - -TEST_F(MultiplexOutputStreamTest, CreateVirtualStream_SendData) { - multiplex_output_stream_ = - std::make_unique(writer_.get(), enabled_); - - auto virtual_output_stream = - multiplex_output_stream_->CreateVirtualOutputStream( - std::string(kServiceId_1), std::string(kSalt_1)); - - absl::string_view data = "abcdefghijklmnopqrstuvwxyz"; - virtual_output_stream->Write(data); - virtual_output_stream->Flush(); - auto frame_data = ReadFrame(); - ASSERT_TRUE(frame_data.ok()); - auto frame = frame_data.result(); - EXPECT_EQ(frame.frame_type(), MultiplexFrame::DATA_FRAME); - EXPECT_EQ(frame.header().salted_service_id_hash(), - std::string(GenerateServiceIdHashWithSalt(std::string(kServiceId_1), - std::string(kSalt_1)))); - EXPECT_EQ(frame.data_frame().data(), std::string(data)); - - multiplex_output_stream_->Shutdown(); -} - -TEST_F(MultiplexOutputStreamTest, CreateTwoVirtualStreams_SendData) { - multiplex_output_stream_ = - std::make_unique(writer_.get(), enabled_); - - auto virtual_output_stream_1 = - multiplex_output_stream_->CreateVirtualOutputStreamForFirstVirtualSocket( - std::string(kServiceId_1), std::string(kSalt_1)); - auto virtual_output_stream_2 = - multiplex_output_stream_->CreateVirtualOutputStreamForFirstVirtualSocket( - std::string(kServiceId_2), std::string(kSalt_2)); - - absl::string_view data_1("abcdefg"); - absl::string_view data_2("hijklmn"); - MultiThreadExecutor executor(2); - CountDownLatch latch(2); - executor.Execute([&virtual_output_stream_1, &latch, &data_1]() { - absl::SleepFor(absl::Milliseconds(100)); - virtual_output_stream_1->Write(data_1); - virtual_output_stream_1->Flush(); - latch.CountDown(); - }); - executor.Execute([&virtual_output_stream_2, &latch, &data_2]() { - virtual_output_stream_2->Write(data_2); - virtual_output_stream_2->Flush(); - latch.CountDown(); - }); - EXPECT_TRUE(latch.Await(absl::Milliseconds(5000)).result()); - - auto frame_data = ReadFrame(); - ASSERT_TRUE(frame_data.ok()); - auto frame = frame_data.result(); - EXPECT_EQ(frame.frame_type(), MultiplexFrame::DATA_FRAME); - bool first_frame_is_data_1 = true; - if (frame.header().salted_service_id_hash() == - std::string(GenerateServiceIdHashWithSalt(std::string(kServiceId_1), - std::string(kSalt_1)))) { - EXPECT_EQ(frame.data_frame().data(), std::string(data_1)); - LOG(INFO) << "Read first virtual stream frame first."; - } else { - EXPECT_EQ(frame.header().salted_service_id_hash(), - std::string(GenerateServiceIdHashWithSalt( - std::string(kServiceId_2), std::string(kSalt_2)))); - EXPECT_EQ(frame.data_frame().data(), std::string(data_2)); - first_frame_is_data_1 = false; - LOG(INFO) << "Read second virtual stream frame first."; - } - - frame_data = ReadFrame(); - ASSERT_TRUE(frame_data.ok()); - frame = frame_data.result(); - EXPECT_EQ(frame.frame_type(), MultiplexFrame::DATA_FRAME); - if (first_frame_is_data_1) { - EXPECT_EQ(frame.data_frame().data(), std::string(data_2)); - } else { - EXPECT_EQ(frame.data_frame().data(), std::string(data_1)); - } - multiplex_output_stream_->Shutdown(); -} - -} // namespace multiplex -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/multiplex/multiplex_socket.cc b/connections/implementation/mediums/multiplex/multiplex_socket.cc deleted file mode 100644 index 888efb82..00000000 --- a/connections/implementation/mediums/multiplex/multiplex_socket.cc +++ /dev/null @@ -1,818 +0,0 @@ -// Copyright 2024 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. - -#include "connections/implementation/mediums/multiplex/multiplex_socket.h" - -#include -#include -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "connections/implementation/mediums/multiplex/multiplex_frames.h" -#include "connections/implementation/mediums/multiplex/multiplex_output_stream.h" -#include "connections/implementation/mediums/utils.h" -#include "internal/platform/atomic_boolean.h" -#include "internal/platform/base64_utils.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/exception.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/future.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex.h" -#include "internal/platform/mutex_lock.h" -#include "internal/platform/socket.h" -#include "internal/platform/types.h" -#include "proto/connections_enums.pb.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace multiplex { - -namespace { -// It is defined for the receiver which send the first packet to the sender -// without getting salt from it yet. The fake salt reminds sender to get the -// correct socket from `virtualSockets` without remapping it. -constexpr absl::string_view kFakeSalt = "RECEIVER_CONDIMENT"; - -// The max duration to wait for the reader thread to stop. -constexpr absl::Duration kTimeoutForReaderThreadStop = absl::Milliseconds(100); - -} // namespace - -using ::location::nearby::mediums::ConnectionResponseFrame; -using ::location::nearby::mediums::MultiplexControlFrame; -using ::location::nearby::mediums::MultiplexDataFrame; -using ::location::nearby::mediums::MultiplexFrame; -using ::location::nearby::proto::connections::Medium; -using ::location::nearby::proto::connections::Medium_Name; -using ConnectionResponseCode = ConnectionResponseFrame::ConnectionResponseCode; - -// AtomicBoolean is trivial destructible, so it is safe to use it as a static -// variable. -AtomicBoolean MultiplexSocket::is_shutting_down_{false}; // NOLINT - -void MultiplexSocket::ListenForIncomingConnection( - const std::string& service_id, Medium type, - MultiplexIncomingConnectionCb incoming_connection_cb) { - GetIncomingConnectionCallbacks().emplace( - std::pair(service_id, type), - std::move(incoming_connection_cb)); -} - -void MultiplexSocket::StopListeningForIncomingConnection( - const std::string& service_id, Medium type) { - GetIncomingConnectionCallbacks().erase( - std::pair(service_id, type)); -} - -MultiplexSocket::MultiplexSocket(std::shared_ptr physical_socket) - : physical_socket_ptr_(physical_socket), - multiplex_output_stream_{&physical_socket_ptr_->GetOutputStream(), - enabled_}, - physical_reader_(&physical_socket_ptr_->GetInputStream()), - medium_(physical_socket_ptr_->GetMedium()) {} - -absl::flat_hash_map, - MultiplexIncomingConnectionCb>& -MultiplexSocket::GetIncomingConnectionCallbacks() { - using MapType = absl::flat_hash_map, - MultiplexIncomingConnectionCb>; - alignas(MapType) static char storage[sizeof(MapType)]; - static MapType* incoming_connection_callbacks = new (&storage) MapType(); - - return *incoming_connection_callbacks; -} - -MultiplexSocket* MultiplexSocket::CreateIncomingSocket( - std::shared_ptr physical_socket, - const std::string& service_id, std::int32_t first_frame_len) { - while (is_shutting_down_.Get()) { - LOG(WARNING) - << "Shutting down is going on, wait for 2ms to create incoming socket"; - absl::SleepFor(absl::Milliseconds(2)); - } - - MultiplexSocket* multiplex_incoming_socket = nullptr; - static MultiplexSocket* multiplex_incoming_socket_bt = nullptr; - static MultiplexSocket* multiplex_incoming_socket_wlan = nullptr; - - switch (physical_socket->GetMedium()) { - case Medium::BLUETOOTH: - if (multiplex_incoming_socket_bt != nullptr) { - LOG(INFO) << "Multiplex incoming socket already exists for BT"; - return multiplex_incoming_socket_bt; - } - alignas(MultiplexSocket) static char storage_bt[sizeof(MultiplexSocket)]; - multiplex_incoming_socket_bt = - new (&storage_bt) MultiplexSocket(physical_socket); - multiplex_incoming_socket = multiplex_incoming_socket_bt; - break; - case Medium::WIFI_LAN: - case Medium::AWDL: - if (multiplex_incoming_socket_wlan != nullptr) { - LOG(INFO) << "Multiplex incoming socket already exists for WLAN"; - return multiplex_incoming_socket_wlan; - } - alignas( - MultiplexSocket) static char storage_wlan[sizeof(MultiplexSocket)]; - multiplex_incoming_socket_wlan = - new (&storage_wlan) MultiplexSocket(physical_socket); - multiplex_incoming_socket = multiplex_incoming_socket_wlan; - break; - default: - LOG(ERROR) << __func__ - << "Unsupported medium: " << physical_socket->GetMedium(); - multiplex_incoming_socket = nullptr; - return multiplex_incoming_socket; - } - LOG(INFO) << "CreateIncomingSocket with serviceId=" << service_id - << ", serviceIdHashSalt=" << kFakeSalt - << " for medium=" << Medium_Name(physical_socket->GetMedium()); - - multiplex_incoming_socket->CreateFirstVirtualSocket(service_id, - (std::string)kFakeSalt); - multiplex_incoming_socket->StartReaderThread(first_frame_len); - - return multiplex_incoming_socket; -} - -MultiplexSocket* MultiplexSocket::CreateOutgoingSocket( - std::shared_ptr physical_socket, - const std::string& service_id, const std::string& service_id_hash_salt) { - while (is_shutting_down_.Get()) { - LOG(WARNING) - << "Shutting down is going on, wait for 2ms to create outgoing socket"; - absl::SleepFor(absl::Milliseconds(2)); - } - - MultiplexSocket* multiplex_outgoing_socket = nullptr; - static MultiplexSocket* multiplex_outgoing_socket_bt = nullptr; - static MultiplexSocket* multiplex_outgoing_socket_wlan = nullptr; - - switch (physical_socket->GetMedium()) { - case Medium::BLUETOOTH: - if (multiplex_outgoing_socket_bt != nullptr) { - LOG(INFO) << "Multiplex outgoing socket already exists for BT"; - return multiplex_outgoing_socket_bt; - } - alignas(MultiplexSocket) static char storage_bt[sizeof(MultiplexSocket)]; - multiplex_outgoing_socket_bt = - new (&storage_bt) MultiplexSocket(physical_socket); - multiplex_outgoing_socket = multiplex_outgoing_socket_bt; - break; - case Medium::WIFI_LAN: - case Medium::AWDL: - if (multiplex_outgoing_socket_wlan != nullptr) { - LOG(INFO) << "Multiplex outgoing socket already exists for WLAN"; - return multiplex_outgoing_socket_wlan; - } - alignas( - MultiplexSocket) static char storage_wlan[sizeof(MultiplexSocket)]; - multiplex_outgoing_socket_wlan = - new (&storage_wlan) MultiplexSocket(physical_socket); - multiplex_outgoing_socket = multiplex_outgoing_socket_wlan; - break; - default: - LOG(ERROR) << __func__ - << "Unsupported medium: " << physical_socket->GetMedium(); - multiplex_outgoing_socket = nullptr; - return multiplex_outgoing_socket; - } - LOG(INFO) << "CreateOutgoingSocket with serviceId=" << service_id - << ", serviceIdHashSalt=" << service_id_hash_salt - << " for medium=" << Medium_Name(physical_socket->GetMedium()); - - multiplex_outgoing_socket->CreateFirstVirtualSocket(service_id, - service_id_hash_salt); - multiplex_outgoing_socket->StartReaderThread(0); - return multiplex_outgoing_socket; -} - -MultiplexSocket* MultiplexSocket::CreateOutgoingSocket( - std::shared_ptr physical_socket, - const std::string& service_id) { - return CreateOutgoingSocket(physical_socket, service_id, - Utils::GenerateSalt()); -} - -std::shared_ptr MultiplexSocket::CreateFirstVirtualSocket( - const std::string& service_id, const std::string& service_id_hash_salt) { - auto output_stream = - multiplex_output_stream_.CreateVirtualOutputStreamForFirstVirtualSocket( - service_id, service_id_hash_salt); - - MutexLock lock(&virtual_socket_mutex_); - std::string salted_service_id_hash_key = - GenerateServiceIdHashKeyWithSalt(service_id, service_id_hash_salt); - LOG(INFO) << __func__ << " for service_id=" << service_id - << ", salt=" << service_id_hash_salt - << ", salted_service_id_hash_key=" << salted_service_id_hash_key; - MediumSocket* virtual_socket_ptr = physical_socket_ptr_->CreateVirtualSocket( - salted_service_id_hash_key, output_stream, medium_, &virtual_sockets_); - - if (virtual_socket_ptr == nullptr) { - return nullptr; - } - std::shared_ptr virtual_socket = - virtual_sockets_[salted_service_id_hash_key]; - virtual_socket->AddOnSocketClosedListener( - std::make_unique>( - [this, service_id]() { OnVirtualSocketClosed(service_id); })); - - if (!IsEnabled()) { - LOG(INFO) << __func__ << ": Register multiplex enabled callback"; - virtual_socket->RegisterMultiplexEnabledCallback(enable_cb_); - } - - return virtual_socket; -} - -std::shared_ptr MultiplexSocket::CreateVirtualSocket( - const std::string& service_id, const std::string& service_id_hash_salt) { - auto output_stream = multiplex_output_stream_.CreateVirtualOutputStream( - service_id, service_id_hash_salt); - MutexLock lock(&virtual_socket_mutex_); - std::string salted_service_id_hash_key = - GenerateServiceIdHashKeyWithSalt(service_id, service_id_hash_salt); - - LOG(INFO) << __func__ << "service_id=" << service_id - << ", salt=" << service_id_hash_salt - << ", salted_service_id_hash_key=" << salted_service_id_hash_key; - - MediumSocket* virtual_socket_ptr = physical_socket_ptr_->CreateVirtualSocket( - salted_service_id_hash_key, output_stream, medium_, &virtual_sockets_); - - if (virtual_socket_ptr == nullptr) { - return nullptr; - } - std::shared_ptr virtual_socket = - virtual_sockets_[salted_service_id_hash_key]; - virtual_socket->AddOnSocketClosedListener( - std::make_unique>( - [this, service_id]() { OnVirtualSocketClosed(service_id); })); - - return virtual_socket; -} - -std::shared_ptr MultiplexSocket::GetVirtualSocket( - const std::string& service_id) { - MutexLock lock(&virtual_socket_mutex_); - LOG(INFO) << __func__ << " service_id=" << service_id << ", Salt=" - << multiplex_output_stream_.GetServiceIdHashSalt(service_id) - << ", virtual_sockets_.size()=" << virtual_sockets_.size(); - auto item = virtual_sockets_.find(GenerateServiceIdHashKeyWithSalt( - service_id, multiplex_output_stream_.GetServiceIdHashSalt(service_id))); - if (item == virtual_sockets_.end()) { - LOG(INFO) << "Not found!"; - return nullptr; - } - return item->second; -} - -int MultiplexSocket::GetVirtualSocketCount() { - MutexLock lock(&virtual_socket_mutex_); - return virtual_sockets_.size(); -} - -void MultiplexSocket::ListVirtualSocket() { - LOG(INFO) << __func__ - << " virtual_sockets_.size()=" << virtual_sockets_.size(); - for (auto& [service_id_hash_key, virtual_socket] : virtual_sockets_) { - LOG(INFO) << __func__ << " service_id_hash_key=" << service_id_hash_key - << ", virtual_socket=" << virtual_socket; - } -} - -std::shared_ptr> -MultiplexSocket::RegisterConnectionResponse(const std::string& service_id) { - auto future = std::make_shared>(); - connection_response_futures_.emplace(service_id, future); - - return future; -} - -void MultiplexSocket::UnRegisterConnectionResponse( - const std::string& service_id) { - connection_response_futures_.erase(service_id); -} - -std::shared_ptr MultiplexSocket::EstablishVirtualSocket( - const std::string& service_id) { - if (!IsEnabled()) { - LOG(ERROR) - << "MultiplexSocket is disabled, cannot establish virtual socket."; - return nullptr; - } - - std::string service_id_hash_salt = Utils::GenerateSalt(); - auto future = RegisterConnectionResponse(service_id); - - multiplex_output_stream_.WriteConnectionRequestFrame(service_id, - service_id_hash_salt); - auto result = - future->Get(FeatureFlags::GetInstance() - .GetFlags() - .multiplex_socket_connection_response_timeout_millis); - if (!result.ok()) { - LOG(ERROR) << __func__ - << "EstablishVirtualSocket failed with response code=" - << result.exception(); - return nullptr; - } - - ConnectionResponseCode response_code = result.GetResult(); - switch (response_code) { - case ConnectionResponseFrame::CONNECTION_ACCEPTED: - LOG(INFO) << "EstablishVirtualSocket after remote response to" - " accept the connection with service_id=" - << service_id - << ", service_id_hash_salt=" << service_id_hash_salt; - return CreateVirtualSocket(service_id, service_id_hash_salt); - case ConnectionResponseFrame::NOT_LISTENING: - LOG(ERROR) << "EstablishVirtualSocket failed for service_id=" - << service_id - << ", service_id_hash_salt=" << service_id_hash_salt - << " with response code=NOT_LISTENING"; - break; - default: - LOG(ERROR) << "EstablishVirtualSocket failed for service_id=" - << service_id - << ", service_id_hash_salt=" << service_id_hash_salt - << " with response code=UNKNOWN_RESPONSE_CODE"; - break; - } - return nullptr; -} - -void MultiplexSocket::StartReaderThread(std::int32_t first_frame_len) { - if (is_shutdown_) { - LOG(WARNING) << "Stop to start reader thread since socket is " - "shutdown."; - return; - } - reader_thread_shutdown_barrier_ = std::make_unique(1); - physical_reader_thread_.Execute([this, first_frame_len]() { - LOG(INFO) << __func__ << " Reader thread starts."; - auto first_frame_len_copy = first_frame_len; - while (!is_shutdown_) { - bool fail = false; - ExceptionOr bytes; - ExceptionOr read_int; - if (first_frame_len_copy > 0) { - read_int = ExceptionOr(first_frame_len); - first_frame_len_copy = 0; - } else { - read_int = Base64Utils::ReadInt(physical_reader_); - } - if (!read_int.ok()) { - LOG(WARNING) << __func__ - << "Failed to read. Exception:" << read_int.exception(); - fail = true; - } else { - auto length = read_int.result(); - VLOG(1) << __func__ << " length:" << length; - - if (length < 0 || length > FeatureFlags::GetInstance() - .GetFlags() - .connection_max_frame_length) { - // Ignore the failure because not only one client use this - // connection. - LOG(WARNING) << __func__ - << "Failed to read because received a invalid length " - << length << ", but continue to read."; - continue; - } - - bytes = physical_reader_->ReadExactly(length); - if (!bytes.ok()) { - LOG(WARNING) << __func__ - << "Read data exception:" << bytes.exception(); - fail = true; - } - } - if (fail) { - reader_thread_shutdown_barrier_->CountDown(); - return; - } - - ExceptionOr frame_exc = - multiplex::FromBytes(bytes.result()); - if (!frame_exc.ok()) { - HandleOfflineFrame(bytes.result()); - continue; - } - - if (!IsEnabled()) { - // The reader thread will only be enabled when local device - // supports multiplex if we received a multiplex frame from - // the remote, it means that the remote and the local both - // support multiplex as well. So it is safe to just turn on - // the feature at this point. - LOG(INFO) << __func__ - << " Received a multiplex frame while not enabled, enable " - "multiplex."; - Enable(); - } - const auto& frame = frame_exc.result(); - auto salted_service_id_hash = - ByteArray{std::move(frame.header().salted_service_id_hash())}; - auto service_id_hash_salt = frame.header().has_service_id_hash_salt() - ? frame.header().service_id_hash_salt() - : ""; - switch (frame.frame_type()) { - case MultiplexFrame::CONTROL_FRAME: - HandleControlFrame(salted_service_id_hash, service_id_hash_salt, - frame.control_frame()); - break; - case MultiplexFrame::DATA_FRAME: - VLOG(1) << "service_id_hash_salt: " << service_id_hash_salt; - HandleDataFrame(salted_service_id_hash, service_id_hash_salt, - frame.data_frame()); - break; - default: - LOG(WARNING) << __func__ - << " Received MultiplexFrame with unknown frame type " - << frame.frame_type(); - } - } - }); -} - -void MultiplexSocket::HandleOfflineFrame(const ByteArray& bytes) { - MutexLock lock(&virtual_socket_mutex_); - LOG(INFO) << __func__ << " Virtual_socket num:" << virtual_sockets_.size(); - if (virtual_sockets_.size() == 1) { - auto item = virtual_sockets_.begin(); - if (item->second == nullptr) { - LOG(WARNING) << "Expected one live socket, but found null."; - return; - } - LOG(INFO) << __func__ << "FeedIncomingData:" << std::string(bytes); - item->second->FeedIncomingData(Base64Utils::IntToBytes(bytes.size())); - item->second->FeedIncomingData(bytes); - } -} - -void MultiplexSocket::HandleControlFrame( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt, - const MultiplexControlFrame& frame) { - switch (frame.control_frame_type()) { - case MultiplexControlFrame::CONNECTION_REQUEST: - RunOffloadThread("CONNECTION_REQUEST", [this, salted_service_id_hash, - service_id_hash_salt] { - HandleConnectionRequest(salted_service_id_hash, service_id_hash_salt); - }); - break; - case MultiplexControlFrame::CONNECTION_RESPONSE: - LOG(INFO) << __func__ << "Received an CONNECTION_RESPONSE frame." - << " salted_service_id_hash: " - << std::string(salted_service_id_hash) - << ", service_id_hash_salt: " << service_id_hash_salt - << ", ConnectionResponseCode: " - << frame.connection_response_frame().connection_response_code(); - - RunOffloadThread("CONNECTION_RESPONSE", [this, salted_service_id_hash, - service_id_hash_salt, - frame = frame] { - HandleConnectionResponse(salted_service_id_hash, service_id_hash_salt, - frame.connection_response_frame()); - }); - break; - case MultiplexControlFrame::DISCONNECTION: - // The virtual socket will be closed in the offload thread, so don't run - // the thread here. - HandleDisconnection(salted_service_id_hash); - break; - default: - LOG(WARNING) << __func__ << "Received an unknown frame type " - << frame.control_frame_type(); - break; - } -} - -void MultiplexSocket::HandleConnectionRequest( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt) { - if (!IsEnabled()) { - LOG(WARNING) << "Received a CONNECTION_REQUEST frame on medium " - << Medium_Name(medium_) - << " but status is disabled, ignore it."; - return; - } - - std::string salted_service_id_hash_key = - GenerateServiceIdHashKey(salted_service_id_hash); - MultiplexIncomingConnectionCb* incoming_connection_callback = nullptr; - std::string listening_service_id = ""; - for (auto& [service_id_medium_pair, callback] : - GetIncomingConnectionCallbacks()) { - if (GenerateServiceIdHashWithSalt(service_id_medium_pair.first, - service_id_hash_salt) == - salted_service_id_hash) { - incoming_connection_callback = &callback; - listening_service_id = service_id_medium_pair.first; - } - } - - if (incoming_connection_callback == nullptr || listening_service_id.empty()) { - LOG(INFO) << "There's no client listening for hash salt : " - << service_id_hash_salt - << ", hash key : " << salted_service_id_hash_key << " on medium " - << Medium_Name(medium_); - - LOG(INFO) << "The size of incomingConnectionCallbacks : " - << GetIncomingConnectionCallbacks().size(); - if (!multiplex_output_stream_.WriteConnectionResponseFrame( - salted_service_id_hash, service_id_hash_salt, - ConnectionResponseFrame::NOT_LISTENING)) { - LOG(INFO) << __func__ << "Failed to write NOT_LISTENING frame."; - } - return; - } - LOG(INFO) << "Accept new virtual socket request service ID : " - << listening_service_id << ", hash salt : " << service_id_hash_salt - << ", hash key : " << salted_service_id_hash_key << " on medium " - << Medium_Name(medium_); - - if (!multiplex_output_stream_.WriteConnectionResponseFrame( - salted_service_id_hash, service_id_hash_salt, - ConnectionResponseFrame::CONNECTION_ACCEPTED)) { - LOG(INFO) << "Failed to write CONNECTION_ACCEPTED frame."; - return; - } - - LOG(INFO) - << "EstablishVirtualSocket after local device accept the connection " - "with serviceId=" - << listening_service_id; - std::shared_ptr virtual_socket = - CreateVirtualSocket(listening_service_id, service_id_hash_salt); - (*incoming_connection_callback)(std::move(listening_service_id), - virtual_socket); -} - -void MultiplexSocket::HandleConnectionResponse( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt, - const ConnectionResponseFrame& frame) { - LOG(INFO) << __func__ - << "connection_response_code: " << frame.connection_response_code(); - for (auto& [service_id, future] : connection_response_futures_) { - if (GenerateServiceIdHashWithSalt(service_id, service_id_hash_salt) == - salted_service_id_hash) { - if (future != nullptr) { - future->Set(frame.connection_response_code()); - LOG(INFO) << __func__ << "Set the future for serviceId=" << service_id - << ", serviceIdHashSalt=" << service_id_hash_salt - << " with response code=" << frame.connection_response_code(); - return; - } - } - } - - LOG(WARNING) - << __func__ - << "Received a CONNECTION_RESPONSE frame but no client waiting for " - "service ID Hash Key" - << GenerateServiceIdHashKey(salted_service_id_hash); -} - -void MultiplexSocket::HandleDisconnection( - const ByteArray& salted_service_id_hash) { - std::string salted_service_id_hash_key = - GenerateServiceIdHashKey(salted_service_id_hash); - MediumSocket* virtual_socket_to_close = nullptr; - { - MutexLock lock(&virtual_socket_mutex_); - auto item = virtual_sockets_.find(salted_service_id_hash_key); - if (item != virtual_sockets_.end()) { - LOG(INFO) - << "Received a DISCONNECTION frame to disconnect virtual socket for " - "salted service ID Hash Key " - << salted_service_id_hash_key; - virtual_socket_to_close = item->second.get(); - } else { - LOG(WARNING) - << "Received a DISCONNECTION frame but there's no alive socket to " - "disconnect for service ID Hash Key " - << salted_service_id_hash_key; - } - } - // Close the virtual socket outside of the mutex lock because - // OnVirtualSocketClosed will lock the mutex. - if (virtual_socket_to_close != nullptr) { - virtual_socket_to_close->Close(); - } -} - -void MultiplexSocket::HandleDataFrame(const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt, - const MultiplexDataFrame& frame) { - std::string salted_service_id_hash_key = - GenerateServiceIdHashKey(salted_service_id_hash); - std::shared_ptr virtual_socket = nullptr; - if (service_id_hash_salt.empty()) { - { - MutexLock lock(&virtual_socket_mutex_); - auto item = virtual_sockets_.find(salted_service_id_hash_key); - if (item != virtual_sockets_.end()) { - virtual_socket = item->second; - } - } - } else { - virtual_socket = - ReMapAndGetVirtualSocket(salted_service_id_hash, service_id_hash_salt); - } - - if (virtual_socket != nullptr) { - VLOG(1) - << "Received a DATA frame to feed virtual socket for salted service ID " - "Hash Key " - << salted_service_id_hash_key; - virtual_socket->FeedIncomingData(ByteArray(frame.data())); - } else { - LOG(WARNING) - << "Received a DATA frame but there's no alive socket to feed for " - "salted service ID Hash Key " - << salted_service_id_hash_key; - } -} - -void MultiplexSocket::OnPhysicalSocketClosed() { - RunOffloadThread("Shutdown", [this]() { Shutdown(); }); -} - -void MultiplexSocket::OnVirtualSocketClosed(const std::string& service_id) { - LOG(INFO) << __func__ << " for service_id:" << service_id; - CountDownLatch latch(1); - bool shutdown = false; - RunOffloadThread( - "VirtualSocketClosed", [this, service_id, &latch, &shutdown]() { - LOG(INFO) << "Try to close Virtual socket: " << service_id; - std::shared_ptr virtual_socket = - GetVirtualSocket(service_id); - { - MutexLock lock(&virtual_socket_mutex_); - LOG(INFO) << "virtual_socket:" << virtual_socket; - if (virtual_socket != nullptr) { - auto salted_service_id_hash_key = GenerateServiceIdHashKeyWithSalt( - service_id, - multiplex_output_stream_.GetServiceIdHashSalt(service_id)); - multiplex_output_stream_.Close(service_id); - virtual_sockets_.erase(salted_service_id_hash_key); - LOG(INFO) << "Erase Virtual socket with service_id: " << service_id - << ", hash_key: " << salted_service_id_hash_key; - ListVirtualSocket(); - - if (virtual_sockets_.empty()) { - LOG(INFO) << "Close the physical socket because all virtual " - "sockets disconnected."; - is_shutting_down_.Set(true); - Shutdown(); - shutdown = true; - } - } else { - LOG(INFO) << "Virtual socket(" << service_id << ") not found"; - } - } - latch.CountDown(); - }); - - if (!latch.Await(absl::Milliseconds(1000)).result()) { - LOG(ERROR) << "Timeout to close virtual socket"; - } - - if (shutdown) { - LOG(INFO) - << "Shutdown single_thread_offloader_ and physical_reader_thread_"; - single_thread_offloader_.Shutdown(); - physical_reader_thread_.Shutdown(); - is_shutting_down_.Set(false); - } -} - -std::shared_ptr MultiplexSocket::ReMapAndGetVirtualSocket( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt) { - std::string salted_service_id_hash_key = - GenerateServiceIdHashKey(salted_service_id_hash); - VLOG(1) << "ReMapAndGetVirtualSocket with serviceIdHashSalt=" - << service_id_hash_salt - << ", saltedServiceIdHashKey=" << salted_service_id_hash_key; - { - MutexLock lock(&virtual_socket_mutex_); - for (auto& [hash_key, virtual_socket] : virtual_sockets_) { - auto output_stream = - down_cast( - &(virtual_socket->GetOutputStream())); - if (output_stream == nullptr) { - continue; - } - if (!output_stream->IsFirstVirtualOutputStream()) { - continue; - } - if ((service_id_hash_salt == kFakeSalt) || - (hash_key == salted_service_id_hash_key)) { - return virtual_socket; - } else { - LOG(INFO) << "Remap the virtualSockets."; - output_stream->SetserviceIdHashSalt(service_id_hash_salt); - auto virtual_socket_tmp = virtual_socket; - LOG(INFO) << "virtual_socket before:" << virtual_socket; - virtual_sockets_.erase(hash_key); - virtual_sockets_[salted_service_id_hash_key] = virtual_socket_tmp; - ListVirtualSocket(); - return virtual_socket_tmp; - } - } - } - - LOG(INFO) << "Failed to remap the virtualSockets."; - return nullptr; -} - -void MultiplexSocket::RunOffloadThread(const std::string& name, - absl::AnyInvocable runnable) { - single_thread_offloader_.Execute(name, std::move(runnable)); -} - -void MultiplexSocket::Shutdown() { - LOG(INFO) << __func__ << " start"; - if (is_shutdown_) { - LOG(INFO) << __func__ << " Already shutdown"; - return; - } - - multiplex_output_stream_.Shutdown(); - physical_socket_ptr_->Close(); - - if (reader_thread_shutdown_barrier_) { - reader_thread_shutdown_barrier_->Await(kTimeoutForReaderThreadStop); - } - - GetIncomingConnectionCallbacks().clear(); - connection_response_futures_.clear(); - - is_shutdown_ = true; - enabled_.Set(false); - LOG(INFO) << __func__ << " end"; -} - -void MultiplexSocket::ShutdownAll() { - LOG(INFO) << __func__ << " start"; - if (is_shutdown_) { - LOG(WARNING) << __func__ << " Already shutdown"; - return; - } - - CountDownLatch latch(1); - RunOffloadThread("VirtualSocketClosed", [this, &latch]() { - { - MutexLock lock(&virtual_socket_mutex_); - multiplex_output_stream_.CloseAll(); - virtual_sockets_.clear(); - - Shutdown(); - } - latch.CountDown(); - }); - - if (!latch - .Await(FeatureFlags::GetInstance() - .GetFlags() - .mediums_frame_write_timeout_millis + - absl::Milliseconds(100)) - .result()) { - LOG(ERROR) << "Timeout to close virtual socket"; - } - - LOG(INFO) << "Shutdown single_thread_offloader_ and physical_reader_thread_"; - single_thread_offloader_.Shutdown(); - physical_reader_thread_.Shutdown(); - LOG(INFO) << __func__ << " end"; -} - -} // namespace multiplex -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/multiplex/multiplex_socket.h b/connections/implementation/mediums/multiplex/multiplex_socket.h deleted file mode 100644 index ed3fdd7d..00000000 --- a/connections/implementation/mediums/multiplex/multiplex_socket.h +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright 2024 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 CORE_INTERNAL_MEDIUMS_MULTIPLEX_MULTIPLEX_SOCKET_H_ -#define CORE_INTERNAL_MEDIUMS_MULTIPLEX_MULTIPLEX_SOCKET_H_ - -#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/multiplex/multiplex_output_stream.h" -#include "connections/medium_selector.h" -#include "internal/platform/atomic_boolean.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/future.h" -#include "internal/platform/input_stream.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/platform/socket.h" -#include "proto/connections_enums.pb.h" -#include "proto/mediums/multiplex_frames.pb.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace multiplex { - -using MultiplexEnbaleCb = absl::AnyInvocable; -using MultiplexIncomingConnectionCb = absl::AnyInvocable socket)>; - -class MultiplexSocket { - public: - MultiplexSocket(const MultiplexSocket&) = delete; - MultiplexSocket& operator=(const MultiplexSocket&) = delete; - ~MultiplexSocket() { ShutdownAll(); }; - - // Creates a new incoming MultiplexSocket. - static MultiplexSocket* CreateIncomingSocket( - std::shared_ptr physical_socket, - const std::string& service_id, std::int32_t first_frame_len); - // Creates a new outgoing MultiplexSocket. - static MultiplexSocket* CreateOutgoingSocket( - std::shared_ptr physical_socket, - const std::string& service_id, const std::string& service_id_hash_salt); - - // Creates a new outgoing MultiplexSocket with default service_id_hash_salt. - static MultiplexSocket* CreateOutgoingSocket( - std::shared_ptr physical_socket, - const std::string& service_id); - - // A Table of service Id as row key, medium type as column key, and - // MultiplexIncomingConnectionCb as value. Non-empty while the client starts - // listening for incoming virtual socket. The MultiplexIncomingConnectionCb - // will be called when the incoming virtual socket is established. - static absl::flat_hash_map< - std::pair, - MultiplexIncomingConnectionCb>& - GetIncomingConnectionCallbacks(); - - // Listens for incoming connection through multiplex for specified {@code - // service_id} on medium - // {@code type}. Should register the callback before new the MultiplexSocket. - static void ListenForIncomingConnection( - const std::string& service_id, - ::location::nearby::proto::connections::Medium type, - absl::AnyInvocable socket)> - incoming_connection_cb); - - // Stops listening for incoming multiplex connection for {@code service_id} on - // medium {@code type}. - static void StopListeningForIncomingConnection( - const std::string& service_id, - ::location::nearby::proto::connections::Medium type); - - bool IsEnabled() { return enabled_.Get(); } - void Enable() { - LOG(INFO) << "Enable the Multiplex MediumSocket."; - enabled_.Set(true); - } - - // Gets the virtual socket by service id. - std::shared_ptr GetVirtualSocket(const std::string& service_id); - // Gets the virtual socket count. - int GetVirtualSocketCount(); - - void ListVirtualSocket() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(virtual_socket_mutex_); - - // Establishes the virtual socket by service id. - std::shared_ptr EstablishVirtualSocket( - const std::string& service_id); - // Shuts down the multiplex socket. - void Shutdown(); - bool IsShutdown() { return is_shutdown_; } - void SetShutdown(bool is_shutdown) { is_shutdown_ = is_shutdown; } - void ShutdownAll(); - - private: - explicit MultiplexSocket(std::shared_ptr physical_socket); - - // Creates the first virtual socket for the service id. The first virtual - // socket is created by the sender. - std::shared_ptr CreateFirstVirtualSocket( - const std::string& service_id, const std::string& service_id_hash_salt); - // Creates the virtual socket for the service id. - std::shared_ptr CreateVirtualSocket( - const std::string& service_id, const std::string& service_id_hash_salt); - // Registers the connection response future for the service id. - std::shared_ptr> - RegisterConnectionResponse(const std::string& service_id); - // Unregisters the connection response future for the service id. - void UnRegisterConnectionResponse(const std::string& service_id); - // Starts the reader thread to read the incoming MultiplexFrame from the - // physical socket. - void StartReaderThread(std::int32_t first_frame_len); - // Handles the offline frame from the physical socket. - void HandleOfflineFrame(const ByteArray& bytes); - // Handles the control frame from the physical socket. - void HandleControlFrame( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt, - const ::location::nearby::mediums::MultiplexControlFrame& frame); - // Handles the connection request frame from the physical socket. - void HandleConnectionRequest(const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt); - // Handles the connection response frame from the physical socket. - void HandleConnectionResponse( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt, - const ::location::nearby::mediums::ConnectionResponseFrame& frame); - // Handles the disconnection frame from the physical socket. - void HandleDisconnection(const ByteArray& salted_service_id_hash); - // Handles the data frame from the physical socket. - void HandleDataFrame( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt, - const ::location::nearby::mediums::MultiplexDataFrame& frame); - // Handles the physical socket closed. - void OnPhysicalSocketClosed(); - // Remaps and gets the virtual socket by service id hash. - std::shared_ptr ReMapAndGetVirtualSocket( - const ByteArray& salted_service_id_hash, - const std::string& service_id_hash_salt); - // Handles the virtual socket closed. - void OnVirtualSocketClosed(const std::string& service_id); - // Runs the offload thread. - void RunOffloadThread(const std::string& name, - absl::AnyInvocable runnable); - - // The physical socket connect to the remote device. - std::shared_ptr physical_socket_ptr_; - - // The output stream to manage all outgoing frames from all clients. - MultiplexOutputStream multiplex_output_stream_; - // The {@link InputStream} of the physical socket. It is used to read the - // incoming MultiplexFrame from the physical socket. - InputStream* physical_reader_; - // The medium type of the physical socket. - Medium medium_; - - // The callback to enable the MultiplexSocket. - std::shared_ptr> enable_cb_ = - std::make_shared>([this]() { Enable(); }); - - // A map of service Id -> {@link SettableFuture} for waiting the - // ConnectionResponse. Non-empty while requesting the virtual socket. - absl::flat_hash_map>> - connection_response_futures_; - - // A map of service Id hash key -> virtual socket. Non-empty while at least - // one virtual socket alive. Class derived from "MediumSocket" should define a - // pointer to the virtual sockets map. When here's any virtual socket - // operation, it will be reflected in both derived MediumSocket class and - // MultiplexSocket object - mutable Mutex virtual_socket_mutex_; - absl::flat_hash_map> - virtual_sockets_ ABSL_GUARDED_BY(virtual_socket_mutex_); - - // The thread to receive incoming MultiplexFrame from the physical socket. - SingleThreadExecutor physical_reader_thread_; - // The single thread we throw the potentially blocking work on to. - SingleThreadExecutor single_thread_offloader_; - - // The status of the MultiplexSocket enabled or disabled, it depends on both - // Sender and Receiver supports MultiplexSocket or not. Default disabled and - // enable it once two devices negotiated finished. - AtomicBoolean enabled_{false}; - - // If the socket is already shutdown and no longer in use. - bool is_shutdown_ = false; - static AtomicBoolean is_shutting_down_; - std::unique_ptr reader_thread_shutdown_barrier_; -}; - -} // namespace multiplex -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_MULTIPLEX_MULTIPLEX_SOCKET_H_ diff --git a/connections/implementation/mediums/multiplex/multiplex_socket_test.cc b/connections/implementation/mediums/multiplex/multiplex_socket_test.cc deleted file mode 100644 index cf382eef..00000000 --- a/connections/implementation/mediums/multiplex/multiplex_socket_test.cc +++ /dev/null @@ -1,463 +0,0 @@ -// Copyright 2024 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. - -#include "connections/implementation/mediums/multiplex/multiplex_socket.h" - -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/container/flat_hash_map.h" -#include "absl/strings/string_view.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "connections/implementation/mediums/multiplex/multiplex_frames.h" -#include "connections/implementation/offline_frames.h" -#include "internal/platform/base64_utils.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/exception.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/future.h" -#include "internal/platform/input_stream.h" -#include "internal/platform/logging.h" -#include "internal/platform/output_stream.h" -#include "internal/platform/pipe.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/platform/socket.h" -#include "internal/platform/types.h" -#include "proto/connections_enums.proto.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace multiplex { - -constexpr absl::string_view SERVICE_ID_1 = "serviceId_1"; -constexpr absl::string_view SERVICE_ID_2 = "serviceId_2"; - -using location::nearby::mediums::ConnectionResponseFrame; -using location::nearby::mediums::MultiplexControlFrame; -using location::nearby::mediums::MultiplexFrame; -using location::nearby::proto::connections::Medium; -using location::nearby::proto::connections::Medium_Name; - -// A fake socket for testing. -class FakeSocket : public MediumSocket { - public: - explicit FakeSocket(Medium medium) : MediumSocket(medium) { - pipe_1_ = CreatePipe(); - reader_1_ = std::move(pipe_1_.first); - writer_1_ = std::move(pipe_1_.second); - pipe_2_ = CreatePipe(); - reader_2_ = std::move(pipe_2_.first); - writer_2_ = std::move(pipe_2_.second); - LOG(WARNING) << "Physical Socket Medium:" << Medium_Name(GetMedium()); - }; - ~FakeSocket() override = default; - - FakeSocket(const FakeSocket&) = default; - FakeSocket& operator=(const FakeSocket&) = default; - - /** - * The constructor for a virtual socket which own the virtual {@link - * OutputStream} and {@link InputStream}. - */ - explicit FakeSocket(Medium medium, OutputStream* virtualOutputStream) - : MediumSocket(medium), - is_virtual_socket_(true), - virtual_output_stream_(virtualOutputStream) { - pipe_1_ = CreatePipe(); - reader_1_ = std::move(pipe_1_.first); - writer_1_ = std::move(pipe_1_.second); - pipe_2_ = CreatePipe(); - reader_2_ = std::move(pipe_2_.first); - writer_2_ = std::move(pipe_2_.second); - } - - InputStream& GetInputStream() override { return *reader_1_; } - OutputStream& GetOutputStream() override { - return IsVirtualSocket() ? *virtual_output_stream_ : *writer_2_; - } - Exception Close() override { - if (IsVirtualSocket()) { - LOG(INFO) << "Multiplex: Closing virtual socket: " << this; - CloseLocal(); - return {Exception::kSuccess}; - } - LOG(INFO) << "Multiplex: Closing physical socket: " << this; - reader_1_->Close(); - reader_2_->Close(); - writer_1_->Close(); - writer_2_->Close(); - return {Exception::kSuccess}; - } - - MediumSocket* CreateVirtualSocket( - const std::string& salted_service_id_hash_key, OutputStream* outputstream, - Medium medium, - absl::flat_hash_map>* - virtual_sockets_ptr) override { - if (IsVirtualSocket()) { - LOG(WARNING) - << "Creating the virtual socket on a virtual socket is not allowed."; - return nullptr; - } - - auto virtual_socket = std::make_shared(medium, outputstream); - LOG(INFO) << "Created the virtual socket for Medium: " - << Medium_Name(virtual_socket->GetMedium()); - - if (virtual_sockets_ptr_ == nullptr) { - virtual_sockets_ptr_ = virtual_sockets_ptr; - } - - (*virtual_sockets_ptr_)[salted_service_id_hash_key] = virtual_socket; - LOG(INFO) << "virtual_sockets_ size: " << virtual_sockets_ptr_->size(); - return virtual_socket.get(); - } - - void FeedIncomingData(ByteArray data) override { - bytes_read_future_.Set(data); - LOG(INFO) << "FeedIncomingData. Size of receive data: " << data.size() - << ", bytes content:" << std::string(data); - } - - bool IsVirtualSocket() override { return is_virtual_socket_; } - Future& GetByteReadFuture() { return bytes_read_future_; } - - std::pair, std::unique_ptr> - pipe_1_; - std::unique_ptr reader_1_; - std::unique_ptr writer_1_; - std::pair, std::unique_ptr> - pipe_2_; - std::unique_ptr reader_2_; - std::unique_ptr writer_2_; - - private: - bool is_virtual_socket_ = false; - Future bytes_read_future_; - absl::flat_hash_map>* - virtual_sockets_ptr_ = nullptr; - OutputStream* virtual_output_stream_ = nullptr; -}; - -TEST(MultiplexSocketTest, CreateIncomingSocketSuccess) { - auto fake_socket_ptr = std::make_shared(Medium::BLUETOOTH); - MultiplexSocket::StopListeningForIncomingConnection(std::string(SERVICE_ID_1), - Medium::BLUETOOTH); - MultiplexSocket::StopListeningForIncomingConnection(std::string(SERVICE_ID_2), - Medium::BLUETOOTH); - MultiplexSocket::ListenForIncomingConnection( - std::string(SERVICE_ID_1), Medium::BLUETOOTH, - [](const std::string& service_id, std::shared_ptr socket) { - LOG(INFO) << "Incoming connection for service_id: " << service_id; - }); - MultiplexSocket::ListenForIncomingConnection( - std::string(SERVICE_ID_2), Medium::BLUETOOTH, - [](const std::string& service_id, std::shared_ptr socket) { - LOG(INFO) << "Incoming connection for service_id: " << service_id; - }); - - MultiplexSocket* multiplex_socket_incoming = - MultiplexSocket::CreateIncomingSocket( - fake_socket_ptr, std::string(SERVICE_ID_1), /*first_frame_len*/ 0); - ASSERT_NE(multiplex_socket_incoming, nullptr); - MultiplexSocket* multiplex_socket_incoming_2 = - MultiplexSocket::CreateIncomingSocket( - fake_socket_ptr, std::string(SERVICE_ID_2), /*first_frame_len*/ 0); - ASSERT_EQ(multiplex_socket_incoming_2, multiplex_socket_incoming); - - std::shared_ptr virtual_socket_shared = - multiplex_socket_incoming->GetVirtualSocket(std::string(SERVICE_ID_1)); - ASSERT_NE(virtual_socket_shared, nullptr); - FakeSocket* virtual_socket = - down_cast(virtual_socket_shared.get()); - - SingleThreadExecutor executor; - FakeSocket* socket = fake_socket_ptr.get(); - executor.Execute([socket]() { - std::string connection_req_frame = parser::ForConnectionRequestConnections( - {}, { - .local_endpoint_id = "endpoint1", - .local_endpoint_info = ByteArray("endpoint1 info"), - }); - auto& writer = socket->writer_1_; - LOG(INFO) << "writer_1_ Write start"; - Base64Utils::WriteInt(writer.get(), connection_req_frame.size()); - writer->Write(connection_req_frame); - writer->Flush(); - LOG(INFO) << "writer_1_ Write end"; - }); - - ExceptionOr result = virtual_socket->GetByteReadFuture().Get(); - if (!result.ok()) { - ADD_FAILURE() << "Read error: " << result.GetException().value; - } - ByteArray data = result.result(); - LOG(INFO) << "Received " << data.size() << " bytes of data."; - EXPECT_NE(data.size(), 0); - absl::SleepFor(absl::Milliseconds(100)); - - EXPECT_EQ(multiplex_socket_incoming->GetVirtualSocketCount(), 1); - virtual_socket->Close(); - EXPECT_EQ(multiplex_socket_incoming->GetVirtualSocketCount(), 0); - multiplex_socket_incoming->ShutdownAll(); -} - -TEST(MultiplexSocketTest, CreateFail_MediumNotSupport) { - auto fake_socket_ptr = std::make_shared(Medium::WEB_RTC); - MultiplexSocket::StopListeningForIncomingConnection(std::string(SERVICE_ID_1), - Medium::WEB_RTC); - MultiplexSocket* multiplex_socket_incoming = - MultiplexSocket::CreateIncomingSocket( - fake_socket_ptr, std::string(SERVICE_ID_1), /*first_frame_len*/ 0); - - ASSERT_EQ(multiplex_socket_incoming, nullptr); -} - -TEST(MultiplexSocketTest, CreateIncomingVirtualSocketSuccess) { - auto fake_socket_ptr = std::make_shared(Medium::WIFI_LAN); - - MultiplexSocket::StopListeningForIncomingConnection(std::string(SERVICE_ID_1), - Medium::WIFI_LAN); - MultiplexSocket::StopListeningForIncomingConnection(std::string(SERVICE_ID_2), - Medium::WIFI_LAN); - MultiplexSocket::ListenForIncomingConnection( - std::string(SERVICE_ID_1), Medium::WIFI_LAN, - [](const std::string& service_id, std::shared_ptr socket) { - LOG(INFO) << "Incoming connection for service_id: " << service_id; - }); - MultiplexSocket::ListenForIncomingConnection( - std::string(SERVICE_ID_2), Medium::WIFI_LAN, - [](const std::string& service_id, std::shared_ptr socket) { - LOG(INFO) << "Incoming connection for service_id: " << service_id; - }); - - MultiplexSocket* multiplex_socket_incoming = - MultiplexSocket::CreateIncomingSocket( - fake_socket_ptr, std::string(SERVICE_ID_1), /*first_frame_len*/ 0); - ASSERT_NE(multiplex_socket_incoming, nullptr); - - std::shared_ptr virtual_socket_shared = - multiplex_socket_incoming->GetVirtualSocket(std::string(SERVICE_ID_1)); - ASSERT_NE(virtual_socket_shared, nullptr); - FakeSocket* virtual_socket = - down_cast(virtual_socket_shared.get()); - - SingleThreadExecutor executor; - FakeSocket* socket = fake_socket_ptr.get(); - executor.Execute([socket]() { - ByteArray connection_req_frame = ForConnectionRequest( - std::string(SERVICE_ID_2), "J7frzSmHK-VBTHjCKpf4ew"); - auto& writer = socket->writer_1_; - LOG(INFO) << "writer_1_ Write start"; - Base64Utils::WriteInt(writer.get(), connection_req_frame.size()); - writer->Write(connection_req_frame.AsStringView()); - writer->Flush(); - LOG(INFO) << "writer_1_ Write end"; - }); - absl::SleepFor(absl::Milliseconds(100)); - - EXPECT_EQ(multiplex_socket_incoming->GetVirtualSocketCount(), 2); - virtual_socket->Close(); - EXPECT_EQ(multiplex_socket_incoming->GetVirtualSocketCount(), 1); - multiplex_socket_incoming->ShutdownAll(); -} - -TEST(MultiplexSocketTest, - EstablishVirtualSocket_Timeout_BecauseNoConnectionResponse) { - auto fake_socket_ptr = std::make_shared(Medium::WIFI_LAN); - MultiplexSocket::StopListeningForIncomingConnection(std::string(SERVICE_ID_1), - Medium::WIFI_LAN); - MultiplexSocket::StopListeningForIncomingConnection(std::string(SERVICE_ID_2), - Medium::WIFI_LAN); - MultiplexSocket* multiplex_socket = MultiplexSocket::CreateOutgoingSocket( - fake_socket_ptr, std::string(SERVICE_ID_1)); - ASSERT_NE(multiplex_socket, nullptr); - MultiplexSocket* multiplex_socket_2 = MultiplexSocket::CreateOutgoingSocket( - fake_socket_ptr, std::string(SERVICE_ID_2)); - ASSERT_EQ(multiplex_socket_2, multiplex_socket); - multiplex_socket->Enable(); - std::shared_ptr virtual_socket_shared = - multiplex_socket->GetVirtualSocket(std::string(SERVICE_ID_1)); - ASSERT_NE(virtual_socket_shared, nullptr); - FakeSocket* virtual_socket = - down_cast(virtual_socket_shared.get()); - - // This is a timeout test, the real timeout is 3s which is too long for a - // unit test, so we set a short timeout for flakiness test to avoid long wait - // time. - auto flags = FeatureFlags::GetInstance().GetFlags(); - auto original_flags = flags; - flags.multiplex_socket_connection_response_timeout_millis = - absl::Milliseconds(200); - FeatureFlags::GetMutableInstanceForTesting().SetFlags(flags); - - CountDownLatch latch(2); - SingleThreadExecutor establish_socket_executor; - establish_socket_executor.Execute([&multiplex_socket, &latch]() { - LOG(INFO) << "EstablishVirtualSocket"; - std::shared_ptr socket = - multiplex_socket->EstablishVirtualSocket(std::string(SERVICE_ID_2)); - LOG(INFO) << "EstablishVirtualSocket finished"; - EXPECT_EQ(socket, nullptr); - latch.CountDown(); - }); - - SingleThreadExecutor read_executor; - read_executor.Execute([&multiplex_socket, &fake_socket_ptr, &latch]() { - auto reader = fake_socket_ptr->reader_2_.get(); - LOG(INFO) << "reader_2_ Read start"; - ExceptionOr read_int = Base64Utils::ReadInt(reader); - if (!read_int.ok()) { - ADD_FAILURE() << "Failed to read. Exception:" << read_int.exception(); - } else { - auto length = read_int.result(); - LOG(INFO) << " length:" << length; - EXPECT_GT(length, 0); - } - EXPECT_EQ(multiplex_socket->GetVirtualSocket(std::string(SERVICE_ID_2)), - nullptr); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await(absl::Seconds(1)).result()); - EXPECT_EQ(multiplex_socket->GetVirtualSocketCount(), 1); - virtual_socket->Close(); - EXPECT_EQ(multiplex_socket->GetVirtualSocketCount(), 0); - multiplex_socket->ShutdownAll(); - - // Restore the original flags. - FeatureFlags::GetMutableInstanceForTesting().SetFlags(original_flags); -} - -TEST(MultiplexSocketTest, EstablishVirtualSocket_RemoteAccepted) { - auto fake_socket_ptr = std::make_shared(Medium::BLUETOOTH); - MultiplexSocket::StopListeningForIncomingConnection(std::string(SERVICE_ID_1), - Medium::BLUETOOTH); - MultiplexSocket::StopListeningForIncomingConnection(std::string(SERVICE_ID_2), - Medium::BLUETOOTH); - - MultiplexSocket* multiplex_socket = MultiplexSocket::CreateOutgoingSocket( - fake_socket_ptr, std::string(SERVICE_ID_1)); - ASSERT_NE(multiplex_socket, nullptr); - MultiplexSocket* multiplex_socket_2 = MultiplexSocket::CreateOutgoingSocket( - fake_socket_ptr, std::string(SERVICE_ID_2)); - ASSERT_EQ(multiplex_socket_2, multiplex_socket); - - SingleThreadExecutor executor; - CountDownLatch latch(1); - executor.Execute([&multiplex_socket, &latch]() { - LOG(INFO) << "EstablishVirtualSocket"; - std::shared_ptr socket = - multiplex_socket->EstablishVirtualSocket(std::string(SERVICE_ID_2)); - EXPECT_EQ(socket, nullptr); - latch.CountDown(); - }); - latch.Await(); - - multiplex_socket->Enable(); - executor.Execute([&multiplex_socket]() { - LOG(INFO) << "EstablishVirtualSocket"; - std::shared_ptr socket = - multiplex_socket->EstablishVirtualSocket(std::string(SERVICE_ID_2)); - EXPECT_NE(socket, nullptr); - }); - - auto reader = fake_socket_ptr->reader_2_.get(); - LOG(INFO) << "reader_2_ Waiting for CONNECTION_REQUEST frame."; - ExceptionOr read_int = Base64Utils::ReadInt(reader); - if (!read_int.ok()) { - ADD_FAILURE() << "Failed to read length.Exception:" << read_int.exception(); - } - auto length = read_int.result(); - if (length < 0 || - length > - FeatureFlags::GetInstance().GetFlags().connection_max_frame_length) { - ADD_FAILURE() << "Invalid length:" << length; - } - - auto bytes = reader->ReadExactly(length); - if (!bytes.ok()) { - ADD_FAILURE() << "Failed to read frame. Exception:" << bytes.exception(); - } - length = read_int.result(); - if (length < 0 || - length > - FeatureFlags::GetInstance().GetFlags().connection_max_frame_length) { - ADD_FAILURE() << "Invalid frame length:" << length; - } - - ExceptionOr frame_exc = multiplex::FromBytes(bytes.result()); - if (!frame_exc.ok()) { - ADD_FAILURE() << "Failed to parse MultiplexFrame. Exception:" - << frame_exc.exception(); - } - auto frame = frame_exc.result(); - auto salted_service_id_hash = - ByteArray{std::move(frame.header().salted_service_id_hash())}; - auto service_id_hash_salt = frame.header().has_service_id_hash_salt() - ? frame.header().service_id_hash_salt() - : ""; - ASSERT_EQ(frame.frame_type(), MultiplexFrame::CONTROL_FRAME); - auto control_frame = frame.control_frame(); - ASSERT_EQ(control_frame.control_frame_type(), - MultiplexControlFrame::CONNECTION_REQUEST); - LOG(INFO) << "Recieved MultiplexControlFrame::CONNECTION_REQUEST " - "frame, now send CONNECTION_RESPONSE frame."; - - ByteArray connection_response_frame = - ForConnectionResponse(salted_service_id_hash, service_id_hash_salt, - ConnectionResponseFrame::CONNECTION_ACCEPTED); - auto& writer = fake_socket_ptr->writer_1_; - LOG(INFO) << "writer_1_ Write start"; - Base64Utils::WriteInt(writer.get(), connection_response_frame.size()); - writer->Write(connection_response_frame.AsStringView()); - writer->Flush(); - LOG(INFO) << "writer_1_ Write end"; - absl::SleepFor(absl::Milliseconds(100)); - EXPECT_NE(multiplex_socket->GetVirtualSocket(std::string(SERVICE_ID_2)), - nullptr); - - EXPECT_EQ(multiplex_socket->GetVirtualSocketCount(), 2); - - LOG(INFO) << "Send Data frame on virtual socket for SERVICE_ID_2."; - ByteArray data_frame = - ForData(std::string(SERVICE_ID_2), service_id_hash_salt, - /*should_pass_salt=*/true, absl::string_view("data")); - Base64Utils::WriteInt(writer.get(), data_frame.size()); - writer->Write(data_frame.AsStringView()); - writer->Flush(); - absl::SleepFor(absl::Milliseconds(100)); - - LOG(INFO) << "Send disconnection frame on virtual socket for SERVICE_ID_2."; - ByteArray disconnect_frame = - ForDisconnection(std::string(SERVICE_ID_2), service_id_hash_salt); - Base64Utils::WriteInt(writer.get(), disconnect_frame.size()); - writer->Write(disconnect_frame.AsStringView()); - writer->Flush(); - absl::SleepFor(absl::Milliseconds(100)); - EXPECT_EQ(multiplex_socket->GetVirtualSocketCount(), 1); - - multiplex_socket->ShutdownAll(); -} - -} // namespace multiplex -} // namespace mediums -} // namespace connections -} // namespace nearby From c4e4b04527b85857a1da35982033c04362c2d117 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 12 May 2026 18:40:55 -0700 Subject: [PATCH 084/151] Fix unsigned underflow OOB read on empty cert_id. PiperOrigin-RevId: 914584854 --- .../nearby_share_certificate_manager_impl.cc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sharing/certificates/nearby_share_certificate_manager_impl.cc b/sharing/certificates/nearby_share_certificate_manager_impl.cc index 5797059a..56526182 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl.cc +++ b/sharing/certificates/nearby_share_certificate_manager_impl.cc @@ -186,11 +186,7 @@ void DumpCertificateId(std::stringstream& sstream, absl::string_view cert_id, } else { sstream << " Private certificates:["; } - for (int i = 0; i < cert_id.size() - 1; ++i) { - sstream << static_cast(static_cast(cert_id[i])) << ", "; - } - sstream << static_cast(static_cast(cert_id[cert_id.size() - 1])) - << "]" << std::endl; + sstream << absl::BytesToHexString(cert_id) << "]" << std::endl; } } // namespace @@ -755,7 +751,7 @@ std::string NearbyShareCertificateManagerImpl::Dump() const { certificate_storage_->GetPublicCertificateIds(); sstream << " Total count:" << ids.size() << std::endl; for (const auto& id : ids) { - DumpCertificateId(sstream, id, true); + DumpCertificateId(sstream, id, /*is_public_cert=*/true); } sstream << std::endl; @@ -768,7 +764,7 @@ std::string NearbyShareCertificateManagerImpl::Dump() const { sstream << " Total count:" << private_certs.size() << std::endl; for (const auto& cert : private_certs) { std::string id(cert.id().begin(), cert.id().end()); - DumpCertificateId(sstream, id, false); + DumpCertificateId(sstream, id, /*is_public_cert=*/false); } } From 2ee9a6a191d70262e461445b494af4a8e3235a96 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 12 May 2026 18:51:35 -0700 Subject: [PATCH 085/151] Heap OOB read in IncomingShareSession::ProcessIntroduction AppMetadata PiperOrigin-RevId: 914587667 --- sharing/incoming_share_session.cc | 12 +++++++ sharing/incoming_share_session_test.cc | 45 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/sharing/incoming_share_session.cc b/sharing/incoming_share_session.cc index ed86146a..8be99f37 100644 --- a/sharing/incoming_share_session.cc +++ b/sharing/incoming_share_session.cc @@ -138,8 +138,20 @@ IncomingShareSession::ProcessIntroduction( "64 bit integer."; return TransferMetadata::Status::kNotEnoughSpace; } + if (apk.file_name_size() != apk.file_size_size() || + apk.file_name_size() != apk.payload_id_size()) { + LOG(WARNING) + << __func__ + << ": Ignore introduction, AppMetadata array length mismatch"; + return TransferMetadata::Status::kUnsupportedAttachmentType; + } // Map each apk file to a file attachment. for (int index = 0; index < apk.file_name_size(); ++index) { + if (apk.file_size(index) <= 0) { + LOG(WARNING) << __func__ + << ": Ignore introduction, due to invalid apk file size"; + return TransferMetadata::Status::kUnsupportedAttachmentType; + } // Locally generate an attachment id for each apk file, and map it to the // payload id. FileAttachment apk_file( diff --git a/sharing/incoming_share_session_test.cc b/sharing/incoming_share_session_test.cc index 999fbe7f..4278e32a 100644 --- a/sharing/incoming_share_session_test.cc +++ b/sharing/incoming_share_session_test.cc @@ -354,6 +354,51 @@ TEST_F(IncomingShareSessionTest, ProcessIntroductionWithApkSuccess) { UnorderedElementsAre(file1, file2, file3)); } +TEST_F(IncomingShareSessionTest, ProcessIntroductionWithApkLengthMismatch) { + IntroductionFrame introduction_frame; + CHECK( + proto2::TextFormat::ParseFromString(R"pb( + app_metadata { + app_name: "MyApp" + size: 300 + payload_id: 9876 + id: 1234 + file_name: "MyApp.apk" + file_name: "MyApp2.apk" + file_size: 100 + file_size: 100 + file_size: 100 + package_name: "com.example.myapp" + } + )pb", + &introduction_frame)); + session_.OnConnected(&connection_); + + EXPECT_THAT(session_.ProcessIntroduction(introduction_frame), + Eq(TransferMetadata::Status::kUnsupportedAttachmentType)); +} + +TEST_F(IncomingShareSessionTest, ProcessIntroductionWithApkInvalidSize) { + IntroductionFrame introduction_frame; + CHECK( + proto2::TextFormat::ParseFromString(R"pb( + app_metadata { + app_name: "MyApp" + size: 300 + payload_id: 9876 + id: 1234 + file_name: "MyApp.apk" + file_size: 0 + package_name: "com.example.myapp" + } + )pb", + &introduction_frame)); + session_.OnConnected(&connection_); + + EXPECT_THAT(session_.ProcessIntroduction(introduction_frame), + Eq(TransferMetadata::Status::kUnsupportedAttachmentType)); +} + TEST_F(IncomingShareSessionTest, PayloadTransferUpdateCompleteWithWrongPayloadType) { connections_manager_.AcceptConnection( From 97ef555f60ea5f7491f1e5e28bacd2f4c99c6e58 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 13 May 2026 10:10:32 -0700 Subject: [PATCH 086/151] Ensure that incoming connections are authenticated unless visibility is Everyone. PiperOrigin-RevId: 914926223 --- sharing/BUILD | 2 + sharing/nearby_sharing_service_impl.cc | 7 +- sharing/paired_key_verification_runner.cc | 105 +++++++++--------- sharing/paired_key_verification_runner.h | 26 ++--- .../paired_key_verification_runner_test.cc | 89 +++++++++++---- sharing/share_session.cc | 6 - sharing/share_session_test.cc | 14 --- 7 files changed, 139 insertions(+), 110 deletions(-) diff --git a/sharing/BUILD b/sharing/BUILD index ee2baf42..eb7cee28 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -200,6 +200,7 @@ cc_library( "//sharing/proto:enums_cc_proto", "//sharing/proto:share_cc_proto", "//sharing/proto:wire_format_cc_proto", + "@com_google_absl//absl/base:nullability", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/time", ], @@ -551,6 +552,7 @@ cc_test( "//sharing/proto:wire_format_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/strings", "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index a999d629..f125391c 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -2216,9 +2216,10 @@ void NearbySharingServiceImpl::OnOutgoingConnection( session->RunPairedKeyVerification( ToProtoOsType(device_info_.GetOsType()), { - .visibility = settings_->GetVisibility(), - .last_visibility = settings_->GetLastVisibility(), - .last_visibility_time = settings_->GetLastVisibilityTimestamp(), + // Sender always uses ALL_CONTACTS cert to sign and verify signature. + .visibility = DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, + .last_visibility = DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, + .last_visibility_time = absl::UnixEpoch(), }, GetCertificateManager(), absl::bind_front( diff --git a/sharing/paired_key_verification_runner.cc b/sharing/paired_key_verification_runner.cc index e8cd74f3..213d6799 100644 --- a/sharing/paired_key_verification_runner.cc +++ b/sharing/paired_key_verification_runner.cc @@ -26,6 +26,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/functional/any_invocable.h" #include "absl/time/time.h" #include "internal/platform/clock.h" @@ -56,20 +57,18 @@ namespace { // if a valid signature cannot be generated. This size is consistent with the // GmsCore implementation. const size_t kNearbyShareNumBytesRandomSignature = 72; -constexpr absl::Duration kRelaxAfterSetVisibilityTimeout = absl::Minutes(15); +constexpr absl::Duration kRelaxAfterSetVisibilityTimeout = absl::Minutes(1); PairedKeyVerificationRunner::PairedKeyVerificationResult Convert( nearby::sharing::service::proto::PairedKeyResultFrame::Status status) { switch (status) { - case PairedKeyResultFrame::UNKNOWN: - return PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnknown; - case PairedKeyResultFrame::SUCCESS: return PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess; case PairedKeyResultFrame::FAIL: return PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail; + case PairedKeyResultFrame::UNKNOWN: case PairedKeyResultFrame::UNABLE: return PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable; } @@ -91,40 +90,24 @@ std::ostream& operator<<( } PairedKeyVerificationRunner::PairedKeyVerificationRunner( - Clock* clock, OSType os_type, bool share_target_is_incoming, + Clock* absl_nonnull clock, OSType os_type, bool share_target_is_incoming, const VisibilityHistory& visibility_history, const std::vector& token, absl::AnyInvocable frame_writer, const std::optional& certificate, - NearbyShareCertificateManager* certificate_manager, - IncomingFramesReader* frames_reader, absl::Duration read_frame_timeout) - : clock_(clock), + NearbyShareCertificateManager* absl_nonnull certificate_manager, + IncomingFramesReader* absl_nonnull frames_reader, + absl::Duration read_frame_timeout) + : clock_(*clock), + certificate_manager_(*certificate_manager), + frames_reader_(*frames_reader), + share_target_is_incoming_(share_target_is_incoming), os_type_(os_type), - raw_token_(token), - frame_writer_(std::move(frame_writer)), + visibility_history_(visibility_history), certificate_(certificate), - certificate_manager_(certificate_manager), - frames_reader_(frames_reader), - read_frame_timeout_(read_frame_timeout) { - DCHECK(clock_); - DCHECK(certificate_manager); - DCHECK(frames_reader); - - if (share_target_is_incoming) { - local_prefix_ = kNearbyShareReceiverVerificationPrefix; - remote_prefix_ = kNearbyShareSenderVerificationPrefix; - visibility_history_ = visibility_history; - } else { - remote_prefix_ = kNearbyShareReceiverVerificationPrefix; - local_prefix_ = kNearbyShareSenderVerificationPrefix; - // Sender always uses ALL_CONTACTS cert to sign and verify signature. - visibility_history_ = { - .visibility = DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, - .last_visibility = DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, - .last_visibility_time = absl::UnixEpoch(), - }; - } -} + read_frame_timeout_(read_frame_timeout), + raw_token_(token), + frame_writer_(std::move(frame_writer)) {} PairedKeyVerificationRunner::~PairedKeyVerificationRunner() = default; @@ -135,7 +118,7 @@ void PairedKeyVerificationRunner::Run( verification_result_ = PairedKeyVerificationResult::kSuccess; SendPairedKeyEncryptionFrame(); - frames_reader_->ReadFrame( + frames_reader_.ReadFrame( V1Frame::PAIRED_KEY_ENCRYPTION, [&, runner = GetWeakPtr()](bool is_timeout, std::optional frame) { @@ -169,6 +152,17 @@ void PairedKeyVerificationRunner::OnReadPairedKeyEncryptionFrame( } } + if (auth_token_hash_result == PairedKeyVerificationResult::kUnable) { + if (share_target_is_incoming_ && + visibility_history_.visibility != + DeviceVisibility::DEVICE_VISIBILITY_EVERYONE) { + VLOG(1) << __func__ << ": Incoming connection with non-everyone " + "visibility cannot verify public certificate. " + "Treating as kFail."; + auth_token_hash_result = PairedKeyVerificationResult::kFail; + } + } + ApplyResult(auth_token_hash_result); VLOG(1) << __func__ << ": Remote public certificate verification result " << auth_token_hash_result; @@ -178,10 +172,18 @@ void PairedKeyVerificationRunner::OnReadPairedKeyEncryptionFrame( ApplyResult(local_result); VLOG(1) << __func__ << ": Paired key encryption verification result " << local_result; + if (share_target_is_incoming_ && visibility_history_.visibility == + DeviceVisibility::DEVICE_VISIBILITY_HIDDEN) { + VLOG(1) << __func__ + << ": device is hidden, reject all incoming connections."; + local_result = PairedKeyVerificationResult::kFail; + ApplyResult(PairedKeyVerificationResult::kFail); + } + SendPairedKeyResultFrame(local_result); - frames_reader_->ReadFrame( + frames_reader_.ReadFrame( V1Frame::PAIRED_KEY_RESULT, [this, runner = GetWeakPtr()](bool is_timeout, std::optional frame) { @@ -240,10 +242,6 @@ void PairedKeyVerificationRunner::SendPairedKeyResultFrame( case PairedKeyVerificationResult::kFail: result_frame->set_status(PairedKeyResultFrame::FAIL); break; - - case PairedKeyVerificationResult::kUnknown: - result_frame->set_status(PairedKeyResultFrame::UNKNOWN); - break; } // Set OS type to allow remote device knowns the paring device OS type. @@ -253,9 +251,13 @@ void PairedKeyVerificationRunner::SendPairedKeyResultFrame( } void PairedKeyVerificationRunner::SendPairedKeyEncryptionFrame() { + std::vector padded_token = PadPrefix( + share_target_is_incoming_ ? kNearbyShareReceiverVerificationPrefix + : kNearbyShareSenderVerificationPrefix, + raw_token_); std::optional> signature = - certificate_manager_->SignWithPrivateCertificate( - visibility_history_.visibility, PadPrefix(local_prefix_, raw_token_)); + certificate_manager_.SignWithPrivateCertificate( + visibility_history_.visibility, padded_token); if (!signature.has_value() || signature->empty()) { signature = GenerateRandomBytes(kNearbyShareNumBytesRandomSignature); } @@ -280,9 +282,8 @@ void PairedKeyVerificationRunner::SendPairedKeyEncryptionFrame() { LOG(INFO) << "Attempts to sign authentication token with a previous private key."; std::optional> optional_signature = - certificate_manager_->SignWithPrivateCertificate( - visibility_history_.last_visibility, - PadPrefix(local_prefix_, raw_token_)); + certificate_manager_.SignWithPrivateCertificate( + visibility_history_.last_visibility, padded_token); if (optional_signature.has_value()) { encryption_frame->set_optional_signed_data(optional_signature->data(), @@ -300,7 +301,7 @@ PairedKeyVerificationRunner::VerifyAuthTokenHashWithPrivateCertificate( DeviceVisibility visibility, const nearby::sharing::service::proto::V1Frame& frame) { std::optional> hash = - certificate_manager_->HashAuthenticationTokenWithPrivateCertificate( + certificate_manager_.HashAuthenticationTokenWithPrivateCertificate( visibility, raw_token_); const std::string& frame_hash = @@ -328,8 +329,11 @@ PairedKeyVerificationRunner::VerifyPairedKeyEncryptionFrame( auto signed_data = frame.paired_key_encryption().signed_data(); std::vector data(signed_data.begin(), signed_data.end()); - if (!certificate_->VerifySignature(PadPrefix(remote_prefix_, raw_token_), - data)) { + std::vector padded_token = PadPrefix( + share_target_is_incoming_ ? kNearbyShareSenderVerificationPrefix + : kNearbyShareReceiverVerificationPrefix, + raw_token_); + if (!certificate_->VerifySignature(padded_token, data)) { if (!frame.paired_key_encryption().has_optional_signed_data()) { LOG(WARNING) << __func__ << ": Unable to verify remote paired key encryption frame. " @@ -341,8 +345,7 @@ PairedKeyVerificationRunner::VerifyPairedKeyEncryptionFrame( frame.paired_key_encryption().optional_signed_data(); std::vector optional_data(optional_signed_data.begin(), optional_signed_data.end()); - if (certificate_->VerifySignature(PadPrefix(remote_prefix_, raw_token_), - optional_data)) { + if (certificate_->VerifySignature(padded_token, optional_data)) { LOG(INFO) << "Successfully verified remote paired key encryption " "frame with the optional signed data."; } else { @@ -374,17 +377,13 @@ void PairedKeyVerificationRunner::ApplyResult( case PairedKeyVerificationResult::kUnable: verification_result_ = PairedKeyVerificationResult::kUnable; break; - case PairedKeyVerificationResult::kUnknown: - default: - verification_result_ = PairedKeyVerificationResult::kUnable; - break; } } bool PairedKeyVerificationRunner::IsVisibilityRecentlyUpdated() const { return visibility_history_.visibility != visibility_history_.last_visibility && - (clock_->Now() - visibility_history_.last_visibility_time < + (clock_.Now() - visibility_history_.last_visibility_time < kRelaxAfterSetVisibilityTimeout); } diff --git a/sharing/paired_key_verification_runner.h b/sharing/paired_key_verification_runner.h index 6bfc8026..372e656c 100644 --- a/sharing/paired_key_verification_runner.h +++ b/sharing/paired_key_verification_runner.h @@ -22,6 +22,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/functional/any_invocable.h" #include "absl/time/time.h" #include "internal/platform/clock.h" @@ -38,8 +39,6 @@ class PairedKeyVerificationRunner : public std::enable_shared_from_this { public: enum class PairedKeyVerificationResult { - // Default value for verification result. - kUnknown, // Succeeded with verification. kSuccess, // Failed to verify. @@ -55,7 +54,8 @@ class PairedKeyVerificationRunner }; PairedKeyVerificationRunner( - Clock* clock, location::nearby::proto::sharing::OSType os_type, + Clock* absl_nonnull clock, + location::nearby::proto::sharing::OSType os_type, bool share_target_is_incoming, const VisibilityHistory& visibility_history, const std::vector& token, @@ -63,8 +63,9 @@ class PairedKeyVerificationRunner void(const nearby::sharing::service::proto::Frame& frame)> frame_writer, const std::optional& certificate, - NearbyShareCertificateManager* certificate_manager, - IncomingFramesReader* frames_reader, absl::Duration read_frame_timeout); + NearbyShareCertificateManager* absl_nonnull certificate_manager, + IncomingFramesReader* absl_nonnull frames_reader, + absl::Duration read_frame_timeout); ~PairedKeyVerificationRunner(); @@ -95,22 +96,21 @@ class PairedKeyVerificationRunner // True if visibility has changed recently. bool IsVisibilityRecentlyUpdated() const; - nearby::Clock* const clock_; + nearby::Clock& clock_; + NearbyShareCertificateManager& certificate_manager_; + IncomingFramesReader& frames_reader_; + const bool share_target_is_incoming_; const location::nearby::proto::sharing::OSType os_type_; - VisibilityHistory visibility_history_; + const VisibilityHistory visibility_history_; + const std::optional certificate_; + const absl::Duration read_frame_timeout_; std::vector raw_token_; absl::AnyInvocable frame_writer_; - std::optional certificate_; - NearbyShareCertificateManager* certificate_manager_; - IncomingFramesReader* frames_reader_; - const absl::Duration read_frame_timeout_; std::function callback_; PairedKeyVerificationResult verification_result_; - char local_prefix_; - char remote_prefix_; }; } // namespace nearby::sharing diff --git a/sharing/paired_key_verification_runner_test.cc b/sharing/paired_key_verification_runner_test.cc index 32e0e72c..6b02462d 100644 --- a/sharing/paired_key_verification_runner_test.cc +++ b/sharing/paired_key_verification_runner_test.cc @@ -124,7 +124,6 @@ GenerateVisibilityHistory() { DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, DeviceVisibility::DEVICE_VISIBILITY_SELF_SHARE, DeviceVisibility::DEVICE_VISIBILITY_EVERYONE, - DeviceVisibility::DEVICE_VISIBILITY_HIDDEN, }; std::list result; for (DeviceVisibility visibility : kValidVisibilities) { @@ -355,13 +354,32 @@ class PairedKeyVerificationRunnerTest : public testing::Test { }; TEST_F(PairedKeyVerificationRunnerTest, - NullCertificate_InvalidPairedKeyEncryptionFrame) { + Incoming_NullCertificate_InvalidPairedKeyEncryptionFrame) { // Empty key encryption frame fails the certificate verification. SetUpPairedKeyEncryptionFrame(ReturnFrameType::kEmpty); SetUpPairedKeyResultFrame(ReturnFrameType::kValid); RunVerification( - true, + /*is_incoming=*/true, + /*use_valid_public_certificate=*/false, + {.visibility = DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, + .last_visibility = DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, + .last_visibility_time = GetFakeClock()->Now()}, + /*expected_result=*/ + PairedKeyVerificationResult::kFail); + + ExpectPairedKeyEncryptionFrameSent(); + ExpectPairedKeyResultFrameSent(PairedKeyResultFrame::UNABLE); +} + +TEST_F(PairedKeyVerificationRunnerTest, + Outgoing_NullCertificate_InvalidPairedKeyEncryptionFrame) { + // Empty key encryption frame fails the certificate verification. + SetUpPairedKeyEncryptionFrame(ReturnFrameType::kEmpty); + SetUpPairedKeyResultFrame(ReturnFrameType::kValid); + + RunVerification( + /*is_incoming=*/false, /*use_valid_public_certificate=*/false, {.visibility = DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, .last_visibility = DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, @@ -373,6 +391,25 @@ TEST_F(PairedKeyVerificationRunnerTest, ExpectPairedKeyResultFrameSent(PairedKeyResultFrame::UNABLE); } +TEST_F(PairedKeyVerificationRunnerTest, + Incoming_HiddenDevice_FailsConnection) { + // Empty key encryption frame fails the certificate verification. + SetUpPairedKeyEncryptionFrame(ReturnFrameType::kEmpty); + SetUpPairedKeyResultFrame(ReturnFrameType::kValid); + + RunVerification( + /*is_incoming=*/true, + /*use_valid_public_certificate=*/false, + {.visibility = DeviceVisibility::DEVICE_VISIBILITY_HIDDEN, + .last_visibility = DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, + .last_visibility_time = GetFakeClock()->Now()}, + /*expected_result=*/ + PairedKeyVerificationResult::kFail); + + ExpectPairedKeyEncryptionFrameSent(); + ExpectPairedKeyResultFrameSent(PairedKeyResultFrame::FAIL); +} + TEST_F(PairedKeyVerificationRunnerTest, ValidPairedKeyEncryptionFrame_ResultFrameTimedOut) { SetUpPairedKeyEncryptionFrame(ReturnFrameType::kValid); @@ -437,14 +474,40 @@ TEST_P(ParameterisedPairedKeyVerificationRunnerTest, PairedKeyResultFrame result_frame = std::get<1>(GetParam()); PairedKeyVerificationRunner::VisibilityHistory visibility_history = std::get<2>(GetParam()); + PairedKeyVerificationRunner::PairedKeyVerificationResult result = + params.result; + // If our visibility has no certificates, then downgrade expected result to + // kUnable if it is not expected to fail. + if ((visibility_history.visibility == + DeviceVisibility::DEVICE_VISIBILITY_EVERYONE) && + !(visibility_history.last_visibility != + DeviceVisibility::DEVICE_VISIBILITY_EVERYONE && + (params.encryption_frame_type == + PairedKeyVerificationRunnerTest::ReturnFrameType::kOptionalValid || + params.encryption_frame_type == + PairedKeyVerificationRunnerTest::ReturnFrameType::kValid))) { + if (result == + PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess) { + result = + PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable; + } + } + if (params.is_incoming && + params.encryption_frame_type == + PairedKeyVerificationRunnerTest::ReturnFrameType::kEmpty && + visibility_history.visibility != + DeviceVisibility::DEVICE_VISIBILITY_EVERYONE) { + result = + PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail; + } PairedKeyVerificationRunner::PairedKeyVerificationResult expected_result = - Merge(params.result, result_frame.status()); + Merge(result, result_frame.status()); LOG(ERROR) << "ValidEncryptionFrame_ValidResultFrame: " << "is_incoming=" << params.is_incoming << ", has_valid_cert=" << params.has_valid_certificate << ", encryption_frame_type=" << (int)params.encryption_frame_type - << ", result=" << (int)params.result + << ", result=" << (int)result << ", expected_result=" << (int)expected_result << ", result_frame=" << (int)result_frame.status() << ", visibility=" << (int)visibility_history.visibility @@ -463,22 +526,6 @@ TEST_P(ParameterisedPairedKeyVerificationRunnerTest, : OSType::UNKNOWN_OS_TYPE); } - // If our visibility has no certificates, then downgrade expected result to - // kUnable if it is not expected to fail. - if ((visibility_history.visibility == - DeviceVisibility::DEVICE_VISIBILITY_EVERYONE || - visibility_history.visibility == - DeviceVisibility::DEVICE_VISIBILITY_HIDDEN) && - (visibility_history.last_visibility == - DeviceVisibility::DEVICE_VISIBILITY_EVERYONE || - visibility_history.last_visibility == - DeviceVisibility::DEVICE_VISIBILITY_HIDDEN)) { - if (expected_result == - PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess) { - expected_result = - PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable; - } - } visibility_history.last_visibility_time = GetFakeClock()->Now(); RunVerification( /*is_incoming=*/params.is_incoming, diff --git a/sharing/share_session.cc b/sharing/share_session.cc index 004b3779..3c7d1676 100644 --- a/sharing/share_session.cc +++ b/sharing/share_session.cc @@ -235,12 +235,6 @@ bool ShareSession::ProcessKeyVerificationResult( // share flag. self_share_ = false; break; - - case PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnknown: - LOG(WARNING) << __func__ - << ": Unknown PairedKeyVerificationResult for target " - << share_target().id << ". Disconnecting."; - return false; } return true; } diff --git a/sharing/share_session_test.cc b/sharing/share_session_test.cc index fc6d9211..ddb3d3b5 100644 --- a/sharing/share_session_test.cc +++ b/sharing/share_session_test.cc @@ -389,20 +389,6 @@ TEST(ShareSessionTest, ProcessKeyVerificationResultNotSelfShareUnable) { EXPECT_FALSE(session.token().empty()); } -TEST(ShareSessionTest, ProcessKeyVerificationResultUnknown) { - ShareTarget share_target; - TestShareSession session(std::string(kEndpointId), share_target); - NearbyConnectionImpl connection(session.device_info()); - session.SetNearbyConnection(&connection); - session.SetTokenForTests("9876"); - - EXPECT_FALSE(session.ProcessKeyVerificationResult( - PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnknown, - OSType::WINDOWS)); - EXPECT_EQ(session.os_type(), OSType::WINDOWS); - EXPECT_FALSE(session.token().empty()); -} - TEST(ShareSessionTest, AbortNotConnected) { ShareTarget share_target; TestShareSession session(std::string(kEndpointId), share_target); From 70e6a829277d222beb12a28cd5351bc5d4e89e54 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 13 May 2026 12:46:06 -0700 Subject: [PATCH 087/151] Change default for responsive UI flag. PiperOrigin-RevId: 915004449 --- sharing/flags/generated/nearby_sharing_feature_flags.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharing/flags/generated/nearby_sharing_feature_flags.h b/sharing/flags/generated/nearby_sharing_feature_flags.h index 6cead2ee..ec0900d3 100755 --- a/sharing/flags/generated/nearby_sharing_feature_flags.h +++ b/sharing/flags/generated/nearby_sharing_feature_flags.h @@ -103,7 +103,7 @@ constexpr auto kEnableNativeNotifications = flags::Flag(kConfigPackage, "45743135", false); // When true, enables responsive UI. constexpr auto kEnableResponsiveUi = - flags::Flag(kConfigPackage, "45727212", false); + flags::Flag(kConfigPackage, "45727212", true); inline absl::btree_map&> GetBoolFlags() { return { From f3a18121a9a3d6a85960a1dab21e733c77f35a63 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 13 May 2026 14:13:29 -0700 Subject: [PATCH 088/151] Fix device type to string. PiperOrigin-RevId: 915051624 --- Package.swift | 1 + internal/platform/implementation/BUILD | 13 +++++++ .../platform/implementation/device_info.h | 35 ++++++++++--------- .../implementation/device_info_test.cc | 29 +++++++++++++++ 4 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 internal/platform/implementation/device_info_test.cc diff --git a/Package.swift b/Package.swift index c0736224..351ea2ca 100644 --- a/Package.swift +++ b/Package.swift @@ -441,6 +441,7 @@ let package = Package( "internal/platform/crypto_test.cc", "internal/platform/byte_array_test.cc", "internal/platform/credential_storage_impl_test.cc", + "internal/platform/implementation/device_info_test.cc", "internal/platform/implementation/g3/awdl_test.cc", "internal/platform/implementation/g3/ble_test.cc", "internal/platform/input_stream_test.cc", diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index b1d9877e..69254c03 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -195,3 +195,16 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_test( + name = "device_info_test", + size = "small", + timeout = "moderate", + srcs = ["device_info_test.cc"], + deps = [ + ":types", + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_absl//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/internal/platform/implementation/device_info.h b/internal/platform/implementation/device_info.h index 89d937d6..3d3e859a 100644 --- a/internal/platform/implementation/device_info.h +++ b/internal/platform/implementation/device_info.h @@ -31,23 +31,6 @@ class DeviceInfo { public: enum class ScreenStatus { kUndetermined = 0, kLocked, kUnlocked }; enum class DeviceType { kUnknown = 0, kPhone, kTablet, kLaptop }; - template - void AbslStringify(Sink& sink, DeviceType device_type) { - switch (device_type) { - case DeviceType::kUnknown: - sink.Append("Unknown"); - return; - case DeviceType::kPhone: - sink.Append("Phone"); - return; - case DeviceType::kTablet: - sink.Append("Tablet"); - return; - case DeviceType::kLaptop: - sink.Append("PC"); - return; - } - } enum class OsType { kUnknown = 0, kAndroid, @@ -88,6 +71,24 @@ class DeviceInfo { virtual bool AllowSleep() = 0; }; +template +void AbslStringify(Sink& sink, DeviceInfo::DeviceType device_type) { + switch (device_type) { + case DeviceInfo::DeviceType::kUnknown: + sink.Append("Unknown"); + return; + case DeviceInfo::DeviceType::kPhone: + sink.Append("Phone"); + return; + case DeviceInfo::DeviceType::kTablet: + sink.Append("Tablet"); + return; + case DeviceInfo::DeviceType::kLaptop: + sink.Append("PC"); + return; + } +} + } // namespace api } // namespace nearby diff --git a/internal/platform/implementation/device_info_test.cc b/internal/platform/implementation/device_info_test.cc new file mode 100644 index 00000000..cae28209 --- /dev/null +++ b/internal/platform/implementation/device_info_test.cc @@ -0,0 +1,29 @@ +// Copyright 2026 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. + +#include "internal/platform/implementation/device_info.h" + +#include "gtest/gtest.h" +#include "absl/strings/str_cat.h" + +namespace nearby::api { +namespace { + +TEST(DeviceInfoTest, DeviceTypeToStringTest) { + DeviceInfo::DeviceType type = DeviceInfo::DeviceType::kPhone; + EXPECT_EQ(absl::StrCat(type), "Phone"); +} + +} // namespace +} // namespace nearby::api From 5a846d91550b71518973890bea7385f0de8b4ef0 Mon Sep 17 00:00:00 2001 From: Nick Bourdakos Date: Wed, 13 May 2026 15:41:07 -0700 Subject: [PATCH 089/151] Remove WebrtcPeerId stub implementation. PiperOrigin-RevId: 915097446 --- Package.swift | 1 - connections/implementation/mediums/BUILD | 2 - .../implementation/mediums/webrtc_peer_id.cc | 7 +-- .../implementation/mediums/webrtc_peer_id.h | 5 -- .../mediums/webrtc_peer_id_stub.cc | 39 -------------- .../mediums/webrtc_peer_id_stub.h | 54 ------------------- .../implementation/mediums/webrtc_stub.h | 2 +- .../implementation/webrtc_bwu_handler_stub.cc | 2 +- 8 files changed, 4 insertions(+), 108 deletions(-) delete mode 100644 connections/implementation/mediums/webrtc_peer_id_stub.cc delete mode 100644 connections/implementation/mediums/webrtc_peer_id_stub.h diff --git a/Package.swift b/Package.swift index 351ea2ca..54d62c41 100644 --- a/Package.swift +++ b/Package.swift @@ -523,7 +523,6 @@ let package = Package( "connections/implementation/webrtc_bwu_handler.cc", "connections/implementation/webrtc_endpoint_channel.cc", "connections/implementation/mediums/webrtc.cc", - "connections/implementation/mediums/webrtc_peer_id.cc", "connections/implementation/mediums/webrtc", "internal/platform/tachyon_express_signaling_messenger.cc", "internal/platform/tachyon_express_signaling_messenger.h", diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index ad7736f8..0d8aea37 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -93,11 +93,9 @@ cc_library( name = "webrtc_utils", srcs = [ "webrtc_peer_id.cc", - "webrtc_peer_id_stub.cc", ], hdrs = [ "webrtc_peer_id.h", - "webrtc_peer_id_stub.h", "webrtc_socket.h", "webrtc_socket_stub.h", ], diff --git a/connections/implementation/mediums/webrtc_peer_id.cc b/connections/implementation/mediums/webrtc_peer_id.cc index 801d40c6..5e7f6224 100644 --- a/connections/implementation/mediums/webrtc_peer_id.cc +++ b/connections/implementation/mediums/webrtc_peer_id.cc @@ -12,15 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef NO_WEBRTC - #include "connections/implementation/mediums/webrtc_peer_id.h" -#include +#include #include "absl/strings/ascii.h" #include "absl/strings/escaping.h" #include "connections/implementation/mediums/utils.h" +#include "internal/platform/byte_array.h" namespace nearby { namespace connections { @@ -52,5 +51,3 @@ bool WebrtcPeerId::IsValid() const { return !id_.empty(); } } // namespace mediums } // namespace connections } // namespace nearby - -#endif diff --git a/connections/implementation/mediums/webrtc_peer_id.h b/connections/implementation/mediums/webrtc_peer_id.h index 93013902..e97deee3 100644 --- a/connections/implementation/mediums/webrtc_peer_id.h +++ b/connections/implementation/mediums/webrtc_peer_id.h @@ -15,9 +15,6 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_ID_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_ID_H_ -#ifndef NO_WEBRTC - -#include #include #include "internal/platform/byte_array.h" @@ -49,6 +46,4 @@ class WebrtcPeerId { } // namespace connections } // namespace nearby -#endif - #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_ID_H_ diff --git a/connections/implementation/mediums/webrtc_peer_id_stub.cc b/connections/implementation/mediums/webrtc_peer_id_stub.cc deleted file mode 100644 index 1b74dad2..00000000 --- a/connections/implementation/mediums/webrtc_peer_id_stub.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2020 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. - -#ifdef NO_WEBRTC - -#include "connections/implementation/mediums/webrtc_peer_id_stub.h" - -#include - -#include "absl/strings/ascii.h" -#include "absl/strings/escaping.h" -#include "connections/implementation/mediums/utils.h" - -namespace nearby { -namespace connections { -namespace mediums { - -WebrtcPeerId WebrtcPeerId::FromRandom() { return {}; } - -WebrtcPeerId WebrtcPeerId::FromSeed(const ByteArray& seed) { return {}; } - -bool WebrtcPeerId::IsValid() const { return false; } - -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif diff --git a/connections/implementation/mediums/webrtc_peer_id_stub.h b/connections/implementation/mediums/webrtc_peer_id_stub.h deleted file mode 100644 index 8d249a8c..00000000 --- a/connections/implementation/mediums/webrtc_peer_id_stub.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_ID_STUB_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_ID_STUB_H_ - -#ifdef NO_WEBRTC - -#include -#include - -#include "internal/platform/byte_array.h" - -namespace nearby { -namespace connections { -namespace mediums { - -// WebrtcPeerId is used as an identifier to exchange SDP messages to establish -// WebRTC p2p connection. An empty WebrtcPeerId is considered to be invalid. -class WebrtcPeerId { - public: - WebrtcPeerId() = default; - explicit WebrtcPeerId(const std::string& id) : id_(id) {} - ~WebrtcPeerId() = default; - - static WebrtcPeerId FromRandom(); - static WebrtcPeerId FromSeed(const ByteArray& seed); - - bool IsValid() const; - - const std::string& GetId() const { return id_; } - - private: - std::string id_; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_ID_STUB_H_ diff --git a/connections/implementation/mediums/webrtc_stub.h b/connections/implementation/mediums/webrtc_stub.h index 787acd7a..832fc38f 100644 --- a/connections/implementation/mediums/webrtc_stub.h +++ b/connections/implementation/mediums/webrtc_stub.h @@ -22,7 +22,7 @@ #include #include -#include "connections/implementation/mediums/webrtc_peer_id_stub.h" +#include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/mediums/webrtc_socket_stub.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "internal/platform/cancellation_flag.h" diff --git a/connections/implementation/webrtc_bwu_handler_stub.cc b/connections/implementation/webrtc_bwu_handler_stub.cc index 062ca77c..619b7647 100644 --- a/connections/implementation/webrtc_bwu_handler_stub.cc +++ b/connections/implementation/webrtc_bwu_handler_stub.cc @@ -22,7 +22,7 @@ #include "absl/functional/bind_front.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/mediums/utils.h" -#include "connections/implementation/mediums/webrtc_peer_id_stub.h" +#include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/webrtc_endpoint_channel.h" #include "internal/platform/expected.h" From 8e4f67912c91fca38cd13f0c1abf9928185a33e4 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 13 May 2026 17:00:52 -0700 Subject: [PATCH 090/151] Improve testing. PiperOrigin-RevId: 915133080 --- .../nearby_share_local_device_data_manager_impl_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc b/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc index 3aa66539..d33eb8d6 100644 --- a/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc +++ b/sharing/local_device_data/nearby_share_local_device_data_manager_impl_test.cc @@ -140,6 +140,7 @@ TEST_F(NearbyShareLocalDeviceDataManagerImplTest, DefaultDeviceName) { kFakeGivenName, GetDeviceType()), manager()->GetDeviceName()); + EXPECT_EQ(manager()->GetDeviceName(), "Barack奥巴马's PC"); // Make sure that when we use a given name that is very long we truncate // correctly. From b66eebfef41d03c7b51a4119be4326afc3bc8662 Mon Sep 17 00:00:00 2001 From: Nick Bourdakos Date: Thu, 14 May 2026 09:47:28 -0700 Subject: [PATCH 091/151] Remove the need for WebRtcSocket stub PiperOrigin-RevId: 915477372 --- connections/implementation/BUILD | 6 +- connections/implementation/mediums/BUILD | 30 ++-- connections/implementation/mediums/webrtc.cc | 21 +-- connections/implementation/mediums/webrtc.h | 10 +- .../implementation/mediums/webrtc/BUILD | 28 ++-- .../mediums/webrtc/connection_flow.cc | 14 +- .../mediums/webrtc/connection_flow.h | 2 +- .../mediums/webrtc/connection_flow_test.cc | 45 +++--- .../mediums/webrtc/data_channel_listener.h | 8 +- .../mediums/webrtc/webrtc_socket_impl.cc | 53 ++++--- .../mediums/webrtc/webrtc_socket_impl.h | 53 ++++--- .../mediums/webrtc/webrtc_socket_impl_test.cc | 28 ++-- .../implementation/mediums/webrtc_socket.h | 59 ++++--- .../mediums/webrtc_socket_stub.h | 71 --------- .../implementation/mediums/webrtc_stub.cc | 4 +- .../implementation/mediums/webrtc_stub.h | 6 +- .../implementation/mediums/webrtc_test.cc | 145 ++++++++++-------- .../implementation/p2p_cluster_pcp_handler.h | 1 - .../implementation/webrtc_bwu_handler.cc | 21 +-- .../implementation/webrtc_bwu_handler.h | 12 +- .../implementation/webrtc_bwu_handler_stub.cc | 6 +- .../implementation/webrtc_bwu_handler_stub.h | 16 +- .../implementation/webrtc_endpoint_channel.cc | 13 +- .../implementation/webrtc_endpoint_channel.h | 9 +- 24 files changed, 315 insertions(+), 346 deletions(-) delete mode 100644 connections/implementation/mediums/webrtc_socket_stub.h diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 61c37dc0..dea9acf3 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -155,7 +155,8 @@ cc_library( "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums", "//connections/implementation/mediums:utils", - "//connections/implementation/mediums:webrtc_utils", + "//connections/implementation/mediums:webrtc_peer_id", + "//connections/implementation/mediums:webrtc_socket", "//connections/implementation/mediums/advertisements:dct_advertisement", "//connections/implementation/mediums/advertisements:util", "//connections/implementation/mediums/ble:ble_advertisement_header", @@ -315,10 +316,9 @@ cc_test( ":internal_test", ":types", "//connections:core_types", - "//connections/implementation/analytics", "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums", - "//connections/implementation/mediums:webrtc_utils", + "//connections/implementation/mediums:webrtc_peer_id", "//connections/implementation/proto:offline_wire_formats_cc_proto", "//connections/v3:v3_types", "//internal/analytics:mock_event_logger", diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index 0d8aea37..e215226d 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -50,7 +50,8 @@ cc_library( ], deps = [ ":utils", - ":webrtc_utils", + ":webrtc_peer_id", + ":webrtc_socket", "//connections:core_types", "//connections/implementation:types", "//connections/implementation/flags:connections_flags", @@ -71,7 +72,6 @@ cc_library( "//internal/platform/flags:platform_flags", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", - "//internal/platform/implementation:wifi_utils", "//proto/mediums:web_rtc_signaling_frames_cc_proto", # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep # "//third_party/webrtc/files/stable/webrtc/api:jsep", @@ -90,15 +90,9 @@ cc_library( ) cc_library( - name = "webrtc_utils", - srcs = [ - "webrtc_peer_id.cc", - ], - hdrs = [ - "webrtc_peer_id.h", - "webrtc_socket.h", - "webrtc_socket_stub.h", - ], + name = "webrtc_peer_id", + srcs = ["webrtc_peer_id.cc"], + hdrs = ["webrtc_peer_id.h"], visibility = [ "//connections/implementation:__pkg__", "//connections/implementation/mediums:__pkg__", @@ -106,7 +100,6 @@ cc_library( ], deps = [ ":utils", - "//connections/implementation/mediums/webrtc:data_types", "//internal/platform:base", "@com_google_absl//absl/strings", ], @@ -141,6 +134,16 @@ cc_library( ], ) +cc_library( + name = "webrtc_socket", + hdrs = ["webrtc_socket.h"], + visibility = ["//connections/implementation:__subpackages__"], + deps = [ + "//internal/platform:base", + "@com_google_absl//absl/strings:string_view", + ], +) + cc_test( name = "core_internal_mediums_test", size = "small", @@ -197,7 +200,8 @@ cc_test( ], deps = [ ":mediums", - ":webrtc_utils", + ":webrtc_peer_id", + ":webrtc_socket", "//internal/platform:base", "//internal/platform:cancellation_flag", "//internal/platform:comm", diff --git a/connections/implementation/mediums/webrtc.cc b/connections/implementation/mediums/webrtc.cc index c0fc4a56..1c412e8c 100644 --- a/connections/implementation/mediums/webrtc.cc +++ b/connections/implementation/mediums/webrtc.cc @@ -207,13 +207,13 @@ void WebRtc::StopAcceptingConnections(const std::string& service_id) { << service_id; } -ErrorOr WebRtc::Connect( +ErrorOr> WebRtc::Connect( const std::string& service_id, const WebrtcPeerId& remote_peer_id, const LocationHint& location_hint, CancellationFlag* cancellation_flag, bool non_cellular) { service_id_to_connect_attempts_count_map_[service_id] = 1; medium_->SetNonCellular(non_cellular); - ErrorOr wrapper_result = { + ErrorOr> wrapper_result = { Error(OperationResultCode::DETAIL_UNKNOWN)}; while (service_id_to_connect_attempts_count_map_[service_id] <= kConnectAttemptsLimit) { @@ -242,12 +242,12 @@ ErrorOr WebRtc::Connect( return {Error(wrapper_result.error().operation_result_code().value())}; } -ErrorOr WebRtc::AttemptToConnect( +ErrorOr> WebRtc::AttemptToConnect( const std::string& service_id, const WebrtcPeerId& remote_peer_id, const LocationHint& location_hint, CancellationFlag* cancellation_flag) { ConnectionRequestInfo info = ConnectionRequestInfo(); info.self_peer_id = WebrtcPeerId::FromRandom(); - Future socket_future = info.socket_future; + Future> socket_future = info.socket_future; // `listener` will go out of scope at the end of `AttemptToConnect`, and this // is expected. This `listener` is tied to `socket_future` which we block on @@ -329,7 +329,7 @@ ErrorOr WebRtc::AttemptToConnect( // Wait for the connection to go through. Don't hold the mutex here so that // we're not blocking necessary operations. - ExceptionOr socket_result = + ExceptionOr> socket_result = socket_future.Get(kDataChannelTimeout); { @@ -660,9 +660,9 @@ void WebRtc::RestartTachyonReceiveMessages(const std::string& service_id) { << service_id; } -void WebRtc::ProcessDataChannelOpen(const std::string& service_id, - const WebrtcPeerId& remote_peer_id, - WebRtcSocketWrapper socket_wrapper) { +void WebRtc::ProcessDataChannelOpen( + const std::string& service_id, const WebrtcPeerId& remote_peer_id, + std::shared_ptr socket_wrapper) { MutexLock lock(&mutex_); // Notify the client of the newly formed socket. @@ -683,7 +683,7 @@ void WebRtc::ProcessDataChannelOpen(const std::string& service_id, } // No one to handle the newly created DataChannel, so we'll just close it. - socket_wrapper.Close(); + socket_wrapper->Close(); LOG(INFO) << "Ignoring new DataChannel because we are not accepting " "connections for service " << service_id; @@ -719,7 +719,8 @@ std::unique_ptr WebRtc::CreateConnectionFlow( }}}, { .data_channel_open_cb = {[this, service_id, remote_peer_id]( - WebRtcSocketWrapper socket_wrapper) { + std::shared_ptr + socket_wrapper) { OffloadFromThread( "rtc-channel-created", [this, service_id, remote_peer_id, socket_wrapper]() { diff --git a/connections/implementation/mediums/webrtc.h b/connections/implementation/mediums/webrtc.h index 66b84b45..47fcbc52 100644 --- a/connections/implementation/mediums/webrtc.h +++ b/connections/implementation/mediums/webrtc.h @@ -50,7 +50,7 @@ class WebRtc { public: // Callback that is invoked when a new connection is accepted. using AcceptedConnectionCallback = absl::AnyInvocable; + const std::string& service_id, std::shared_ptr socket)>; WebRtc(); ~WebRtc(); @@ -85,7 +85,7 @@ class WebRtc { // Initiates a WebRtc connection with peer device identified by |peer_id| // with internal retry for maximum attempts of kConnectAttemptsLimit. // Runs on @MainThread. - ErrorOr Connect( + ErrorOr> Connect( const std::string& service_id, const WebrtcPeerId& peer_id, const location::nearby::connections::LocationHint& location_hint, CancellationFlag* cancellation_flag, bool non_cellular) @@ -145,13 +145,13 @@ class WebRtc { // The pending DataChannel future. Our client will be blocked on this while // they wait for us to set up the channel over Tachyon. - Future socket_future; + Future> socket_future; }; // Attempt to initiates a WebRtc connection with peer device identified by // |peer_id|. // Runs on @MainThread. - ErrorOr AttemptToConnect( + ErrorOr> AttemptToConnect( const std::string& service_id, const WebrtcPeerId& peer_id, const location::nearby::connections::LocationHint& location_hint, CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_); @@ -214,7 +214,7 @@ class WebRtc { // Runs on |single_thread_executor_|. void ProcessDataChannelOpen(const std::string& service_id, const WebrtcPeerId& remote_peer_id, - WebRtcSocketWrapper socket_wrapper) + std::shared_ptr socket_wrapper) ABSL_LOCKS_EXCLUDED(mutex_); // Runs on |single_thread_executor_|. diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index a2b92747..3c20133b 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -37,9 +37,10 @@ cc_library( "//connections/implementation:__subpackages__", ], deps = [ - ":data_types", + ":webrtc_socket_impl", "//connections:core_types", - "//connections/implementation/mediums:webrtc_utils", + "//connections/implementation/mediums:webrtc_peer_id", + "//connections/implementation/mediums:webrtc_socket", "//internal/platform:base", "//internal/platform:comm", "//internal/platform:logging", @@ -57,24 +58,20 @@ cc_library( ) cc_library( - name = "data_types", - srcs = [ - "webrtc_socket_impl.cc", - ], - hdrs = [ - "webrtc_socket_impl.h", - ], - copts = [ - "-DCORE_ADAPTER_DLL", - "-DNO_WEBRTC", - ], + name = "webrtc_socket_impl", + srcs = ["webrtc_socket_impl.cc"], + hdrs = ["webrtc_socket_impl.h"], visibility = [ "//connections/implementation:__subpackages__", ], deps = [ + "//connections/implementation/mediums:webrtc_socket", "//internal/platform:base", "//internal/platform:logging", "//internal/platform:types", + # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", + # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/strings:string_view", ], ) @@ -92,9 +89,10 @@ cc_test( "requires-net:external", ], deps = [ - ":data_types", ":webrtc", - "//connections/implementation/mediums:webrtc_utils", + ":webrtc_socket_impl", + "//connections/implementation/mediums:webrtc_peer_id", + "//connections/implementation/mediums:webrtc_socket", "//internal/platform:base", "//internal/platform:comm", "//internal/platform:test_util", diff --git a/connections/implementation/mediums/webrtc/connection_flow.cc b/connections/implementation/mediums/webrtc/connection_flow.cc index 1d32ae17..bff8e441 100644 --- a/connections/implementation/mediums/webrtc/connection_flow.cc +++ b/connections/implementation/mediums/webrtc/connection_flow.cc @@ -412,10 +412,11 @@ void ConnectionFlow::OnSignalingStable() { void ConnectionFlow::CreateSocketFromDataChannel( webrtc::scoped_refptr data_channel) { LOG(INFO) << "Creating data channel socket"; - auto socket = - std::make_unique("WebRtcSocket", std::move(data_channel)); + auto socket = std::make_shared("WebRtcSocket", + std::move(data_channel)); + socket_ = socket; socket->SetSocketListener({ - .socket_ready_cb = {[this](WebRtcSocket* socket) { + .socket_ready_cb = {[this](WebRtcSocketImpl* socket) { CHECK(IsRunningOnSignalingThread()); if (!TransitionState(State::kWaitingToConnect, State::kConnected)) { LOG(ERROR) << "Data channel socket is open but connection " @@ -424,14 +425,13 @@ void ConnectionFlow::CreateSocketFromDataChannel( return; } // Pass socket wrapper by copy on purpose - data_channel_listener_.data_channel_open_cb(socket_wrapper_); + data_channel_listener_.data_channel_open_cb(socket_); }}, .socket_closed_cb = - [this](WebRtcSocket*) { + [this](WebRtcSocketImpl*) { data_channel_listener_.data_channel_closed_cb(); }, }); - socket_wrapper_ = WebRtcSocketWrapper(std::move(socket)); } void ConnectionFlow::OnIceCandidate(const webrtc::IceCandidate* candidate) { @@ -512,7 +512,7 @@ bool ConnectionFlow::CloseOnSignalingThread() { // Close the socket wrapper before terminating the PeerConnection // since the teardown process of the PC may close threads that are // otherwise depended upon by objects kept alive by the socket_wrapper. - if (socket_wrapper_.IsValid()) socket_wrapper_.Close(); + if (socket_ && socket_->IsValid()) socket_->Close(); // This prevents other tasks from queuing on the signaling thread for this // object. diff --git a/connections/implementation/mediums/webrtc/connection_flow.h b/connections/implementation/mediums/webrtc/connection_flow.h index e0986786..73e8294e 100644 --- a/connections/implementation/mediums/webrtc/connection_flow.h +++ b/connections/implementation/mediums/webrtc/connection_flow.h @@ -222,7 +222,7 @@ class ConnectionFlow : public webrtc::PeerConnectionObserver { // Used to hold a reference to the WebRtcSocket while the data channel is // connecting. - WebRtcSocketWrapper socket_wrapper_; + std::shared_ptr socket_; std::vector> cached_remote_ice_candidates_; diff --git a/connections/implementation/mediums/webrtc/connection_flow_test.cc b/connections/implementation/mediums/webrtc/connection_flow_test.cc index 64a7766d..e08aa5ae 100644 --- a/connections/implementation/mediums/webrtc/connection_flow_test.cc +++ b/connections/implementation/mediums/webrtc/connection_flow_test.cc @@ -61,7 +61,8 @@ TEST_F(ConnectionFlowTest, SuccessfulOfferAnswerFlow) { Future message_received_future; - Future offerer_socket_future, answerer_socket_future; + Future> offerer_socket_future, + answerer_socket_future; std::unique_ptr offerer, answerer; @@ -77,7 +78,7 @@ TEST_F(ConnectionFlowTest, SuccessfulOfferAnswerFlow) { answerer->OnRemoteIceCandidatesReceived(std::move(vec)); }}, {.data_channel_open_cb = - [&offerer_socket_future](WebRtcSocketWrapper socket) { + [&offerer_socket_future](std::shared_ptr socket) { offerer_socket_future.Set(std::move(socket)); }}, {.adapter_type_changed_cb = @@ -97,7 +98,7 @@ TEST_F(ConnectionFlowTest, SuccessfulOfferAnswerFlow) { offerer->OnRemoteIceCandidatesReceived(std::move(vec)); }}, {.data_channel_open_cb = - [&answerer_socket_future](WebRtcSocketWrapper socket) { + [&answerer_socket_future](std::shared_ptr socket) { answerer_socket_future.Set(std::move(socket)); }}, {.adapter_type_changed_cb = @@ -122,18 +123,18 @@ TEST_F(ConnectionFlowTest, SuccessfulOfferAnswerFlow) { EXPECT_TRUE(answerer->SetLocalSessionDescription(std::move(answer))); // Retrieve Data Channels - ExceptionOr offerer_socket = + ExceptionOr> offerer_socket = offerer_socket_future.Get(absl::Seconds(1)); EXPECT_TRUE(offerer_socket.ok()); - ExceptionOr answerer_socket = + ExceptionOr> answerer_socket = answerer_socket_future.Get(absl::Seconds(1)); EXPECT_TRUE(answerer_socket.ok()); // Send message on data channel absl::string_view message = "Test"; - offerer_socket.result().GetImpl().GetOutputStream().Write(message); + offerer_socket.result()->GetOutputStream().Write(message); ExceptionOr received_message = - answerer_socket.result().GetImpl().GetInputStream().Read(4); + answerer_socket.result()->GetInputStream().Read(4); EXPECT_TRUE(received_message.ok()); EXPECT_EQ(received_message.result(), ByteArray{message.data()}); } @@ -259,7 +260,8 @@ TEST_F(ConnectionFlowTest, TerminateAnswerer) { Future message_received_future; - Future offerer_socket_future, answerer_socket_future; + Future> offerer_socket_future, + answerer_socket_future; std::unique_ptr offerer, answerer; @@ -275,7 +277,7 @@ TEST_F(ConnectionFlowTest, TerminateAnswerer) { answerer->OnRemoteIceCandidatesReceived(std::move(vec)); }}, {.data_channel_open_cb = - [&offerer_socket_future](WebRtcSocketWrapper socket) { + [&offerer_socket_future](std::shared_ptr socket) { offerer_socket_future.Set(std::move(socket)); }}, {.adapter_type_changed_cb = @@ -295,7 +297,7 @@ TEST_F(ConnectionFlowTest, TerminateAnswerer) { offerer->OnRemoteIceCandidatesReceived(std::move(vec)); }}, {.data_channel_open_cb = - [&answerer_socket_future](WebRtcSocketWrapper wrapper) { + [&answerer_socket_future](std::shared_ptr wrapper) { answerer_socket_future.Set(std::move(wrapper)); }}, {.adapter_type_changed_cb = @@ -321,10 +323,10 @@ TEST_F(ConnectionFlowTest, TerminateAnswerer) { EXPECT_TRUE(answerer->SetLocalSessionDescription(std::move(answer))); // Retrieve Data Channels - ExceptionOr offerer_socket = + ExceptionOr> offerer_socket = offerer_socket_future.Get(absl::Seconds(1)); EXPECT_TRUE(offerer_socket.ok()); - ExceptionOr answerer_socket = + ExceptionOr> answerer_socket = answerer_socket_future.Get(absl::Seconds(1)); EXPECT_TRUE(offerer_socket.ok()); @@ -338,9 +340,9 @@ TEST_F(ConnectionFlowTest, TerminateAnswerer) { // Send message on data channel absl::string_view message = "Test"; - offerer_socket.result().GetOutputStream().Write(message); + offerer_socket.result()->GetOutputStream().Write(message); ExceptionOr received_message = - answerer_socket.result().GetInputStream().Read(4); + answerer_socket.result()->GetInputStream().Read(4); EXPECT_TRUE(received_message.GetResult().Empty()); } @@ -349,7 +351,8 @@ TEST_F(ConnectionFlowTest, TerminateOfferer) { Future message_received_future; - Future offerer_socket_future, answerer_socket_future; + Future> offerer_socket_future, + answerer_socket_future; std::unique_ptr offerer, answerer; @@ -365,7 +368,7 @@ TEST_F(ConnectionFlowTest, TerminateOfferer) { answerer->OnRemoteIceCandidatesReceived(std::move(vec)); }}, {.data_channel_open_cb = - [&offerer_socket_future](WebRtcSocketWrapper socket) { + [&offerer_socket_future](std::shared_ptr socket) { offerer_socket_future.Set(std::move(socket)); }}, {.adapter_type_changed_cb = @@ -386,7 +389,7 @@ TEST_F(ConnectionFlowTest, TerminateOfferer) { offerer->OnRemoteIceCandidatesReceived(std::move(vec)); }}, {.data_channel_open_cb = - [&answerer_socket_future](WebRtcSocketWrapper wrapper) { + [&answerer_socket_future](std::shared_ptr wrapper) { answerer_socket_future.Set(std::move(wrapper)); }}, {.adapter_type_changed_cb = @@ -412,10 +415,10 @@ TEST_F(ConnectionFlowTest, TerminateOfferer) { EXPECT_TRUE(answerer->SetLocalSessionDescription(std::move(answer))); // Retrieve Data Channels - ExceptionOr offerer_socket = + ExceptionOr> offerer_socket = offerer_socket_future.Get(absl::Seconds(1)); EXPECT_TRUE(offerer_socket.ok()); - ExceptionOr answerer_socket = + ExceptionOr> answerer_socket = answerer_socket_future.Get(absl::Seconds(1)); EXPECT_TRUE(offerer_socket.ok()); @@ -429,9 +432,9 @@ TEST_F(ConnectionFlowTest, TerminateOfferer) { // Send message on data channel absl::string_view message = "Test"; - offerer_socket.result().GetOutputStream().Write(message); + offerer_socket.result()->GetOutputStream().Write(message); ExceptionOr received_message = - answerer_socket.result().GetInputStream().Read(4); + answerer_socket.result()->GetInputStream().Read(4); EXPECT_TRUE(received_message.GetResult().Empty()); } diff --git a/connections/implementation/mediums/webrtc/data_channel_listener.h b/connections/implementation/mediums/webrtc/data_channel_listener.h index 17e6a0dc..ec679940 100644 --- a/connections/implementation/mediums/webrtc/data_channel_listener.h +++ b/connections/implementation/mediums/webrtc/data_channel_listener.h @@ -17,6 +17,8 @@ #ifndef NO_WEBRTC +#include + #include "absl/functional/any_invocable.h" #include "connections/implementation/mediums/webrtc_socket.h" @@ -28,8 +30,8 @@ namespace mediums { struct DataChannelListener { // Called when the data channel is open and the socket wrapper is ready to // read and write. - absl::AnyInvocable data_channel_open_cb = - [](WebRtcSocketWrapper) {}; + absl::AnyInvocable)> data_channel_open_cb = + [](std::shared_ptr) {}; // Called when the data channel is closed. absl::AnyInvocable data_channel_closed_cb = []() {}; @@ -39,6 +41,6 @@ struct DataChannelListener { } // namespace connections } // namespace nearby -#endif +#endif // NO_WEBRTC #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc b/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc index aca93c67..c34160c5 100644 --- a/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc +++ b/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc @@ -12,6 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#ifndef NO_WEBRTC + +#include "connections/implementation/mediums/webrtc/webrtc_socket_impl.h" + #include #include #include @@ -21,19 +25,20 @@ #include "internal/platform/byte_array.h" #include "internal/platform/exception.h" #include "internal/platform/input_stream.h" -#include "internal/platform/pipe.h" -#ifndef NO_WEBRTC - -#include "connections/implementation/mediums/webrtc/webrtc_socket_impl.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" +#include "internal/platform/output_stream.h" +#include "internal/platform/pipe.h" +#include "internal/platform/runnable.h" +#include "webrtc/api/data_channel_interface.h" +#include "webrtc/api/scoped_refptr.h" namespace nearby { namespace connections { namespace mediums { // OutputStreamImpl -Exception WebRtcSocket::OutputStreamImpl::Write(absl::string_view data) { +Exception WebRtcSocketImpl::OutputStreamImpl::Write(absl::string_view data) { if (data.size() > kMaxDataSize) { LOG(WARNING) << "Sending data larger than 1MB"; return {Exception::kIo}; @@ -53,18 +58,18 @@ Exception WebRtcSocket::OutputStreamImpl::Write(absl::string_view data) { return {Exception::kSuccess}; } -Exception WebRtcSocket::OutputStreamImpl::Flush() { +Exception WebRtcSocketImpl::OutputStreamImpl::Flush() { // Java implementation is empty. return {Exception::kSuccess}; } -Exception WebRtcSocket::OutputStreamImpl::Close() { +Exception WebRtcSocketImpl::OutputStreamImpl::Close() { socket_->Close(); return {Exception::kSuccess}; } // WebRtcSocket -WebRtcSocket::WebRtcSocket( +WebRtcSocketImpl::WebRtcSocketImpl( const std::string& name, webrtc::scoped_refptr data_channel) : name_(name), data_channel_(std::move(data_channel)) { @@ -73,7 +78,7 @@ WebRtcSocket::WebRtcSocket( data_channel_->RegisterObserver(this); } -WebRtcSocket::~WebRtcSocket() { +WebRtcSocketImpl::~WebRtcSocketImpl() { LOG(INFO) << "WebRtcSocket::~WebRtcSocket(" << name_ << ") this: " << this; if (!IsClosed()) { @@ -85,16 +90,16 @@ WebRtcSocket::~WebRtcSocket() { << " done"; } -InputStream& WebRtcSocket::GetInputStream() { return *pipe_input_; } +InputStream& WebRtcSocketImpl::GetInputStream() { return *pipe_input_; } -OutputStream& WebRtcSocket::GetOutputStream() { return output_stream_; } +OutputStream& WebRtcSocketImpl::GetOutputStream() { return output_stream_; } -Exception WebRtcSocket::Close() { +Exception WebRtcSocketImpl::Close() { LOG(INFO) << "WebRtcSocket::Close(" << name_ << ") this: " << this; if (closed_.Set(true)) return {Exception::kSuccess}; ClosePipe(); - // NOTE: This call blocks and triggers a state change on the siginaling thread + // NOTE: This call blocks and triggers a state change on the signaling thread // to 'closing' but does not block until 'closed' is sent so the data channel // is not fully closed when this call is done. data_channel_->Close(); @@ -102,7 +107,7 @@ Exception WebRtcSocket::Close() { return {Exception::kSuccess}; } -void WebRtcSocket::OnStateChange() { +void WebRtcSocketImpl::OnStateChange() { // Running on the signaling thread right now. LOG(ERROR) << "WebRtcSocket::OnStateChange() webrtc data channel state: " << webrtc::DataChannelInterface::DataStateString( @@ -131,7 +136,7 @@ void WebRtcSocket::OnStateChange() { break; } } -void WebRtcSocket::OnMessage(const webrtc::DataBuffer& buffer) { +void WebRtcSocketImpl::OnMessage(const webrtc::DataBuffer& buffer) { // This is a data channel callback on the signaling thread, lets off load so // we don't block signaling. OffloadFromSignalingThread( @@ -147,20 +152,20 @@ void WebRtcSocket::OnMessage(const webrtc::DataBuffer& buffer) { }); } -void WebRtcSocket::OnBufferedAmountChange(uint64_t sent_data_size) { +void WebRtcSocketImpl::OnBufferedAmountChange(uint64_t sent_data_size) { // This is a data channel callback on the signaling thread, lets off load so // we don't block signaling. OffloadFromSignalingThread([this] { WakeUpWriter(); }); } -bool WebRtcSocket::SendMessage(const ByteArray& data) { +bool WebRtcSocketImpl::SendMessage(const ByteArray& data) { return data_channel_->Send( webrtc::DataBuffer(std::string(data.data(), data.size()))); } -bool WebRtcSocket::IsClosed() { return closed_.Get(); } +bool WebRtcSocketImpl::IsClosed() { return closed_.Get(); } -void WebRtcSocket::ClosePipe() { +void WebRtcSocketImpl::ClosePipe() { LOG(INFO) << "WebRtcSocket::ClosePipe(" << name_ << ") this: " << this; // This is thread-safe to close these sockets even if a read or write is in // process on another thread, Close will wait for the exclusive mutex before @@ -173,16 +178,16 @@ void WebRtcSocket::ClosePipe() { } // Must not be called on signalling thread. -void WebRtcSocket::WakeUpWriter() { +void WebRtcSocketImpl::WakeUpWriter() { MutexLock lock(&backpressure_mutex_); buffer_variable_.Notify(); } -void WebRtcSocket::SetSocketListener(SocketListener&& listener) { +void WebRtcSocketImpl::SetSocketListener(SocketListener&& listener) { socket_listener_ = std::move(listener); } -void WebRtcSocket::BlockUntilSufficientSpaceInBuffer(int length) { +void WebRtcSocketImpl::BlockUntilSufficientSpaceInBuffer(int length) { MutexLock lock(&backpressure_mutex_); while (!IsClosed() && (data_channel_->buffered_amount() + length > kMaxDataSize)) { @@ -191,7 +196,7 @@ void WebRtcSocket::BlockUntilSufficientSpaceInBuffer(int length) { } } -void WebRtcSocket::OffloadFromSignalingThread(Runnable runnable) { +void WebRtcSocketImpl::OffloadFromSignalingThread(Runnable runnable) { single_thread_executor_.Execute(std::move(runnable)); } @@ -199,4 +204,4 @@ void WebRtcSocket::OffloadFromSignalingThread(Runnable runnable) { } // namespace connections } // namespace nearby -#endif +#endif // NO_WEBRTC diff --git a/connections/implementation/mediums/webrtc/webrtc_socket_impl.h b/connections/implementation/mediums/webrtc/webrtc_socket_impl.h index 109367b7..071522ef 100644 --- a/connections/implementation/mediums/webrtc/webrtc_socket_impl.h +++ b/connections/implementation/mediums/webrtc/webrtc_socket_impl.h @@ -15,23 +15,27 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_IMPL_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_IMPL_H_ -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/exception.h" -#include "internal/platform/listeners.h" -#include "internal/platform/runnable.h" #ifndef NO_WEBRTC + +#include +#include +#include + +#include "absl/functional/any_invocable.h" +#include "absl/strings/string_view.h" +#include "connections/implementation/mediums/webrtc_socket.h" #include "internal/platform/atomic_boolean.h" +#include "internal/platform/byte_array.h" #include "internal/platform/condition_variable.h" +#include "internal/platform/exception.h" #include "internal/platform/input_stream.h" +#include "internal/platform/listeners.h" #include "internal/platform/mutex.h" #include "internal/platform/output_stream.h" +#include "internal/platform/runnable.h" #include "internal/platform/single_thread_executor.h" -#include "internal/platform/socket.h" +#include "webrtc/api/data_channel_interface.h" +#include "webrtc/api/scoped_refptr.h" namespace nearby { namespace connections { @@ -45,20 +49,22 @@ constexpr int kMaxDataSize = 1 * 1024 * 1024; // // Messages are buffered here to prevent the data channel from overflowing, // which could lead to data loss. -class WebRtcSocket : public Socket, public webrtc::DataChannelObserver { +class WebRtcSocketImpl : public WebRtcSocket, + public webrtc::DataChannelObserver { public: - WebRtcSocket( + WebRtcSocketImpl( const std::string& name, webrtc::scoped_refptr data_channel); - ~WebRtcSocket() override; + ~WebRtcSocketImpl() override; - WebRtcSocket(const WebRtcSocket& other) = delete; - WebRtcSocket& operator=(const WebRtcSocket& other) = delete; + WebRtcSocketImpl(const WebRtcSocketImpl& other) = delete; + WebRtcSocketImpl& operator=(const WebRtcSocketImpl& other) = delete; - // Overrides for nearby::Socket: + // Overrides for WebRtcSocket: InputStream& GetInputStream() override; OutputStream& GetOutputStream() override; Exception Close() override; + bool IsValid() const override { return true; } // webrtc::DataChannelObserver: void OnStateChange() override; @@ -67,10 +73,10 @@ class WebRtcSocket : public Socket, public webrtc::DataChannelObserver { // Listener class the gets called when the socket is ready or closed struct SocketListener { - absl::AnyInvocable socket_ready_cb = - DefaultCallback(); - absl::AnyInvocable socket_closed_cb = - DefaultCallback(); + absl::AnyInvocable socket_ready_cb = + DefaultCallback(); + absl::AnyInvocable socket_closed_cb = + DefaultCallback(); }; void SetSocketListener(SocketListener&& listener); @@ -78,7 +84,8 @@ class WebRtcSocket : public Socket, public webrtc::DataChannelObserver { private: class OutputStreamImpl : public OutputStream { public: - explicit OutputStreamImpl(WebRtcSocket* const socket) : socket_(socket) {} + explicit OutputStreamImpl(WebRtcSocketImpl* const socket) + : socket_(socket) {} ~OutputStreamImpl() override = default; OutputStreamImpl(const OutputStreamImpl& other) = delete; @@ -91,7 +98,7 @@ class WebRtcSocket : public Socket, public webrtc::DataChannelObserver { private: // |this| OutputStreamImpl is owned by |socket_|. - WebRtcSocket* const socket_; + WebRtcSocketImpl* const socket_; }; void WakeUpWriter(); @@ -124,6 +131,6 @@ class WebRtcSocket : public Socket, public webrtc::DataChannelObserver { } // namespace connections } // namespace nearby -#endif +#endif // NO_WEBRTC #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_IMPL_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc b/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc index 78ec1771..b7f46c3a 100644 --- a/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc +++ b/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc @@ -64,7 +64,7 @@ TEST(WebRtcSocketTest, ReadFromSocket) { const char* message = "message"; webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); webrtc_socket.OnMessage(webrtc::DataBuffer{message}); ExceptionOr result = webrtc_socket.GetInputStream().Read(7); @@ -75,7 +75,7 @@ TEST(WebRtcSocketTest, ReadFromSocket) { TEST(WebRtcSocketTest, ReadMultipleMessages) { webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); webrtc_socket.OnMessage(webrtc::DataBuffer{"Me"}); webrtc_socket.OnMessage(webrtc::DataBuffer{"ssa"}); @@ -101,7 +101,7 @@ TEST(WebRtcSocketTest, WriteToSocket) { absl::string_view kMessage{"Message"}; webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); EXPECT_CALL(*mock_data_channel, Send(testing::_)) .WillRepeatedly(testing::Return(true)); @@ -112,7 +112,7 @@ TEST(WebRtcSocketTest, SendDataBiggerThanMax) { std::string kMessage(kMaxDataSize + 1, '0'); webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); EXPECT_CALL(*mock_data_channel, Send(testing::_)).Times(0); EXPECT_EQ(webrtc_socket.GetOutputStream().Write(kMessage), @@ -123,7 +123,7 @@ TEST(WebRtcSocketTest, WriteToDataChannelFails) { absl::string_view kMessage{"Message"}; webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); ON_CALL(*mock_data_channel, Send(testing::_)) .WillByDefault(testing::Return(false)); @@ -134,14 +134,14 @@ TEST(WebRtcSocketTest, WriteToDataChannelFails) { TEST(WebRtcSocketTest, Close) { webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); EXPECT_CALL(*mock_data_channel, Close()); int socket_closed_cb_called = 0; webrtc_socket.SetSocketListener( - {.socket_closed_cb = [&](WebRtcSocket* socket) { + {.socket_closed_cb = [&](WebRtcSocketImpl* socket) { socket_closed_cb_called++; }}); webrtc_socket.Close(); @@ -160,7 +160,7 @@ TEST(WebRtcSocketTest, WriteOnClosedChannel) { absl::string_view kMessage{"Message"}; webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); webrtc_socket.Close(); EXPECT_CALL(*mock_data_channel, Send(testing::_)).Times(0); @@ -172,7 +172,7 @@ TEST(WebRtcSocketTest, ReadFromClosedChannel) { absl::string_view kMessage{"Message"}; webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); ON_CALL(*mock_data_channel, Send(testing::_)) .WillByDefault(testing::Return(true)); @@ -185,7 +185,7 @@ TEST(WebRtcSocketTest, ReadFromClosedChannel) { TEST(WebRtcSocketTest, DataChannelCloseEventCleansUp) { webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); ON_CALL(*mock_data_channel, state()) .WillByDefault( @@ -203,12 +203,12 @@ TEST(WebRtcSocketTest, DataChannelCloseEventCleansUp) { TEST(WebRtcSocketTest, OpenStateTriggersCallback) { webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); int socket_ready_cb_called = 0; webrtc_socket.SetSocketListener( - {.socket_ready_cb = [&](WebRtcSocket* socket) { + {.socket_ready_cb = [&](WebRtcSocketImpl* socket) { socket_ready_cb_called++; }}); @@ -224,12 +224,12 @@ TEST(WebRtcSocketTest, OpenStateTriggersCallback) { TEST(WebRtcSocketTest, CloseStateTriggersCallback) { webrtc::scoped_refptr mock_data_channel( new MockDataChannel()); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); + WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); int socket_closed_cb_called = 0; webrtc_socket.SetSocketListener( - {.socket_closed_cb = [&](WebRtcSocket* socket) { + {.socket_closed_cb = [&](WebRtcSocketImpl* socket) { socket_closed_cb_called++; }}); diff --git a/connections/implementation/mediums/webrtc_socket.h b/connections/implementation/mediums/webrtc_socket.h index 724e247a..3881c2f0 100644 --- a/connections/implementation/mediums/webrtc_socket.h +++ b/connections/implementation/mediums/webrtc_socket.h @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2026 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,44 +15,57 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_SOCKET_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_SOCKET_H_ +#include + +#include "absl/strings/string_view.h" +#include "internal/platform/byte_array.h" #include "internal/platform/exception.h" -#ifndef NO_WEBRTC - -#include - -#include "connections/implementation/mediums/webrtc/webrtc_socket_impl.h" +#include "internal/platform/input_stream.h" +#include "internal/platform/output_stream.h" +#include "internal/platform/socket.h" namespace nearby { namespace connections { namespace mediums { -class WebRtcSocketWrapper final { +// A base implementation that creates a non-working WebRtcSocket that can be +// used as a placeholder when WebRTC is disabled. +class WebRtcSocket : public Socket { public: - WebRtcSocketWrapper() = default; - WebRtcSocketWrapper(const WebRtcSocketWrapper&) = default; - WebRtcSocketWrapper& operator=(const WebRtcSocketWrapper&) = default; - explicit WebRtcSocketWrapper(std::unique_ptr socket) - : impl_(socket.release()) {} - ~WebRtcSocketWrapper() = default; + ~WebRtcSocket() override = default; - InputStream& GetInputStream() { return impl_->GetInputStream(); } + InputStream& GetInputStream() override { return fake_input_stream_; } - OutputStream& GetOutputStream() { return impl_->GetOutputStream(); } + OutputStream& GetOutputStream() override { return fake_output_stream_; } - Exception Close() { return impl_->Close(); } + Exception Close() override { return {Exception::kSuccess}; } - bool IsValid() const { return impl_ != nullptr; } - - WebRtcSocket& GetImpl() { return *impl_; } + virtual bool IsValid() const { return false; } private: - std::shared_ptr impl_; + class FakeInputStream : public InputStream { + public: + ExceptionOr Read(std::int64_t size) override { + return {Exception::kSuccess}; + } + Exception Close() override { return {Exception::kSuccess}; } + }; + + class FakeOutputStream : public OutputStream { + public: + Exception Write(absl::string_view data) override { + return {Exception::kSuccess}; + } + Exception Flush() override { return {Exception::kSuccess}; } + Exception Close() override { return {Exception::kSuccess}; } + }; + + FakeInputStream fake_input_stream_; + FakeOutputStream fake_output_stream_; }; } // namespace mediums } // namespace connections } // namespace nearby -#endif - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_H_ +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_SOCKET_H_ diff --git a/connections/implementation/mediums/webrtc_socket_stub.h b/connections/implementation/mediums/webrtc_socket_stub.h deleted file mode 100644 index f3f104ef..00000000 --- a/connections/implementation/mediums/webrtc_socket_stub.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_SOCKET_STUB_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_SOCKET_STUB_H_ - -#ifdef NO_WEBRTC - -#include - -#include "internal/platform/input_stream.h" -#include "internal/platform/output_stream.h" - -namespace nearby { -namespace connections { -namespace mediums { -class FakeInputStream : public InputStream { - public: - ExceptionOr Read(std::int64_t size) { - return {Exception::kSuccess}; - } - Exception Close() { return {Exception::kSuccess}; } -}; - -class FakeOutputStream : public OutputStream { - public: - Exception Write(absl::string_view data) override { - return {Exception::kSuccess}; - } - Exception Flush() override { return {Exception::kSuccess}; } - Exception Close() override { return {Exception::kSuccess}; } -}; - -class WebRtcSocketWrapper final { - public: - WebRtcSocketWrapper() = default; - WebRtcSocketWrapper(const WebRtcSocketWrapper&) = default; - WebRtcSocketWrapper& operator=(const WebRtcSocketWrapper&) = default; - ~WebRtcSocketWrapper() = default; - - InputStream& GetInputStream() { return fake_input_stream_; } - - OutputStream& GetOutputStream() { return fake_output_stream_; } - - void Close() {} - - bool IsValid() const { return false; } - - private: - FakeInputStream fake_input_stream_; - FakeOutputStream fake_output_stream_; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_SOCKET_STUB_H_ diff --git a/connections/implementation/mediums/webrtc_stub.cc b/connections/implementation/mediums/webrtc_stub.cc index 385fc882..b50a7bf4 100644 --- a/connections/implementation/mediums/webrtc_stub.cc +++ b/connections/implementation/mediums/webrtc_stub.cc @@ -19,7 +19,7 @@ #include #include -#include "connections/implementation/mediums/webrtc_socket_stub.h" +#include "connections/implementation/mediums/webrtc_socket.h" #include "internal/platform/cancelable_alarm.h" #include "internal/platform/expected.h" #include "internal/platform/future.h" @@ -52,7 +52,7 @@ bool WebRtc::StartAcceptingConnections(const std::string& service_id, void WebRtc::StopAcceptingConnections(const std::string& service_id) {} -ErrorOr WebRtc::Connect( +ErrorOr> WebRtc::Connect( const std::string& service_id, const WebrtcPeerId& remote_peer_id, const LocationHint& location_hint, CancellationFlag* cancellation_flag) { return {Error(OperationResultCode::DETAIL_UNKNOWN)}; diff --git a/connections/implementation/mediums/webrtc_stub.h b/connections/implementation/mediums/webrtc_stub.h index 832fc38f..ef5ddfb9 100644 --- a/connections/implementation/mediums/webrtc_stub.h +++ b/connections/implementation/mediums/webrtc_stub.h @@ -23,7 +23,7 @@ #include #include "connections/implementation/mediums/webrtc_peer_id.h" -#include "connections/implementation/mediums/webrtc_socket_stub.h" +#include "connections/implementation/mediums/webrtc_socket.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" @@ -38,7 +38,7 @@ class WebRtc { public: // Callback that is invoked when a new connection is accepted. using AcceptedConnectionCallback = - absl::AnyInvocable; + absl::AnyInvocable socket)>; WebRtc(); ~WebRtc(); @@ -69,7 +69,7 @@ class WebRtc { // Initiates a WebRtc connection with peer device identified by |peer_id| // with internal retry for maximum attempts of kConnectAttemptsLimit. // Runs on @MainThread. - ErrorOr Connect( + ErrorOr> Connect( const std::string& service_id, const WebrtcPeerId& peer_id, const location::nearby::connections::LocationHint& location_hint, CancellationFlag* cancellation_flag); diff --git a/connections/implementation/mediums/webrtc_test.cc b/connections/implementation/mediums/webrtc_test.cc index 061dbd4c..fbd4da27 100644 --- a/connections/implementation/mediums/webrtc_test.cc +++ b/connections/implementation/mediums/webrtc_test.cc @@ -61,7 +61,7 @@ class TestWebRtc : public WebRtc { class WebRtcTest : public ::testing::TestWithParam { protected: using MockAcceptedCallback = testing::MockFunction; + const std::string& service_id, std::shared_ptr socket)>; MediumEnvironment& env_{MediumEnvironment::Instance()}; }; @@ -73,7 +73,7 @@ TEST_P(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) { WebRtcTestParams params = GetParam(); env_.SetFeatureFlags(params.feature_flags); WebRtc receiver, sender; - WebRtcSocketWrapper receiver_socket; + std::shared_ptr receiver_socket; const WebrtcPeerId self_id("self_id"); const std::string service_id("NearbySharing"); LocationHint location_hint; @@ -82,18 +82,19 @@ TEST_P(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) { receiver.StartAcceptingConnections( service_id, self_id, location_hint, - [&receiver_socket, connected](const std::string& service_id, - WebRtcSocketWrapper wrapper) mutable { + [&receiver_socket, connected]( + const std::string& service_id, + std::shared_ptr wrapper) mutable { receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); + connected.Set(receiver_socket->IsValid()); }, params.non_cellular); CancellationFlag flag; - ErrorOr sender_socket_result = sender.Connect( + ErrorOr> sender_socket_result = sender.Connect( service_id, self_id, location_hint, &flag, params.non_cellular); EXPECT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value().IsValid()); + EXPECT_TRUE(sender_socket_result.value()->IsValid()); ExceptionOr devices_connected = connected.Get(); ASSERT_TRUE(devices_connected.ok()); @@ -102,9 +103,9 @@ TEST_P(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) { // Only shuts down signaling channel. receiver.StopAcceptingConnections(service_id); - sender_socket_result.value().GetOutputStream().Write(message); + sender_socket_result.value()->GetOutputStream().Write(message); ExceptionOr received_msg = - receiver_socket.GetInputStream().Read(/*size=*/32); + receiver_socket->GetInputStream().Read(/*size=*/32); ASSERT_TRUE(received_msg.ok()); EXPECT_EQ(message, received_msg.result().AsStringView()); env_.Stop(); @@ -115,7 +116,7 @@ TEST_P(WebRtcTest, CanCancelConnect) { WebRtcTestParams params = GetParam(); env_.SetFeatureFlags(params.feature_flags); WebRtc receiver, sender; - WebRtcSocketWrapper receiver_socket; + std::shared_ptr receiver_socket; const WebrtcPeerId self_id("self_id"); const std::string service_id("NearbySharing"); LocationHint location_hint; @@ -124,32 +125,33 @@ TEST_P(WebRtcTest, CanCancelConnect) { receiver.StartAcceptingConnections( service_id, self_id, location_hint, - [&receiver_socket, connected](const std::string& service_id, - WebRtcSocketWrapper wrapper) mutable { + [&receiver_socket, connected]( + const std::string& service_id, + std::shared_ptr wrapper) mutable { receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); + connected.Set(receiver_socket->IsValid()); }, params.non_cellular); CancellationFlag flag(true); - ErrorOr sender_socket_result = sender.Connect( + ErrorOr> sender_socket_result = sender.Connect( service_id, self_id, location_hint, &flag, params.non_cellular); // If FeatureFlag is disabled, Cancelled is false as no-op. if (!params.feature_flags.enable_cancellation_flag) { EXPECT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value().IsValid()); + EXPECT_TRUE(sender_socket_result.value()->IsValid()); ExceptionOr devices_connected = connected.Get(); ASSERT_TRUE(devices_connected.ok()); EXPECT_TRUE(devices_connected.result()); - sender_socket_result.value().GetOutputStream().Write(message); + sender_socket_result.value()->GetOutputStream().Write(message); ExceptionOr received_msg = - receiver_socket.GetInputStream().Read(/*size=*/32); + receiver_socket->GetInputStream().Read(/*size=*/32); ASSERT_TRUE(received_msg.ok()); EXPECT_EQ(message, received_msg.result().AsStringView()); - receiver_socket.Close(); + receiver_socket->Close(); } else { EXPECT_TRUE(sender_socket_result.has_error()); } @@ -200,7 +202,7 @@ TEST_P(WebRtcTest, Connect_NoPeer) { ASSERT_TRUE(webrtc.IsAvailable()); CancellationFlag flag; - ErrorOr wrapper_1_result = webrtc.Connect( + ErrorOr> wrapper_1_result = webrtc.Connect( service_id, peer_id, location_hint, &flag, params.non_cellular); EXPECT_TRUE(wrapper_1_result.has_error()); @@ -225,7 +227,7 @@ TEST_P(WebRtcTest, StartAcceptingConnection_ThenConnect) { service_id, self_id, location_hint, mock_accepted_callback_.AsStdFunction(), params.non_cellular)); CancellationFlag flag; - ErrorOr wrapper_result = + ErrorOr> wrapper_result = webrtc.Connect(service_id, WebrtcPeerId("random_peer_id"), location_hint, &flag, params.non_cellular); EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); @@ -262,7 +264,7 @@ TEST_P(WebRtcTest, StartAndStopAcceptingConnections) { TEST_P(WebRtcTest, ConnectTwice) { env_.Start({.webrtc_enabled = true}); WebRtc receiver, sender, device_c; - WebRtcSocketWrapper receiver_socket; + std::shared_ptr receiver_socket; WebRtcTestParams params = GetParam(); const WebrtcPeerId self_id("self_id"), other_id("other_id"); const std::string service_id("NearbySharing"); @@ -272,45 +274,47 @@ TEST_P(WebRtcTest, ConnectTwice) { receiver.StartAcceptingConnections( service_id, self_id, location_hint, - [&receiver_socket, connected](const std::string& service_id, - WebRtcSocketWrapper wrapper) mutable { + [&receiver_socket, connected]( + const std::string& service_id, + std::shared_ptr wrapper) mutable { receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); + connected.Set(receiver_socket->IsValid()); }, params.non_cellular); device_c.StartAcceptingConnections( service_id, other_id, location_hint, - [](const std::string& service_id, WebRtcSocketWrapper wrapper) {}, + [](const std::string& service_id, std::shared_ptr wrapper) { + }, params.non_cellular); CancellationFlag flag; - ErrorOr sender_socket_result = sender.Connect( + ErrorOr> sender_socket_result = sender.Connect( service_id, self_id, location_hint, &flag, params.non_cellular); EXPECT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value().IsValid()); + EXPECT_TRUE(sender_socket_result.value()->IsValid()); ExceptionOr devices_connected = connected.Get(); ASSERT_TRUE(devices_connected.ok()); EXPECT_TRUE(devices_connected.result()); - ErrorOr socket_result = sender.Connect( + ErrorOr> socket_result = sender.Connect( service_id, other_id, location_hint, &flag, params.non_cellular); EXPECT_TRUE(socket_result.has_value()); - EXPECT_TRUE(socket_result.value().IsValid()); - socket_result.value().Close(); + EXPECT_TRUE(socket_result.value()->IsValid()); + socket_result.value()->Close(); - EXPECT_TRUE(receiver_socket.IsValid()); + EXPECT_TRUE(receiver_socket->IsValid()); EXPECT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value().IsValid()); + EXPECT_TRUE(sender_socket_result.value()->IsValid()); - sender_socket_result.value().GetOutputStream().Write(message); + sender_socket_result.value()->GetOutputStream().Write(message); ExceptionOr received_msg = - receiver_socket.GetInputStream().Read(/*size=*/32); + receiver_socket->GetInputStream().Read(/*size=*/32); ASSERT_TRUE(received_msg.ok()); EXPECT_EQ(message, received_msg.result().AsStringView()); - receiver_socket.Close(); + receiver_socket->Close(); env_.Stop(); } @@ -319,7 +323,7 @@ TEST_P(WebRtcTest, ConnectTwice) { TEST_P(WebRtcTest, ConnectBothDevicesAndAbort) { env_.Start({.webrtc_enabled = true}); WebRtc receiver, sender; - WebRtcSocketWrapper receiver_socket, sender_socket; + std::shared_ptr receiver_socket, sender_socket; WebRtcTestParams params = GetParam(); const WebrtcPeerId self_id("self_id"); const std::string service_id("NearbySharing"); @@ -328,24 +332,25 @@ TEST_P(WebRtcTest, ConnectBothDevicesAndAbort) { receiver.StartAcceptingConnections( service_id, self_id, location_hint, - [&receiver_socket, connected](const std::string& service_id, - WebRtcSocketWrapper wrapper) mutable { + [&receiver_socket, connected]( + const std::string& service_id, + std::shared_ptr wrapper) mutable { receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); + connected.Set(receiver_socket->IsValid()); }, params.non_cellular); CancellationFlag flag; - ErrorOr sender_socket_result = sender.Connect( + ErrorOr> sender_socket_result = sender.Connect( service_id, self_id, location_hint, &flag, params.non_cellular); EXPECT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value().IsValid()); + EXPECT_TRUE(sender_socket_result.value()->IsValid()); ExceptionOr devices_connected = connected.Get(); ASSERT_TRUE(devices_connected.ok()); EXPECT_TRUE(devices_connected.result()); - receiver_socket.Close(); + receiver_socket->Close(); env_.Stop(); } @@ -354,7 +359,7 @@ TEST_P(WebRtcTest, ConnectBothDevicesAndAbort) { TEST_P(WebRtcTest, ConnectBothDevicesAndSendData) { env_.Start({.webrtc_enabled = true}); WebRtc receiver, sender; - WebRtcSocketWrapper receiver_socket; + std::shared_ptr receiver_socket; WebRtcTestParams params = GetParam(); const WebrtcPeerId self_id("self_id"); const std::string service_id("NearbySharing"); @@ -364,30 +369,31 @@ TEST_P(WebRtcTest, ConnectBothDevicesAndSendData) { receiver.StartAcceptingConnections( service_id, self_id, location_hint, - [&receiver_socket, connected](const std::string& service_id, - WebRtcSocketWrapper wrapper) mutable { + [&receiver_socket, connected]( + const std::string& service_id, + std::shared_ptr wrapper) mutable { receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); + connected.Set(receiver_socket->IsValid()); }, params.non_cellular); CancellationFlag flag; - ErrorOr sender_socket_result = sender.Connect( + ErrorOr> sender_socket_result = sender.Connect( service_id, self_id, location_hint, &flag, params.non_cellular); EXPECT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value().IsValid()); + EXPECT_TRUE(sender_socket_result.value()->IsValid()); ExceptionOr devices_connected = connected.Get(); ASSERT_TRUE(devices_connected.ok()); EXPECT_TRUE(devices_connected.result()); - sender_socket_result.value().GetOutputStream().Write(message); + sender_socket_result.value()->GetOutputStream().Write(message); ExceptionOr received_msg = - receiver_socket.GetInputStream().Read(/*size=*/32); + receiver_socket->GetInputStream().Read(/*size=*/32); ASSERT_TRUE(received_msg.ok()); EXPECT_EQ(message, received_msg.result().AsStringView()); - receiver_socket.Close(); + receiver_socket->Close(); env_.Stop(); } @@ -405,7 +411,7 @@ TEST_P(WebRtcTest, Connect_NullPeerConnection) { ASSERT_TRUE(webrtc.IsAvailable()); CancellationFlag flag; - ErrorOr wrapper_result = + ErrorOr> wrapper_result = webrtc.Connect(service_id, WebrtcPeerId("random_peer_id"), location_hint, &flag, params.non_cellular); EXPECT_TRUE(wrapper_result.has_error()); @@ -456,7 +462,7 @@ TEST_P(WebRtcTest, CancelDuringConnect) { .enable_cancellation_flag = true, }); - WebRtcSocketWrapper receiver_socket, sender_socket; + std::shared_ptr receiver_socket, sender_socket; const WebrtcPeerId self_id("self_id"); const std::string service_id("NearbySharing"); LocationHint location_hint; @@ -479,14 +485,15 @@ TEST_P(WebRtcTest, CancelDuringConnect) { receiver->StartAcceptingConnections( service_id, self_id, location_hint, - [&receiver_socket, connected](const std::string& service_id, - WebRtcSocketWrapper wrapper) mutable { + [&receiver_socket, connected]( + const std::string& service_id, + std::shared_ptr wrapper) mutable { receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); + connected.Set(receiver_socket->IsValid()); }, params.non_cellular); - ErrorOr sender_socket_result = sender->Connect( + ErrorOr> sender_socket_result = sender->Connect( service_id, self_id, location_hint, &sender_flag, params.non_cellular); // Since the flag was cancelled during the initial `AttemptToConnect`, except @@ -512,7 +519,7 @@ TEST_P(WebRtcTest, CancelBeforeConnect) { .enable_cancellation_flag = true, }); - WebRtcSocketWrapper receiver_socket; + std::shared_ptr receiver_socket; const WebrtcPeerId self_id("self_id"); const std::string service_id("NearbySharing"); LocationHint location_hint; @@ -528,14 +535,15 @@ TEST_P(WebRtcTest, CancelBeforeConnect) { receiver->StartAcceptingConnections( service_id, self_id, location_hint, - [&receiver_socket, connected](const std::string& service_id, - WebRtcSocketWrapper wrapper) mutable { + [&receiver_socket, connected]( + const std::string& service_id, + std::shared_ptr wrapper) mutable { receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); + connected.Set(receiver_socket->IsValid()); }, params.non_cellular); - ErrorOr sender_socket_result = sender->Connect( + ErrorOr> sender_socket_result = sender->Connect( service_id, self_id, location_hint, &sender_flag, params.non_cellular); // Expect an invalid socket from stopping during the first attempt to connect, @@ -558,7 +566,7 @@ TEST_P(WebRtcTest, CancelDuringConnect_MultipleConnect) { .enable_cancellation_flag = true, }); - WebRtcSocketWrapper receiver_socket; + std::shared_ptr receiver_socket; const WebrtcPeerId self_id("self_id"); const std::string ns_service_id("NearbySharing"); const std::string ph_service_id("PhoneHub"); @@ -576,18 +584,19 @@ TEST_P(WebRtcTest, CancelDuringConnect_MultipleConnect) { receiver->StartAcceptingConnections( ns_service_id, self_id, location_hint, - [&receiver_socket, connected](const std::string& ns_service_id, - WebRtcSocketWrapper wrapper) mutable { + [&receiver_socket, connected]( + const std::string& ns_service_id, + std::shared_ptr wrapper) mutable { receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); + connected.Set(receiver_socket->IsValid()); }, params.non_cellular); // Simulate a successful connect for the endpoint of NearbySharing. - ErrorOr sender_socket_result = sender->Connect( + ErrorOr> sender_socket_result = sender->Connect( ns_service_id, self_id, location_hint, &flag, params.non_cellular); EXPECT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value().IsValid()); + EXPECT_TRUE(sender_socket_result.value()->IsValid()); // Calls `CancellationFlag::Cancel` during a call to `GetSignalingMessenger` // to simulate the cancellation occuring during an `AttemptToConnect` for the diff --git a/connections/implementation/p2p_cluster_pcp_handler.h b/connections/implementation/p2p_cluster_pcp_handler.h index a3ac0891..7dac0be2 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.h +++ b/connections/implementation/p2p_cluster_pcp_handler.h @@ -56,7 +56,6 @@ #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" #else #include "connections/implementation/mediums/webrtc.h" diff --git a/connections/implementation/webrtc_bwu_handler.cc b/connections/implementation/webrtc_bwu_handler.cc index 50a38814..5ec2c1c0 100644 --- a/connections/implementation/webrtc_bwu_handler.cc +++ b/connections/implementation/webrtc_bwu_handler.cc @@ -60,10 +60,10 @@ LocationHint BuildLocationHint(const std::string& location) { } // namespace WebrtcBwuHandler::WebrtcIncomingSocket::WebrtcIncomingSocket( - const std::string& name, mediums::WebRtcSocketWrapper socket) - : name_(name), socket_(socket) {} + const std::string& name, std::shared_ptr socket) + : name_(name), socket_(std::move(socket)) {} -void WebrtcBwuHandler::WebrtcIncomingSocket::Close() { socket_.Close(); } +void WebrtcBwuHandler::WebrtcIncomingSocket::Close() { socket_->Close(); } std::string WebrtcBwuHandler::WebrtcIncomingSocket::ToString() { return name_; } @@ -93,9 +93,10 @@ WebrtcBwuHandler::CreateUpgradedEndpointChannel( << peer_id.GetId() << ", location hint " << location_hint.location(); - ErrorOr socket_result = webrtc_.Connect( - service_id, peer_id, location_hint, - client->GetCancellationFlag(endpoint_id), client->GetWebRtcNonCellular()); + ErrorOr> socket_result = + webrtc_.Connect(service_id, peer_id, location_hint, + client->GetCancellationFlag(endpoint_id), + client->GetWebRtcNonCellular()); if (socket_result.has_error()) { LOG(ERROR) << "WebRtcBwuHandler failed to connect to remote peer (" << peer_id.GetId() << ") on endpoint " << endpoint_id @@ -111,7 +112,7 @@ WebrtcBwuHandler::CreateUpgradedEndpointChannel( auto channel = std::make_unique( service_id, /*channel_name=*/service_id, socket_result.value()); if (channel == nullptr) { - socket_result.value().Close(); + socket_result.value()->Close(); LOG(ERROR) << "WebRtcBwuHandler failed to create new EndpointChannel for " "outgoing socket, aborting upgrade."; return {Error( @@ -164,11 +165,11 @@ std::string WebrtcBwuHandler::HandleInitializeUpgradedMediumForEndpoint( // for this socket. void WebrtcBwuHandler::OnIncomingWebrtcConnection( ClientProxy* client, const std::string& upgrade_service_id, - mediums::WebRtcSocketWrapper socket) { + std::shared_ptr socket) { auto channel = std::make_unique( upgrade_service_id, /*channel_name=*/upgrade_service_id, socket); - auto webrtc_socket = - std::make_unique(upgrade_service_id, socket); + auto webrtc_socket = std::make_unique( + upgrade_service_id, std::move(socket)); std::unique_ptr connection( new IncomingSocketConnection{std::move(webrtc_socket), std::move(channel)}); diff --git a/connections/implementation/webrtc_bwu_handler.h b/connections/implementation/webrtc_bwu_handler.h index 5220ef18..c4918ad2 100644 --- a/connections/implementation/webrtc_bwu_handler.h +++ b/connections/implementation/webrtc_bwu_handler.h @@ -44,15 +44,15 @@ class WebrtcBwuHandler : public BaseBwuHandler { private: class WebrtcIncomingSocket : public BwuHandler::IncomingSocket { public: - explicit WebrtcIncomingSocket(const std::string& name, - mediums::WebRtcSocketWrapper socket); + explicit WebrtcIncomingSocket( + const std::string& name, std::shared_ptr socket); std::string ToString() override; void Close() override; private: std::string name_; - mediums::WebRtcSocketWrapper socket_; + std::shared_ptr socket_; }; // BwuHandler implementation: @@ -74,9 +74,9 @@ class WebrtcBwuHandler : public BaseBwuHandler { void HandleRevertInitiatorStateForService( const std::string& upgrade_service_id) final; - void OnIncomingWebrtcConnection(ClientProxy* client, - const std::string& upgrade_service_id, - mediums::WebRtcSocketWrapper socket); + void OnIncomingWebrtcConnection( + ClientProxy* client, const std::string& upgrade_service_id, + std::shared_ptr socket); Mediums& mediums_; mediums::WebRtc& webrtc_{mediums_.GetWebRtc()}; diff --git a/connections/implementation/webrtc_bwu_handler_stub.cc b/connections/implementation/webrtc_bwu_handler_stub.cc index 619b7647..d116d100 100644 --- a/connections/implementation/webrtc_bwu_handler_stub.cc +++ b/connections/implementation/webrtc_bwu_handler_stub.cc @@ -36,8 +36,8 @@ using ::location::nearby::proto::connections::OperationResultCode; } // namespace WebrtcBwuHandler::WebrtcIncomingSocket::WebrtcIncomingSocket( - const std::string& name, mediums::WebRtcSocketWrapper socket) - : name_(name), socket_(socket) {} + const std::string& name, std::shared_ptr socket) + : name_(name), socket_(std::move(socket)) {} void WebrtcBwuHandler::WebrtcIncomingSocket::Close() {} @@ -76,7 +76,7 @@ std::string WebrtcBwuHandler::HandleInitializeUpgradedMediumForEndpoint( // for this socket. void WebrtcBwuHandler::OnIncomingWebrtcConnection( ClientProxy* client, const std::string& upgrade_service_id, - mediums::WebRtcSocketWrapper socket) {} + std::shared_ptr socket) {} } // namespace connections } // namespace nearby diff --git a/connections/implementation/webrtc_bwu_handler_stub.h b/connections/implementation/webrtc_bwu_handler_stub.h index 6ee6635f..7c959cd9 100644 --- a/connections/implementation/webrtc_bwu_handler_stub.h +++ b/connections/implementation/webrtc_bwu_handler_stub.h @@ -23,11 +23,7 @@ #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel_manager.h" #include "connections/implementation/mediums/mediums.h" -#ifdef NO_WEBRTC -#include "connections/implementation/mediums/webrtc_socket_stub.h" -#else #include "connections/implementation/mediums/webrtc_socket.h" -#endif #include "internal/platform/expected.h" namespace nearby { @@ -44,15 +40,15 @@ class WebrtcBwuHandler : public BaseBwuHandler { private: class WebrtcIncomingSocket : public BwuHandler::IncomingSocket { public: - explicit WebrtcIncomingSocket(const std::string& name, - mediums::WebRtcSocketWrapper socket); + explicit WebrtcIncomingSocket( + const std::string& name, std::shared_ptr socket); std::string ToString() override; void Close() override; private: std::string name_; - mediums::WebRtcSocketWrapper socket_; + std::shared_ptr socket_; }; // BwuHandler implementation: @@ -74,9 +70,9 @@ class WebrtcBwuHandler : public BaseBwuHandler { void HandleRevertInitiatorStateForService( const std::string& upgrade_service_id) final; - void OnIncomingWebrtcConnection(ClientProxy* client, - const std::string& upgrade_service_id, - mediums::WebRtcSocketWrapper socket); + void OnIncomingWebrtcConnection( + ClientProxy* client, const std::string& upgrade_service_id, + std::shared_ptr socket); Mediums& mediums_; mediums::WebRtc& webrtc_{mediums_.GetWebRtc()}; diff --git a/connections/implementation/webrtc_endpoint_channel.cc b/connections/implementation/webrtc_endpoint_channel.cc index b22501bf..a95c4027 100644 --- a/connections/implementation/webrtc_endpoint_channel.cc +++ b/connections/implementation/webrtc_endpoint_channel.cc @@ -14,16 +14,21 @@ #include "connections/implementation/webrtc_endpoint_channel.h" +#include #include +#include + +#include "connections/implementation/base_endpoint_channel.h" +#include "connections/implementation/mediums/webrtc_socket.h" namespace nearby { namespace connections { WebRtcEndpointChannel::WebRtcEndpointChannel( const std::string& service_id, const std::string& channel_name, - mediums::WebRtcSocketWrapper socket) - : BaseEndpointChannel(service_id, channel_name, &socket.GetInputStream(), - &socket.GetOutputStream()), + std::shared_ptr socket) + : BaseEndpointChannel(service_id, channel_name, &socket->GetInputStream(), + &socket->GetOutputStream()), webrtc_socket_(std::move(socket)) {} location::nearby::proto::connections::Medium WebRtcEndpointChannel::GetMedium() @@ -31,7 +36,7 @@ location::nearby::proto::connections::Medium WebRtcEndpointChannel::GetMedium() return location::nearby::proto::connections::Medium::WEB_RTC; } -void WebRtcEndpointChannel::CloseImpl() { webrtc_socket_.Close(); } +void WebRtcEndpointChannel::CloseImpl() { webrtc_socket_->Close(); } } // namespace connections } // namespace nearby diff --git a/connections/implementation/webrtc_endpoint_channel.h b/connections/implementation/webrtc_endpoint_channel.h index ae0eb551..dd11bdf6 100644 --- a/connections/implementation/webrtc_endpoint_channel.h +++ b/connections/implementation/webrtc_endpoint_channel.h @@ -15,14 +15,11 @@ #ifndef CORE_INTERNAL_WEBRTC_ENDPOINT_CHANNEL_H_ #define CORE_INTERNAL_WEBRTC_ENDPOINT_CHANNEL_H_ +#include #include #include "connections/implementation/base_endpoint_channel.h" -#ifdef NO_WEBRTC -#include "connections/implementation/mediums/webrtc_socket_stub.h" -#else #include "connections/implementation/mediums/webrtc_socket.h" -#endif namespace nearby { namespace connections { @@ -31,14 +28,14 @@ class WebRtcEndpointChannel final : public BaseEndpointChannel { public: WebRtcEndpointChannel(const std::string& service_id, const std::string& channel_name, - mediums::WebRtcSocketWrapper webrtc_socket); + std::shared_ptr socket); location::nearby::proto::connections::Medium GetMedium() const override; private: void CloseImpl() override; - mediums::WebRtcSocketWrapper webrtc_socket_; + std::shared_ptr webrtc_socket_; }; } // namespace connections From 7d84d08619a9cf5db9abbf5bbeb4a297ef85e8a5 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 14 May 2026 15:19:58 -0700 Subject: [PATCH 092/151] Remove unused code. PiperOrigin-RevId: 915643059 --- internal/platform/ble.h | 11 --- internal/platform/ble_test.cc | 79 ------------------- .../apple/Tests/ble_gatt_client_test.mm | 13 --- .../implementation/apple/ble_gatt_client.h | 10 --- .../implementation/apple/ble_gatt_client.mm | 7 -- internal/platform/implementation/ble.h | 8 -- internal/platform/implementation/g3/ble.cc | 27 ------- internal/platform/implementation/g3/ble.h | 5 -- .../implementation/windows/ble_gatt_client.cc | 74 ----------------- .../implementation/windows/ble_gatt_client.h | 5 -- 10 files changed, 239 deletions(-) diff --git a/internal/platform/ble.h b/internal/platform/ble.h index 7aafbce6..6eef673c 100644 --- a/internal/platform/ble.h +++ b/internal/platform/ble.h @@ -295,17 +295,6 @@ class GattClient final { return impl_->WriteCharacteristic(characteristic, value, write_type); } - // TODO(qinwangz): We should not need `on_characteristic_changed_cb` when - // unsubscribing. - // NOLINTNEXTLINE(google3-legacy-absl-backports) - bool SetCharacteristicSubscription( - const api::ble::GattCharacteristic& characteristic, bool enable, - absl::AnyInvocable - on_characteristic_changed_cb) { - return impl_->SetCharacteristicSubscription( - characteristic, enable, std::move(on_characteristic_changed_cb)); - } - void Disconnect() { impl_->Disconnect(); } // Returns true if a client_gatt_connection is usable. If this method diff --git a/internal/platform/ble_test.cc b/internal/platform/ble_test.cc index 9b43629d..6c7ee843 100644 --- a/internal/platform/ble_test.cc +++ b/internal/platform/ble_test.cc @@ -55,7 +55,6 @@ using ::nearby::api::ble::BleAdvertisementData; using ::nearby::api::ble::GattCharacteristic; using ::nearby::api::ble::TxPowerLevel; using ::testing::Optional; -using ::testing::status::StatusIs; constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); constexpr absl::string_view kAdvertisementString = "\x0a\x0b\x0c\x0d"; @@ -771,83 +770,5 @@ TEST_F(BleMediumTest, GattClientOperatiosOnCharacteristic) { env_.Stop(); } -TEST_F(BleMediumTest, GattClientSubscribeNotificationGattServerCanNotify) { - env_.Start(); - BluetoothAdapter adapter_a; - BluetoothAdapter adapter_b; - BleMedium ble_a(adapter_a); - BleMedium ble_b(adapter_b); - Uuid service_uuid(1234, 5678); - Uuid characteristic_uuid(5678, 1234); - GattCharacteristic::Permission permissions = - GattCharacteristic::Permission::kRead; - GattCharacteristic::Property properties = - GattCharacteristic::Property::kRead | - GattCharacteristic::Property::kNotify; - - // Start GattServer - std::unique_ptr gatt_server = - ble_a.StartGattServer(/*ServerGattConnectionCallback=*/{}); - - ASSERT_NE(gatt_server, nullptr); - // Add characteristic and its value. - // NOLINTNEXTLINE(google3-legacy-absl-backports) - std::optional server_characteristic = - gatt_server->CreateCharacteristic(service_uuid, characteristic_uuid, - permissions, properties); - EXPECT_TRUE(gatt_server->UpdateCharacteristic(server_characteristic.value(), - ByteArray("any"))); - - // Start GattClient - MacAddress mac_address = adapter_a.GetAddress(); - std::unique_ptr gatt_client = ble_b.ConnectToGattServer( - BlePeripheral(ble_b, mac_address.address()), kTxPowerLevel, - /*ClientGattConnectionCallback=*/{}); - ASSERT_NE(gatt_client, nullptr); - - EXPECT_TRUE(gatt_client->DiscoverServiceAndCharacteristics( - service_uuid, {characteristic_uuid})); - - // Subscribes notification - EXPECT_TRUE(gatt_client->SetCharacteristicSubscription( - server_characteristic.value(), true, - [](absl::string_view value) { EXPECT_EQ(value, "hello"); })); - - // Sends notification - EXPECT_EQ(gatt_server->NotifyCharacteristicChanged( - server_characteristic.value(), false, ByteArray("hello")), - absl::OkStatus()); - - std::string notified_value; - CountDownLatch latch(1); - // Subscribes notification - EXPECT_TRUE(gatt_client->SetCharacteristicSubscription( - server_characteristic.value(), true, [&](absl::string_view value) { - notified_value = value; - latch.CountDown(); - })); - // Sends indication - EXPECT_EQ(gatt_server->NotifyCharacteristicChanged( - server_characteristic.value(), true, ByteArray("any")), - absl::OkStatus()); - latch.Await(); - EXPECT_EQ(notified_value, "any"); - - // Unsubscribes notification - EXPECT_TRUE(gatt_client->SetCharacteristicSubscription( - server_characteristic.value(), false, - [&](absl::string_view value) { GTEST_FAIL(); })); - EXPECT_THAT(gatt_server->NotifyCharacteristicChanged( - server_characteristic.value(), true, ByteArray("any")), - StatusIs(absl::StatusCode::kNotFound)); - - gatt_client->Disconnect(); - // Failed to subscribe characteristic notification as gatt is disconnected. - EXPECT_FALSE(gatt_client->SetCharacteristicSubscription( - server_characteristic.value(), true, [](absl::string_view value) {})); - gatt_server->Stop(); - env_.Stop(); -} - } // namespace } // namespace nearby diff --git a/internal/platform/implementation/apple/Tests/ble_gatt_client_test.mm b/internal/platform/implementation/apple/Tests/ble_gatt_client_test.mm index c5969c5f..ae1066a8 100644 --- a/internal/platform/implementation/apple/Tests/ble_gatt_client_test.mm +++ b/internal/platform/implementation/apple/Tests/ble_gatt_client_test.mm @@ -210,19 +210,6 @@ XCTAssertFalse(result); } -- (void)testSetCharacteristicSubscriptionReturnsFalse { - GNCBLEGATTCharacteristic *characteristic = - [[GNCBLEGATTCharacteristic alloc] initWithUUID:[CBUUID UUIDWithString:@"B2B4"] - serviceUUID:[CBUUID UUIDWithString:@"FEF3"] - permissions:CBAttributePermissionsReadable - properties:CBCharacteristicPropertyNotify]; - nearby::api::ble::GattCharacteristic cppCharacteristic = - nearby::apple::CPPGATTCharacteristicFromObjC(characteristic); - BOOL result = _gattClient->SetCharacteristicSubscription(cppCharacteristic, true, - [](absl::string_view value) {}); - XCTAssertFalse(result); -} - - (void)testDisconnectWhenFlagEnabled { nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( nearby::connections::config_package_nearby::nearby_connections_feature:: diff --git a/internal/platform/implementation/apple/ble_gatt_client.h b/internal/platform/implementation/apple/ble_gatt_client.h index f375586c..1be7ae1e 100644 --- a/internal/platform/implementation/apple/ble_gatt_client.h +++ b/internal/platform/implementation/apple/ble_gatt_client.h @@ -66,16 +66,6 @@ class GattClient : public api::ble::GattClient { bool WriteCharacteristic(const api::ble::GattCharacteristic &characteristic, absl::string_view value, api::ble::GattClient::WriteType type) override; - // Enable or disable notifications/indications for a given characteristic. - // - // Once notifications are enabled for a characteristic, on_characteristic_changed_cb will be - // triggered if the remote device indicates that the given characteristic has changed. - // - // Returns whether or not the subscription was successful. - bool SetCharacteristicSubscription( - const api::ble::GattCharacteristic &characteristic, bool enable, - absl::AnyInvocable on_characteristic_changed_cb) override; - // Disconnects an established connection, or cancels a connection attempt currently in progress. void Disconnect() override; diff --git a/internal/platform/implementation/apple/ble_gatt_client.mm b/internal/platform/implementation/apple/ble_gatt_client.mm index 655878cf..4b1a07f2 100644 --- a/internal/platform/implementation/apple/ble_gatt_client.mm +++ b/internal/platform/implementation/apple/ble_gatt_client.mm @@ -121,13 +121,6 @@ bool GattClient::WriteCharacteristic(const api::ble::GattCharacteristic &charact return false; } -// TODO(b/290385712): Implement. -bool GattClient::SetCharacteristicSubscription( - const api::ble::GattCharacteristic &characteristic, bool enable, - absl::AnyInvocable on_characteristic_changed_cb) { - return false; -} - void GattClient::Disconnect() { // There seems to be an issue between some iOS<>Android device pairs where the Android device will // not connect to the iOS device if the iOS device disconnects and then attempts to reconnect. diff --git a/internal/platform/implementation/ble.h b/internal/platform/implementation/ble.h index 00866e1e..beb7a13b 100644 --- a/internal/platform/implementation/ble.h +++ b/internal/platform/implementation/ble.h @@ -248,14 +248,6 @@ class GattClient { virtual bool WriteCharacteristic(const GattCharacteristic& characteristic, absl::string_view value, WriteType type) = 0; - // https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#setCharacteristicNotification(android.bluetooth.BluetoothGattCharacteristic,%20boolean) - // - // Enable or disable notifications/indications for a given characteristic. - virtual bool SetCharacteristicSubscription( - const GattCharacteristic& characteristic, bool enable, - absl::AnyInvocable - on_characteristic_changed_cb) = 0; - // https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#disconnect() virtual void Disconnect() = 0; }; diff --git a/internal/platform/implementation/g3/ble.cc b/internal/platform/implementation/g3/ble.cc index 9e1282b5..573d2cf1 100644 --- a/internal/platform/implementation/g3/ble.cc +++ b/internal/platform/implementation/g3/ble.cc @@ -679,33 +679,6 @@ bool BleMedium::GattClient::WriteCharacteristic( return status.ok(); } -bool BleMedium::GattClient::SetCharacteristicSubscription( - const api::ble::GattCharacteristic& characteristic, bool enable, - absl::AnyInvocable - on_characteristic_changed_cb) { - absl::MutexLock lock(mutex_); - if (!is_connection_alive_) { - return false; - } - Borrowed borrowed = gatt_server_.Borrow(); - if (!borrowed) { - return false; - } - BleMedium::GattServer* gatt_server = - static_cast(*borrowed); - LOG(INFO) << "G3 Ble SetCharacteristicSubscription, characteristic=(" - << characteristic.service_uuid.Get16BitAsString() << "," - << std::string(characteristic.uuid) << "), enable = " << enable; - if (enable) { - return gatt_server->AddCharacteristicSubscription( - peripheral_id_, characteristic, - std::move(on_characteristic_changed_cb)); - } else { - return gatt_server->RemoveCharacteristicSubscription(peripheral_id_, - characteristic); - } -} - void BleMedium::GattClient::Disconnect() { bool was_alive = is_connection_alive_.exchange(false); if (!was_alive) return; diff --git a/internal/platform/implementation/g3/ble.h b/internal/platform/implementation/g3/ble.h index 86c6daf8..e3eacca3 100644 --- a/internal/platform/implementation/g3/ble.h +++ b/internal/platform/implementation/g3/ble.h @@ -282,11 +282,6 @@ class BleMedium : public api::ble::BleMedium { absl::string_view value, api::ble::GattClient::WriteType write_type) override; - bool SetCharacteristicSubscription( - const api::ble::GattCharacteristic& characteristic, bool enable, - absl::AnyInvocable - on_characteristic_changed_cb) override; - void Disconnect() override; void OnServerDisconnected(); diff --git a/internal/platform/implementation/windows/ble_gatt_client.cc b/internal/platform/implementation/windows/ble_gatt_client.cc index 83ed7695..3089d819 100644 --- a/internal/platform/implementation/windows/ble_gatt_client.cc +++ b/internal/platform/implementation/windows/ble_gatt_client.cc @@ -431,80 +431,6 @@ bool BleGattClient::WriteCharacteristic( return false; } -bool BleGattClient::SetCharacteristicSubscription( - const api::ble::GattCharacteristic& characteristic, bool enable, - absl::AnyInvocable - on_characteristic_changed_cb) { - absl::MutexLock lock(mutex_); - VLOG(1) << __func__ << ": Started to set Characteristic Subscription."; - GattClientCharacteristicConfigurationDescriptorValue gcccd_value = - GattClientCharacteristicConfigurationDescriptorValue::None; - if ((characteristic.property & Property::kNotify) != Property::kNone) { - gcccd_value = GattClientCharacteristicConfigurationDescriptorValue::Notify; - } else if ((characteristic.property & Property::kIndicate) != - Property::kNone) { - gcccd_value = - GattClientCharacteristicConfigurationDescriptorValue::Indicate; - } else { - LOG(WARNING) << "Characeristic: " << std::string(characteristic.uuid) - << " supports neither notifications nor indications."; - return false; - } - - std::optional gatt_characteristic; - - gatt_characteristic = - native_characteristic_map_[characteristic].native_characteristic; - - if (!gatt_characteristic.has_value()) { - LOG(ERROR) << __func__ << ": Failed to get native GATT characteristic."; - return false; - } - - // Write characteristic configuration descriptor - if (!WriteCharacteristicConfigurationDescriptor( - gatt_characteristic.value(), - enable - ? gcccd_value - : GattClientCharacteristicConfigurationDescriptorValue::None)) { - return false; - } - - // Set value changed handler - try { - if (enable) { - native_characteristic_map_[characteristic].on_characteristic_changed_cb = - std::move(on_characteristic_changed_cb); - native_characteristic_map_[characteristic].notification_token = - gatt_characteristic->ValueChanged( - [&](GattCharacteristic const& native_characteristic, - GattValueChangedEventArgs args) { - BleGattClient::OnCharacteristicValueChanged(characteristic, - args); - }); - - if (!native_characteristic_map_[characteristic].notification_token) { - LOG(ERROR) << __func__ << ": Failed to add value change handler."; - return false; - } - } else if (native_characteristic_map_[characteristic].notification_token) { - gatt_characteristic->ValueChanged(std::exchange( - native_characteristic_map_[characteristic].notification_token, {})); - } - LOG(ERROR) << __func__ << ": Successfully set Characteristic Subscription."; - return true; - } catch (std::exception exception) { - LOG(ERROR) << __func__ << ": Failed to set Characteristic Subscription." - << exception.what(); - } catch (const winrt::hresult_error& error) { - LOG(ERROR) << __func__ - << ": Failed to set Characteristic Subscription." - " WinRT exception: " - << error.code() << ": " << winrt::to_string(error.message()); - } - return false; -} - void BleGattClient::Disconnect() { absl::MutexLock lock(mutex_); try { diff --git a/internal/platform/implementation/windows/ble_gatt_client.h b/internal/platform/implementation/windows/ble_gatt_client.h index 651001e1..958cc102 100644 --- a/internal/platform/implementation/windows/ble_gatt_client.h +++ b/internal/platform/implementation/windows/ble_gatt_client.h @@ -63,11 +63,6 @@ class BleGattClient : public api::ble::GattClient { api::ble::GattClient::WriteType write_type) override ABSL_LOCKS_EXCLUDED(mutex_); - bool SetCharacteristicSubscription( - const api::ble::GattCharacteristic& characteristic, bool enable, - absl::AnyInvocable - on_characteristic_changed_cb) override ABSL_LOCKS_EXCLUDED(mutex_); - void Disconnect() override ABSL_LOCKS_EXCLUDED(mutex_); private: From 6a70c3d49bc334bf0ba45ee348d67fcc69f53314 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 14 May 2026 15:20:31 -0700 Subject: [PATCH 093/151] Fix dangling string_view UAF. PiperOrigin-RevId: 915643410 --- sharing/nearby_sharing_service_impl.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index f125391c..615c1c87 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -2258,16 +2258,15 @@ void NearbySharingServiceImpl::OnIncomingAdvertisementDecoded( // data to lambda. GetCertificateManager()->GetDecryptedPublicCertificate( std::move(encrypted_metadata_key), - [this, endpoint_id, advertisement_copy = *advertisement, - placeholder_share_target_id]( + [this, endpoint_id = std::string(endpoint_id), + advertisement_copy = *advertisement, placeholder_share_target_id]( std::optional decrypted_public_certificate) { RunOnNearbySharingServiceThread( "incoming_decrypted_certificate", // capture endpoint_id string_view as a std::string to ensure the // data does not go out of scope. - [this, endpoint_id = std::string(endpoint_id), advertisement_copy, - placeholder_share_target_id, + [this, endpoint_id, advertisement_copy, placeholder_share_target_id, decrypted_public_certificate = std::move(decrypted_public_certificate)]() { OnIncomingDecryptedCertificate(endpoint_id, advertisement_copy, From 80d209c76b22448cfcf58043b9328da088eddb31 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 14 May 2026 18:09:55 -0700 Subject: [PATCH 094/151] Store backup source device type in SyncBinding. PiperOrigin-RevId: 915714878 --- sharing/nearby_sharing_service_impl.cc | 21 +++++++++++++++++++++ sharing/nearby_sharing_service_impl_test.cc | 2 ++ 2 files changed, 23 insertions(+) diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 615c1c87..0b22c96d 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -233,6 +233,25 @@ std::string SendSurfaceStateToString( } } +sync::SyncBinding::SourceDeviceType ShareTargetTypeToSourceDeviceType( + ShareTargetType share_target_type) { + switch (share_target_type) { + case ShareTargetType::kPhone: + return sync::SyncBinding::SOURCE_DEVICE_TYPE_PHONE; + case ShareTargetType::kTablet: + return sync::SyncBinding::SOURCE_DEVICE_TYPE_TABLET; + case ShareTargetType::kLaptop: + return sync::SyncBinding::SOURCE_DEVICE_TYPE_LAPTOP; + case ShareTargetType::kCar: + return sync::SyncBinding::SOURCE_DEVICE_TYPE_CAR; + case ShareTargetType::kFoldable: + return sync::SyncBinding::SOURCE_DEVICE_TYPE_FOLDABLE; + case ShareTargetType::kXR: + return sync::SyncBinding::SOURCE_DEVICE_TYPE_XR; + case ShareTargetType::kUnknown: + return sync::SyncBinding::SOURCE_DEVICE_TYPE_UNKNOWN; + } +} } // namespace NearbySharingServiceImpl::NearbySharingServiceImpl( @@ -2666,6 +2685,8 @@ void NearbySharingServiceImpl::OnPeerSyncBindingComplete( FilePath destination_path{settings_->GetCustomSavePath()}; destination_path.append(FilePath(session->share_target().device_name)); binding.set_destination_directory(destination_path.ToString()); + binding.set_source_device_type( + ShareTargetTypeToSourceDeviceType(session->share_target().type)); sync_manager_.AddSyncBinding(binding); session->UpdateTransferMetadata( TransferMetadataBuilder() diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index 46dfd81f..91ef7624 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -5097,6 +5097,8 @@ TEST_F(NearbySharingServiceImplTest, InitiatePairingSuccess) { expected_binding.set_source_name(kDeviceName); expected_binding.set_destination_directory( FilePath("Downloads").append(FilePath(kDeviceName)).ToString()); + expected_binding.set_source_device_type( + sync::SyncBinding::SOURCE_DEVICE_TYPE_PHONE); EXPECT_THAT(binding->sync_bindings(0), EqualsProto(expected_binding)); } From e2340027505c66c24db0bbb2e7955263caf94d1b Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Thu, 14 May 2026 18:11:32 -0700 Subject: [PATCH 095/151] Fixed a go/mobile_tsan error (data_race) found while running //third_party/nearby/internal/platform/implementation/apple/Tests:PlatformTest PiperOrigin-RevId: 915715369 --- .../apple/Mediums/BLE/GNCBLEGATTServer.m | 12 +- .../apple/Tests/GNCMultiThreadExecutorTest.mm | 2 +- .../Tests/GNCSingleThreadExecutorTest.mm | 16 +-- .../apple/Tests/GNCTimerTest.mm | 6 +- .../implementation/apple/Tests/UtilsTest.mm | 5 +- .../Tests/ble_l2cap_server_socket_test.mm | 6 +- .../apple/Tests/ble_medium_test.mm | 12 +- .../apple/Tests/ble_server_socket_test.mm | 6 +- .../implementation/apple/ble_medium.h | 9 +- .../implementation/apple/ble_medium.mm | 108 +++++++++++++----- .../platform/implementation/apple/utils.mm | 8 +- 11 files changed, 124 insertions(+), 66 deletions(-) diff --git a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.m b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.m index 1b9035ad..edf95082 100644 --- a/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.m +++ b/internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTServer.m @@ -64,6 +64,11 @@ static const int kMaxAdvertisementLengthOnIOS = 23; self = [super init]; if (self) { _queue = queue ?: dispatch_queue_create(kGNCBLEGATTServerQueueLabel, DISPATCH_QUEUE_SERIAL); + _services = [[NSMutableDictionary alloc] init]; + _pendingCharacteristics = [[NSMutableDictionary alloc] init]; + _characteristicValues = [[NSMutableDictionary alloc] init]; + _advertisementData = nil; + if (GNCFeatureFlags.sharedPeripheralManagerEnabled) { if (!peripheralManager) { // In shared mode, the peripheral manager must be injected. @@ -76,7 +81,7 @@ static const int kMaxAdvertisementLengthOnIOS = 23; // Legacy mode: Create a new manager if one isn't provided. if (!peripheralManager) { peripheralManager = [[CBPeripheralManager alloc] - initWithDelegate:self + initWithDelegate:nil queue:_queue options:@{CBPeripheralManagerOptionShowPowerAlertKey : @NO}]; } @@ -85,11 +90,6 @@ static const int kMaxAdvertisementLengthOnIOS = 23; // delegate. _peripheralManager.peripheralDelegate = self; } - - _services = [[NSMutableDictionary alloc] init]; - _pendingCharacteristics = [[NSMutableDictionary alloc] init]; - _characteristicValues = [[NSMutableDictionary alloc] init]; - _advertisementData = nil; } return self; } diff --git a/internal/platform/implementation/apple/Tests/GNCMultiThreadExecutorTest.mm b/internal/platform/implementation/apple/Tests/GNCMultiThreadExecutorTest.mm index 886ff646..2d794f65 100644 --- a/internal/platform/implementation/apple/Tests/GNCMultiThreadExecutorTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCMultiThreadExecutorTest.mm @@ -93,7 +93,7 @@ using MultiThreadExecutor = ::nearby::api::SubmittableExecutor; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_TARGET_QUEUE_DEFAULT, 0); XCTestExpectation *expectation = [self expectationWithDescription:@"finished"]; - const int kRunnableCount = 1000; + const int kRunnableCount = 100; for (int i = 0; i < kRunnableCount; i++) { executor->Execute([self]() { self.counter++; }); } diff --git a/internal/platform/implementation/apple/Tests/GNCSingleThreadExecutorTest.mm b/internal/platform/implementation/apple/Tests/GNCSingleThreadExecutorTest.mm index e5857cb8..8e5e1dbf 100644 --- a/internal/platform/implementation/apple/Tests/GNCSingleThreadExecutorTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCSingleThreadExecutorTest.mm @@ -76,20 +76,14 @@ using SingleThreadExecutor = ::nearby::api::SubmittableExecutor; // Tests that shutting down an existing task allows to complete. - (void)testShutdownToAllowExistingTaskComplete { std::unique_ptr executor([self executor]); - - dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_TARGET_QUEUE_DEFAULT, 0); XCTestExpectation *expectation = [self expectationWithDescription:@"finished"]; - - executor->Execute([self]() { self.counter++; }); - - executor->Shutdown(); - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), queue, ^{ - XCTAssertEqual(self.counter, 1); + executor->Execute([self, expectation]() { + self.counter++; [expectation fulfill]; }); - - [self waitForExpectationsWithTimeout:0.5 handler:nil]; + executor->Shutdown(); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + XCTAssertEqual(self.counter, 1); } @end diff --git a/internal/platform/implementation/apple/Tests/GNCTimerTest.mm b/internal/platform/implementation/apple/Tests/GNCTimerTest.mm index 269bdf0f..32c895f1 100644 --- a/internal/platform/implementation/apple/Tests/GNCTimerTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCTimerTest.mm @@ -65,7 +65,7 @@ auto timer = std::make_unique(); std::atomic fireCount = 0; - XCTAssertTrue(timer->Create(10, 10, [&]() { + XCTAssertTrue(timer->Create(100, 100, [&]() { if (fireCount.fetch_add(1) == 1) { dispatch_async(dispatch_get_main_queue(), ^{ [expectation fulfill]; @@ -73,9 +73,9 @@ } })); - [self waitForExpectationsWithTimeout:1.0 handler:nil]; + [self waitForExpectationsWithTimeout:2.0 handler:nil]; XCTAssertTrue(timer->Stop()); - XCTAssertEqual(fireCount.load(), 2); + XCTAssertGreaterThanOrEqual(fireCount.load(), 2); } - (void)testRestart { diff --git a/internal/platform/implementation/apple/Tests/UtilsTest.mm b/internal/platform/implementation/apple/Tests/UtilsTest.mm index cabf5d3d..5c513c1f 100644 --- a/internal/platform/implementation/apple/Tests/UtilsTest.mm +++ b/internal/platform/implementation/apple/Tests/UtilsTest.mm @@ -56,8 +56,9 @@ using ::nearby::ObjCStringFromCppString; - (void)testUUIDStringFromNSUUID { NSString *uuidString = @"E621E1F8-C36C-495A-93FC-0C247A3E6E5F"; NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:uuidString]; - std::string expectedCppString = [uuidString UTF8String]; - XCTAssertEqual(nearby::UUIDStringFromNSUUID(uuid), expectedCppString); + XCTAssert(nearby::UUIDStringFromNSUUID(uuid) == + std::string([uuidString UTF8String], + [uuidString lengthOfBytesUsingEncoding:NSUTF8StringEncoding])); } - (void)testBluetoothUUIDConversions { diff --git a/internal/platform/implementation/apple/Tests/ble_l2cap_server_socket_test.mm b/internal/platform/implementation/apple/Tests/ble_l2cap_server_socket_test.mm index 88b47282..2be79381 100644 --- a/internal/platform/implementation/apple/Tests/ble_l2cap_server_socket_test.mm +++ b/internal/platform/implementation/apple/Tests/ble_l2cap_server_socket_test.mm @@ -50,8 +50,9 @@ - (void)testBleL2capServerSocketAccept { XCTestExpectation *expectation = [self expectationWithDescription:@"accept"]; + nearby::apple::BleL2capServerSocket *serverSocket = _serverSocket.get(); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - std::unique_ptr clientSocket = _serverSocket->Accept(); + std::unique_ptr clientSocket = serverSocket->Accept(); XCTAssertNotEqual(clientSocket.get(), nullptr); [expectation fulfill]; }); @@ -76,8 +77,9 @@ - (void)testBleL2capServerSocketClose { XCTestExpectation *expectation = [self expectationWithDescription:@"close"]; + nearby::apple::BleL2capServerSocket *serverSocket = _serverSocket.get(); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - std::unique_ptr clientSocket = _serverSocket->Accept(); + std::unique_ptr clientSocket = serverSocket->Accept(); XCTAssertEqual(clientSocket.get(), nullptr); [expectation fulfill]; }); diff --git a/internal/platform/implementation/apple/Tests/ble_medium_test.mm b/internal/platform/implementation/apple/Tests/ble_medium_test.mm index 491ee93f..a8fb6199 100644 --- a/internal/platform/implementation/apple/Tests/ble_medium_test.mm +++ b/internal/platform/implementation/apple/Tests/ble_medium_test.mm @@ -776,18 +776,20 @@ static const char *const kTestServiceID = "TestServiceID"; NSDictionary *serviceData = @{[CBUUID UUIDWithString:kTestServiceUUIDString] : [NSData dataWithBytes:"test" length:4]}; - __block XCTestExpectation *expectation1 = [self expectationWithDescription:@"Callback 1"]; + XCTestExpectation *expectation1 = [self expectationWithDescription:@"Callback 1"]; XCTestExpectation *expectation2 = [self expectationWithDescription:@"Callback 2"]; expectation2.inverted = YES; // Should NOT be called. + auto callback1_fulfilled = std::make_shared>(false); + nearby::api::ble::BleMedium::ScanCallback callback = { .advertisement_found_cb = std::function( - ^(nearby::api::ble::BlePeripheral::UniqueId peripheral_id, - const nearby::api::ble::BleAdvertisementData &advertisement) { - if ([expectation1.description isEqualToString:@"Callback 1"]) { + [callback1_fulfilled, expectation1, expectation2]( + nearby::api::ble::BlePeripheral::UniqueId peripheral_id, + const nearby::api::ble::BleAdvertisementData &advertisement) { + if (!callback1_fulfilled->exchange(true)) { [expectation1 fulfill]; - expectation1 = nil; // Prevent double fulfillment } else { [expectation2 fulfill]; } diff --git a/internal/platform/implementation/apple/Tests/ble_server_socket_test.mm b/internal/platform/implementation/apple/Tests/ble_server_socket_test.mm index 1b887880..a9574f96 100644 --- a/internal/platform/implementation/apple/Tests/ble_server_socket_test.mm +++ b/internal/platform/implementation/apple/Tests/ble_server_socket_test.mm @@ -42,8 +42,9 @@ - (void)testBleServerSocketAccept { XCTestExpectation *expectation = [self expectationWithDescription:@"accept"]; + nearby::apple::BleServerSocket *serverSocket = _serverSocket.get(); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - std::unique_ptr clientSocket = _serverSocket->Accept(); + std::unique_ptr clientSocket = serverSocket->Accept(); XCTAssertNotEqual(clientSocket.get(), nullptr); [expectation fulfill]; }); @@ -57,8 +58,9 @@ - (void)testBleServerSocketClose { XCTestExpectation *expectation = [self expectationWithDescription:@"close"]; + nearby::apple::BleServerSocket *serverSocket = _serverSocket.get(); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - std::unique_ptr clientSocket = _serverSocket->Accept(); + std::unique_ptr clientSocket = serverSocket->Accept(); XCTAssertEqual(clientSocket.get(), nullptr); [expectation fulfill]; }); diff --git a/internal/platform/implementation/apple/ble_medium.h b/internal/platform/implementation/apple/ble_medium.h index 28438113..34695757 100644 --- a/internal/platform/implementation/apple/ble_medium.h +++ b/internal/platform/implementation/apple/ble_medium.h @@ -245,13 +245,16 @@ class BleMedium : public api::ble::BleMedium { GNSPeripheralServiceManager *socketPeripheralServiceManager_; GNSPeripheralManager *socketPeripheralManager_; - GNSCentralManager *socketCentralManager_; + + absl::Mutex scanning_mutex_; + GNSCentralManager *socketCentralManager_ ABSL_GUARDED_BY(scanning_mutex_); // Used for the blocking version of StartAdvertising and only has an advertisement found callback. - api::ble::BleMedium::ScanCallback scan_cb_; + std::shared_ptr scan_cb_ ABSL_GUARDED_BY(scanning_mutex_); // Used for the async version of StartAdvertising and has both an advertisement found and result // callback. - api::ble::BleMedium::ScanningCallback scanning_cb_; + std::shared_ptr scanning_cb_ + ABSL_GUARDED_BY(scanning_mutex_); // Used for the BleServerSocket. absl::Mutex server_socket_mutex_; diff --git a/internal/platform/implementation/apple/ble_medium.mm b/internal/platform/implementation/apple/ble_medium.mm index dcb1d19f..1120f8b6 100644 --- a/internal/platform/implementation/apple/ble_medium.mm +++ b/internal/platform/implementation/apple/ble_medium.mm @@ -173,11 +173,19 @@ void BleMedium::HandleAdvertisementFound(id peripheral, } #endif - if (scanning_cb_.advertisement_found_cb) { - scanning_cb_.advertisement_found_cb(unique_id, data); + std::shared_ptr scanning_cb; + std::shared_ptr scan_cb; + { + absl::MutexLock lock(&scanning_mutex_); + scanning_cb = scanning_cb_; + scan_cb = scan_cb_; } - if (scan_cb_.advertisement_found_cb) { - scan_cb_.advertisement_found_cb(unique_id, data); + + if (scanning_cb && scanning_cb->advertisement_found_cb) { + scanning_cb->advertisement_found_cb(unique_id, data); + } + if (scan_cb && scan_cb->advertisement_found_cb) { + scan_cb->advertisement_found_cb(unique_id, data); } } @@ -185,7 +193,17 @@ std::unique_ptr BleMedium::StartScanning( const Uuid &service_uuid, api::ble::TxPowerLevel tx_power_level, api::ble::BleMedium::ScanningCallback callback) { CBUUID *serviceUUID = CBUUID128FromCPP(service_uuid); - scanning_cb_ = std::move(callback); + + { + absl::MutexLock lock(&scanning_mutex_); + scanning_cb_ = std::make_shared(std::move(callback)); + + if (central_manager_factory_) { + socketCentralManager_ = central_manager_factory_(serviceUUID); + } else { + socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUID]; + } + } // Clear the map of discovered peripherals only when we are starting a new scan. If we cleared the // map every time we stopped a scan, we would not be able to connect to peripherals that we @@ -193,12 +211,10 @@ std::unique_ptr BleMedium::StartScanning( peripherals_.Clear(); ClearAdvertisementPacketsMap(); - if (central_manager_factory_) { - socketCentralManager_ = central_manager_factory_(serviceUUID); - } else { - socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUID]; + { + absl::MutexLock lock(&scanning_mutex_); + [socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUID ]]; } - [socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUID ]]; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); __block NSError *blockError = nil; @@ -211,8 +227,13 @@ std::unique_ptr BleMedium::StartScanning( } completionHandler:^(NSError *error) { blockError = error; - if (scanning_cb_.start_scanning_result) { - scanning_cb_.start_scanning_result( + std::shared_ptr scanning_cb; + { + absl::MutexLock lock(&scanning_mutex_); + scanning_cb = scanning_cb_; + } + if (scanning_cb && scanning_cb->start_scanning_result) { + scanning_cb->start_scanning_result( error == nil ? absl::OkStatus() : absl::InternalError(error.localizedDescription.UTF8String)); } @@ -222,8 +243,13 @@ std::unique_ptr BleMedium::StartScanning( dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, kApiTimeoutInSeconds * NSEC_PER_SEC); if (dispatch_semaphore_wait(semaphore, timeout) != 0) { GNCLoggerError(@"Start scanning operation timed out."); - if (scanning_cb_.start_scanning_result) { - scanning_cb_.start_scanning_result(absl::DeadlineExceededError("Start scanning timed out")); + std::shared_ptr scanning_cb; + { + absl::MutexLock lock(&scanning_mutex_); + scanning_cb = scanning_cb_; + } + if (scanning_cb && scanning_cb->start_scanning_result) { + scanning_cb->start_scanning_result(absl::DeadlineExceededError("Start scanning timed out")); } return nullptr; } @@ -243,7 +269,17 @@ std::unique_ptr BleMedium::StartScanning( bool BleMedium::StartScanning(const Uuid &service_uuid, api::ble::TxPowerLevel tx_power_level, api::ble::BleMedium::ScanCallback callback) { CBUUID *serviceUUID = CBUUID128FromCPP(service_uuid); - scan_cb_ = std::move(callback); + + { + absl::MutexLock lock(&scanning_mutex_); + scan_cb_ = std::make_shared(std::move(callback)); + + if (central_manager_factory_) { + socketCentralManager_ = central_manager_factory_(serviceUUID); + } else { + socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUID]; + } + } // Clear the map of discovered peripherals only when we are starting a new scan. If we cleared the // map every time we stopped a scan, we would not be able to connect to peripherals that we @@ -251,12 +287,10 @@ bool BleMedium::StartScanning(const Uuid &service_uuid, api::ble::TxPowerLevel t peripherals_.Clear(); ClearAdvertisementPacketsMap(); - if (central_manager_factory_) { - socketCentralManager_ = central_manager_factory_(serviceUUID); - } else { - socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUID]; + { + absl::MutexLock lock(&scanning_mutex_); + [socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUID ]]; } - [socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUID ]]; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); __block NSError *blockError = nil; @@ -294,7 +328,16 @@ bool BleMedium::StartMultipleServicesScanning(const std::vector &service_u [serviceUUIDs addObject:CBUUID128FromCPP(service_uuid)]; } - scan_cb_ = std::move(callback); + { + absl::MutexLock lock(&scanning_mutex_); + scan_cb_ = std::make_shared(std::move(callback)); + + if (central_manager_factory_) { + socketCentralManager_ = central_manager_factory_(serviceUUIDs[0]); + } else { + socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUIDs[0]]; + } + } // Clear the map of discovered peripherals only when we are starting a new scan. If we cleared the // map every time we stopped a scan, we would not be able to connect to peripherals that we @@ -302,12 +345,10 @@ bool BleMedium::StartMultipleServicesScanning(const std::vector &service_u peripherals_.Clear(); ClearAdvertisementPacketsMap(); - if (central_manager_factory_) { - socketCentralManager_ = central_manager_factory_(serviceUUIDs[0]); - } else { - socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUIDs[0]]; + { + absl::MutexLock lock(&scanning_mutex_); + [socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUIDs[0] ]]; } - [socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUIDs[0] ]]; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); __block NSError *blockError = nil; @@ -333,7 +374,12 @@ bool BleMedium::StartMultipleServicesScanning(const std::vector &service_u } bool BleMedium::StopScanning() { - [socketCentralManager_ stopNoScanMode]; + { + absl::MutexLock lock(&scanning_mutex_); + [socketCentralManager_ stopNoScanMode]; + scan_cb_ = nullptr; + scanning_cb_ = nullptr; + } dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); __block NSError *blockError = nil; @@ -694,8 +740,12 @@ std::unique_ptr BleMedium::Connect( return nullptr; } - GNSCentralPeerManager *updatedCentralPeerManager = - [socketCentralManager_ retrieveCentralPeerWithIdentifier:peripheral.identifier]; + GNSCentralPeerManager *updatedCentralPeerManager; + { + absl::MutexLock lock(&scanning_mutex_); + updatedCentralPeerManager = + [socketCentralManager_ retrieveCentralPeerWithIdentifier:peripheral.identifier]; + } if (!updatedCentralPeerManager) { return nullptr; } diff --git a/internal/platform/implementation/apple/utils.mm b/internal/platform/implementation/apple/utils.mm index 386e1036..e517310d 100644 --- a/internal/platform/implementation/apple/utils.mm +++ b/internal/platform/implementation/apple/utils.mm @@ -27,11 +27,15 @@ bool CppBoolFromObjCBool(BOOL b) { return b ? true : false; } char CharFromNSNumber(NSNumber* n) { return n.charValue; } NSString* ObjCStringFromCppString(absl::string_view s) { - return [NSString stringWithUTF8String:s.data()]; + return [[NSString alloc] initWithBytes:s.data() length:s.size() encoding:NSUTF8StringEncoding]; } std::string CppStringFromObjCString(NSString* s) { - return std::string([s UTF8String], [s lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + if (!s) return std::string(); + const char* cstr = [s UTF8String]; + if (!cstr) return std::string(); + NSUInteger len = [s lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + return std::string(cstr, len); } NSData* NSDataFromByteArray(ByteArray byteArray) { From 2cec4aaadb3992ed7427a132646c99cfc8a07529 Mon Sep 17 00:00:00 2001 From: hai007 Date: Sat, 16 May 2026 05:14:27 -0700 Subject: [PATCH 096/151] Automated Code Change PiperOrigin-RevId: 916435607 --- internal/platform/BUILD | 2 +- internal/platform/tachyon_express_signaling_messenger.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/platform/BUILD b/internal/platform/BUILD index d077fda5..c0531d13 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -305,9 +305,9 @@ cc_library( "//internal/proto:tachyon_cc_proto", "//internal/rpc:utils", "//location/nearby/sharing/lib/account:account_manager", + "//third_party/gloop/util/random:mt_random", "//third_party/grpc:gpr", "//third_party/grpc:grpc++", - "//util/random:mt_random", "//util/random:util", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/functional:any_invocable", diff --git a/internal/platform/tachyon_express_signaling_messenger.cc b/internal/platform/tachyon_express_signaling_messenger.cc index 6b07190a..e430f7ff 100644 --- a/internal/platform/tachyon_express_signaling_messenger.cc +++ b/internal/platform/tachyon_express_signaling_messenger.cc @@ -25,6 +25,7 @@ #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "absl/time/time.h" +#include "third_party/gloop/util/random/mt_random.h" #include "third_party/grpc/include/grpc/support/time.h" #include "third_party/grpc/include/grpcpp/channel.h" #include "third_party/grpc/include/grpcpp/client_context.h" @@ -42,7 +43,6 @@ #include "internal/proto/tachyon_common.proto.h" #include "internal/proto/tachyon_enums.proto.h" #include "internal/rpc/utils.h" -#include "util/random/mt_random.h" #include "util/random/util.h" namespace nearby { From a9a0a981e31903e0910128b9acbba59e4bd7f559 Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 19 May 2026 08:35:51 -0700 Subject: [PATCH 097/151] ...text exposed to open source public git repo... PiperOrigin-RevId: 917853144 --- proto/sharing_enums.proto | 2 ++ sharing/proto/wire_format.proto | 1 + 2 files changed, 3 insertions(+) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index 7adafdd3..e8c3b121 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -845,6 +845,8 @@ enum SharingUseCase { USE_CASE_NEARBY_SHARE_WITH_QR_CODE = 7 [deprecated = true]; // The user was redirected from Bluetooth sharing UI to Nearby Share USE_CASE_REDIRECTED_FROM_BLUETOOTH_SHARE = 8; + USE_CASE_TAP_TO_SHARE = 9; + USE_CASE_TAP_TO_SHARE_FROM_TTX_FLOW = 10; } // Used only for Windows App now. diff --git a/sharing/proto/wire_format.proto b/sharing/proto/wire_format.proto index b0db8294..a8d7396f 100644 --- a/sharing/proto/wire_format.proto +++ b/sharing/proto/wire_format.proto @@ -220,6 +220,7 @@ message IntroductionFrame { NEARBY_SHARE = 1; REMOTE_COPY = 2; TAP_TO_SHARE = 9; + TAP_TO_SHARE_FROM_TTX_FLOW = 10; } repeated FileMetadata file_metadata = 1; From df7666758f5e95864fa8b2f71869522910a99b0d Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 19 May 2026 10:36:15 -0700 Subject: [PATCH 098/151] Remove use of deprecated absl::optional. PiperOrigin-RevId: 917909400 --- internal/base/BUILD | 2 -- internal/base/bluetooth_address.cc | 15 +++++++------ internal/platform/BUILD | 1 - internal/platform/awdl.h | 4 ++-- internal/platform/ble.h | 7 +++--- internal/platform/implementation/BUILD | 1 - internal/platform/implementation/ble.h | 19 ++++++++-------- .../platform/implementation/wifi_direct.h | 4 ++-- .../platform/implementation/windows/BUILD | 1 - .../implementation/windows/ble_gatt_client.cc | 22 +++++++++---------- .../implementation/windows/ble_gatt_client.h | 8 ++----- .../implementation/windows/ble_gatt_server.cc | 5 ++--- .../implementation/windows/ble_gatt_server.h | 4 ++-- internal/platform/wifi_direct.h | 5 ++--- internal/platform/wifi_lan.h | 4 ++-- sharing/BUILD | 1 - .../nearby_connections_manager_impl_test.cc | 5 ++--- 17 files changed, 46 insertions(+), 62 deletions(-) diff --git a/internal/base/BUILD b/internal/base/BUILD index 6fc220dc..771eeecc 100644 --- a/internal/base/BUILD +++ b/internal/base/BUILD @@ -50,8 +50,6 @@ cc_library( ], deps = [ "@com_google_absl//absl/strings", - "@com_google_absl//absl/strings:str_format", - "@com_google_absl//absl/types:optional", "@com_google_absl//absl/types:span", ], ) diff --git a/internal/base/bluetooth_address.cc b/internal/base/bluetooth_address.cc index ac1de37d..913a863d 100644 --- a/internal/base/bluetooth_address.cc +++ b/internal/base/bluetooth_address.cc @@ -15,18 +15,19 @@ #include "internal/base/bluetooth_address.h" #include +#include +#include +#include #include "absl/strings/string_view.h" -#include "absl/types/optional.h" +#include "absl/types/span.h" namespace nearby { namespace device { namespace { template -// Note that some of the methods return absl::optional instead -// of std::optional, because iOS platform is still in C++14. -absl::optional CharToDigit(CHAR c) { +std::optional CharToDigit(CHAR c) { static_assert(1 <= BASE && BASE <= 36, "BASE needs to be in [1, 36]"); if (c >= '0' && c < '0' + std::min(BASE, 10)) return c - '0'; @@ -34,7 +35,7 @@ absl::optional CharToDigit(CHAR c) { if (c >= 'A' && c < 'A' + BASE - 10) return c - 'A' + 10; - return absl::nullopt; + return std::nullopt; } template @@ -43,9 +44,9 @@ static bool HexStringToByteContainer(absl::string_view input, OutIter output) { if (count == 0 || (count % 2) != 0) return false; for (uintptr_t i = 0; i < count / 2; ++i) { // most significant 4 bits - absl::optional msb = CharToDigit<16>(input[i * 2]); + std::optional msb = CharToDigit<16>(input[i * 2]); // least significant 4 bits - absl::optional lsb = CharToDigit<16>(input[i * 2 + 1]); + std::optional lsb = CharToDigit<16>(input[i * 2 + 1]); if (!msb.has_value() || !lsb.has_value()) { return false; } diff --git a/internal/platform/BUILD b/internal/platform/BUILD index c0531d13..677206a7 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -374,7 +374,6 @@ cc_library( "@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/awdl.h b/internal/platform/awdl.h index 66dc63f4..7ff1d36a 100644 --- a/internal/platform/awdl.h +++ b/internal/platform/awdl.h @@ -16,6 +16,7 @@ #define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_AWDL_H_ #include #include +#include #include #include @@ -23,7 +24,6 @@ #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" #include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" @@ -261,7 +261,7 @@ class AwdlMedium { } // Returns the port range as a pair of min and max port. - absl::optional> GetDynamicPortRange() { + std::optional> GetDynamicPortRange() { return impl_->GetDynamicPortRange(); } diff --git a/internal/platform/ble.h b/internal/platform/ble.h index 6eef673c..4117ea9c 100644 --- a/internal/platform/ble.h +++ b/internal/platform/ble.h @@ -27,7 +27,6 @@ #include "absl/strings/escaping.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" -#include "absl/types/optional.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" @@ -223,7 +222,7 @@ class GattServer final { ~GattServer() { Stop(); } // NOLINTNEXTLINE(google3-legacy-absl-backports) - absl::optional CreateCharacteristic( + std::optional CreateCharacteristic( const Uuid& service_uuid, const Uuid& characteristic_uuid, const api::ble::GattCharacteristic::Permission permission, const api::ble::GattCharacteristic::Property property) { @@ -277,13 +276,13 @@ class GattClient final { } // NOLINTNEXTLINE(google3-legacy-absl-backports) - absl::optional GetCharacteristic( + std::optional GetCharacteristic( const Uuid& service_uuid, const Uuid& characteristic_uuid) { return impl_->GetCharacteristic(service_uuid, characteristic_uuid); } // NOLINTNEXTLINE(google3-legacy-absl-backports) - absl::optional ReadCharacteristic( + std::optional ReadCharacteristic( const api::ble::GattCharacteristic& characteristic) { return impl_->ReadCharacteristic(characteristic); } diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 69254c03..c122ef11 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -133,7 +133,6 @@ cc_library( "@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/ble.h b/internal/platform/implementation/ble.h index beb7a13b..d2f31276 100644 --- a/internal/platform/implementation/ble.h +++ b/internal/platform/implementation/ble.h @@ -29,7 +29,6 @@ #include "absl/status/statusor.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" -#include "absl/types/optional.h" #include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" @@ -155,26 +154,26 @@ struct GattCharacteristic { Property property; // overloading operator for enum class Permission and Property - friend inline Permission operator|(Permission a, Permission b) { + friend Permission operator|(Permission a, Permission b) { return static_cast(static_cast(a) | static_cast(b)); } - friend inline Permission operator&(Permission a, Permission b) { + friend Permission operator&(Permission a, Permission b) { return static_cast(static_cast(a) & static_cast(b)); } - friend inline Permission& operator|=(Permission& a, Permission b) { + friend Permission& operator|=(Permission& a, Permission b) { a = a | b; return a; } - friend inline Property operator|(Property a, Property b) { + friend Property operator|(Property a, Property b) { return static_cast(static_cast(a) | static_cast(b)); } - friend inline Property operator&(Property a, Property b) { + friend Property operator&(Property a, Property b) { return static_cast(static_cast(a) & static_cast(b)); } - friend inline Property& operator|=(Property& a, Property b) { + friend Property& operator|=(Property& a, Property b) { a = a | b; return a; } @@ -231,13 +230,13 @@ class GattClient { // It is okay for duplicate services to exist, as long as the specified // characteristic UUID is unique among all services of the same UUID. // NOLINTNEXTLINE(google3-legacy-absl-backports) - virtual absl::optional GetCharacteristic( + virtual std::optional GetCharacteristic( const Uuid& service_uuid, const Uuid& characteristic_uuid) = 0; // https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#readCharacteristic(android.bluetooth.BluetoothGattCharacteristic) // https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html#getValue() // NOLINTNEXTLINE(google3-legacy-absl-backports) - virtual absl::optional ReadCharacteristic( + virtual std::optional ReadCharacteristic( const GattCharacteristic& characteristic) = 0; // https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html#setValue(byte[]) @@ -273,7 +272,7 @@ class GattServer { // more information about this descriptor, please go to: // https://www.bluetooth.com/specifications/Gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.Gatt.client_characteristic_configuration.xml // NOLINTNEXTLINE(google3-legacy-absl-backports) - virtual absl::optional CreateCharacteristic( + virtual std::optional CreateCharacteristic( const Uuid& service_uuid, const Uuid& characteristic_uuid, GattCharacteristic::Permission permission, GattCharacteristic::Property property) = 0; diff --git a/internal/platform/implementation/wifi_direct.h b/internal/platform/implementation/wifi_direct.h index adfcf55f..6b6112bc 100644 --- a/internal/platform/implementation/wifi_direct.h +++ b/internal/platform/implementation/wifi_direct.h @@ -17,12 +17,12 @@ #include #include +#include #include #include #include #include "absl/strings/string_view.h" -#include "absl/types/optional.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" #include "internal/platform/input_stream.h" @@ -121,7 +121,7 @@ class WifiDirectMedium { virtual bool DisconnectWifiDirect() = 0; // Returns the port range as a pair of min and max port. - virtual absl::optional> + virtual std::optional> GetDynamicPortRange() = 0; // Returns the supported WifiDirect auth types. diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index b7e93a57..90b7528c 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -380,7 +380,6 @@ cc_library( "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", - "@com_google_absl//absl/types:optional", "@com_google_absl//absl/types:span", "@com_google_protobuf//:protobuf", "@com_google_protobuf//json", diff --git a/internal/platform/implementation/windows/ble_gatt_client.cc b/internal/platform/implementation/windows/ble_gatt_client.cc index 3089d819..78244f1b 100644 --- a/internal/platform/implementation/windows/ble_gatt_client.cc +++ b/internal/platform/implementation/windows/ble_gatt_client.cc @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -30,7 +29,6 @@ #include "absl/strings/str_join.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" -#include "absl/types/optional.h" #include "internal/platform/implementation/ble.h" #include "internal/platform/implementation/windows/bluetooth_adapter.h" #include "internal/platform/implementation/windows/utils.h" @@ -261,7 +259,7 @@ bool BleGattClient::DiscoverServiceAndCharacteristics( return false; } -absl::optional BleGattClient::GetCharacteristic( +std::optional BleGattClient::GetCharacteristic( const Uuid& service_uuid, const Uuid& characteristic_uuid) { absl::MutexLock lock(mutex_); VLOG(1) << __func__ << ": Stared to get characteristic UUID=" @@ -273,7 +271,7 @@ absl::optional BleGattClient::GetCharacteristic( if (!gatt_characteristic.has_value()) { LOG(ERROR) << __func__ << ": Failed to get native GATT characteristic."; - return absl::nullopt; + return std::nullopt; } api::ble::GattCharacteristic result; @@ -323,10 +321,10 @@ absl::optional BleGattClient::GetCharacteristic( << error.code() << ": " << winrt::to_string(error.message()); } - return absl::nullopt; + return std::nullopt; } -absl::optional BleGattClient::ReadCharacteristic( +std::optional BleGattClient::ReadCharacteristic( const api::ble::GattCharacteristic& characteristic) { absl::MutexLock lock(mutex_); VLOG(1) << __func__ @@ -338,7 +336,7 @@ absl::optional BleGattClient::ReadCharacteristic( if (!gatt_characteristic.has_value()) { LOG(ERROR) << __func__ << ": Failed to get native GATT characteristic."; - return absl::nullopt; + return std::nullopt; } GattReadResult result = @@ -347,7 +345,7 @@ absl::optional BleGattClient::ReadCharacteristic( LOG(ERROR) << __func__ << ": Failed to read GATT characteristic with error: " << GattCommunicationStatusToString(result.Status()); - return absl::nullopt; + return std::nullopt; } IBuffer buffer = result.Value(); @@ -377,7 +375,7 @@ absl::optional BleGattClient::ReadCharacteristic( << error.code() << ": " << winrt::to_string(error.message()); } - return absl::nullopt; + return std::nullopt; } bool BleGattClient::WriteCharacteristic( @@ -459,12 +457,12 @@ std::optional BleGattClient::GetNativeCharacteristic( try { if (ble_device_ == nullptr) { LOG(ERROR) << __func__ << ": BLE device is disconnected."; - return absl::nullopt; + return std::nullopt; } if (gatt_devices_services_result_ == nullptr) { LOG(ERROR) << __func__ << ": No available GATT services."; - return absl::nullopt; + return std::nullopt; } for (const auto& service : gatt_devices_services_result_.Services()) { @@ -505,7 +503,7 @@ std::optional BleGattClient::GetNativeCharacteristic( << error.code() << ": " << winrt::to_string(error.message()); } - return absl::nullopt; + return std::nullopt; } bool BleGattClient::WriteCharacteristicConfigurationDescriptor( diff --git a/internal/platform/implementation/windows/ble_gatt_client.h b/internal/platform/implementation/windows/ble_gatt_client.h index 958cc102..2f14eca1 100644 --- a/internal/platform/implementation/windows/ble_gatt_client.h +++ b/internal/platform/implementation/windows/ble_gatt_client.h @@ -17,8 +17,6 @@ #include -#include -#include #include #include #include @@ -28,8 +26,6 @@ #include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" -#include "absl/types/optional.h" -#include "internal/platform/byte_array.h" #include "internal/platform/implementation/ble.h" #include "internal/platform/uuid.h" #include "winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h" @@ -50,11 +46,11 @@ class BleGattClient : public api::ble::GattClient { const std::vector& characteristic_uuids) override ABSL_LOCKS_EXCLUDED(mutex_); - absl::optional GetCharacteristic( + std::optional GetCharacteristic( const Uuid& service_uuid, const Uuid& characteristic_uuid) override ABSL_LOCKS_EXCLUDED(mutex_); - absl::optional ReadCharacteristic( + std::optional ReadCharacteristic( const api::ble::GattCharacteristic& characteristic) override ABSL_LOCKS_EXCLUDED(mutex_); diff --git a/internal/platform/implementation/windows/ble_gatt_server.cc b/internal/platform/implementation/windows/ble_gatt_server.cc index d3c2a939..cbb540a7 100644 --- a/internal/platform/implementation/windows/ble_gatt_server.cc +++ b/internal/platform/implementation/windows/ble_gatt_server.cc @@ -31,7 +31,6 @@ #include "absl/synchronization/mutex.h" #include "absl/time/clock.h" #include "absl/time/time.h" -#include "absl/types/optional.h" #include "internal/platform/byte_array.h" #include "internal/platform/implementation/ble.h" #include "internal/platform/implementation/bluetooth_adapter.h" @@ -114,7 +113,7 @@ BleGattServer::BleGattServer(api::BluetoothAdapter* adapter, DCHECK(adapter_ != nullptr); } -absl::optional +std::optional BleGattServer::CreateCharacteristic( const Uuid& service_uuid, const Uuid& characteristic_uuid, api::ble::GattCharacteristic::Permission permission, @@ -126,7 +125,7 @@ BleGattServer::CreateCharacteristic( if (!service_uuid_.IsEmpty() && service_uuid_ != service_uuid) { LOG(ERROR) << __func__ << ": Only support one GATT service for now."; - return absl::nullopt; + return std::nullopt; } service_uuid_ = service_uuid; diff --git a/internal/platform/implementation/windows/ble_gatt_server.h b/internal/platform/implementation/windows/ble_gatt_server.h index 78ed86b1..52832a9e 100644 --- a/internal/platform/implementation/windows/ble_gatt_server.h +++ b/internal/platform/implementation/windows/ble_gatt_server.h @@ -18,6 +18,7 @@ #include #include +#include #include #include "absl/base/thread_annotations.h" @@ -27,7 +28,6 @@ #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "absl/synchronization/notification.h" -#include "absl/types/optional.h" #include "internal/platform/byte_array.h" #include "internal/platform/implementation/ble.h" #include "internal/platform/implementation/bluetooth_adapter.h" @@ -47,7 +47,7 @@ class BleGattServer : public api::ble::GattServer { BleGattServer(api::BluetoothAdapter* adapter, api::ble::ServerGattConnectionCallback callback); ~BleGattServer() override = default; - absl::optional CreateCharacteristic( + std::optional CreateCharacteristic( const Uuid& service_uuid, const Uuid& characteristic_uuid, api::ble::GattCharacteristic::Permission permission, api::ble::GattCharacteristic::Property property) override diff --git a/internal/platform/wifi_direct.h b/internal/platform/wifi_direct.h index f78339e4..a8296da0 100644 --- a/internal/platform/wifi_direct.h +++ b/internal/platform/wifi_direct.h @@ -17,13 +17,12 @@ #include #include -#include +#include #include #include #include "absl/base/thread_annotations.h" #include "absl/strings/string_view.h" -#include "absl/types/optional.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "internal/flags/nearby_flags.h" #include "internal/platform/cancellation_flag.h" @@ -178,7 +177,7 @@ class WifiDirectMedium { } // Returns the port range as a pair of min and max port. - absl::optional> GetDynamicPortRange() { + std::optional> GetDynamicPortRange() { return impl_->GetDynamicPortRange(); } diff --git a/internal/platform/wifi_lan.h b/internal/platform/wifi_lan.h index e46a39f6..2f9fc2ed 100644 --- a/internal/platform/wifi_lan.h +++ b/internal/platform/wifi_lan.h @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -24,7 +25,6 @@ #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" #include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" @@ -254,7 +254,7 @@ class WifiLanMedium { } // Returns the port range as a pair of min and max port. - absl::optional> GetDynamicPortRange() { + std::optional> GetDynamicPortRange() { return impl_->GetDynamicPortRange(); } diff --git a/sharing/BUILD b/sharing/BUILD index eb7cee28..674ab9f6 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -633,7 +633,6 @@ cc_test( "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", - "@com_google_absl//absl/types:optional", "@com_google_absl//absl/types:span", "@com_google_googletest//:gtest_main", ], diff --git a/sharing/nearby_connections_manager_impl_test.cc b/sharing/nearby_connections_manager_impl_test.cc index 2e46ec1f..f3c32490 100644 --- a/sharing/nearby_connections_manager_impl_test.cc +++ b/sharing/nearby_connections_manager_impl_test.cc @@ -33,7 +33,6 @@ #include "absl/strings/string_view.h" #include "absl/synchronization/notification.h" #include "absl/time/time.h" -#include "absl/types/optional.h" #include "absl/types/span.h" #include "internal/base/file_path.h" #include "internal/base/files.h" @@ -1037,7 +1036,7 @@ TEST_F(NearbyConnectionsManagerImplTest, ConnectClosedByRemote) { [&]() { close_notification.Notify(); }); Sync(); absl::Notification read_notification; - nearby_connection->Read([&](absl::optional> bytes) { + nearby_connection->Read([&](std::optional> bytes) { EXPECT_FALSE(bytes); read_notification.Notify(); }); @@ -1071,7 +1070,7 @@ TEST_F(NearbyConnectionsManagerImplTest, ConnectClosedByClient) { [&]() { close_notification.Notify(); }); Sync(); absl::Notification read_notification; - nearby_connection->Read([&](absl::optional> bytes) { + nearby_connection->Read([&](std::optional> bytes) { EXPECT_FALSE(bytes); read_notification.Notify(); }); From 269af7126e05d61ec7fd82578bec4dfcf960a4c8 Mon Sep 17 00:00:00 2001 From: Nick Bourdakos Date: Tue, 19 May 2026 10:52:35 -0700 Subject: [PATCH 099/151] Internal PiperOrigin-RevId: 917918107 --- BUILD.bazel | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 BUILD.bazel diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 00000000..82473d02 --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,29 @@ +# Copyright 2026 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. + +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +bool_flag( + name = "enable_webrtc", + build_setting_default = False, +) + +config_setting( + name = "webrtc_enabled", + flag_values = {":enable_webrtc": "True"}, +) From 2a09838b6192e2ffb709ce278f80f3f0ab70d37e Mon Sep 17 00:00:00 2001 From: Nick Bourdakos Date: Tue, 19 May 2026 12:45:45 -0700 Subject: [PATCH 100/151] Remove the need for WebRtc stub PiperOrigin-RevId: 917974575 --- connections/implementation/BUILD | 1 + connections/implementation/mediums/BUILD | 40 +-- connections/implementation/mediums/mediums.cc | 15 +- connections/implementation/mediums/mediums.h | 10 +- connections/implementation/mediums/webrtc.h | 228 ++-------------- .../implementation/mediums/webrtc/BUILD | 84 ++++-- .../{webrtc.cc => webrtc/webrtc_impl.cc} | 96 +++---- .../mediums/webrtc/webrtc_impl.h | 254 ++++++++++++++++++ .../webrtc_impl_test.cc} | 44 +-- .../implementation/mediums/webrtc_stub.cc | 67 ----- .../implementation/mediums/webrtc_stub.h | 86 ------ .../implementation/p2p_cluster_pcp_handler.h | 4 - 12 files changed, 456 insertions(+), 473 deletions(-) rename connections/implementation/mediums/{webrtc.cc => webrtc/webrtc_impl.cc} (89%) create mode 100644 connections/implementation/mediums/webrtc/webrtc_impl.h rename connections/implementation/mediums/{webrtc_test.cc => webrtc/webrtc_impl_test.cc} (96%) delete mode 100644 connections/implementation/mediums/webrtc_stub.cc delete mode 100644 connections/implementation/mediums/webrtc_stub.h diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index dea9acf3..a1912375 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -155,6 +155,7 @@ cc_library( "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums", "//connections/implementation/mediums:utils", + "//connections/implementation/mediums:webrtc", "//connections/implementation/mediums:webrtc_peer_id", "//connections/implementation/mediums:webrtc_socket", "//connections/implementation/mediums/advertisements:dct_advertisement", diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index e215226d..d5c8189f 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -25,8 +25,6 @@ cc_library( "bluetooth_classic.cc", "bluetooth_radio.cc", "mediums.cc", - "webrtc.cc", - "webrtc_stub.cc", "wifi_direct.cc", "wifi_hotspot.cc", "wifi_lan.cc", @@ -37,21 +35,22 @@ cc_library( "bluetooth_classic.h", "bluetooth_radio.h", "mediums.h", - "webrtc.h", - "webrtc_stub.h", "wifi.h", "wifi_direct.h", "wifi_hotspot.h", "wifi_lan.h", ], copts = ["-DNO_WEBRTC"], + local_defines = select({ + "//:webrtc_enabled": [], + "//conditions:default": ["NO_WEBRTC"], + }), visibility = [ "//connections/implementation:__subpackages__", ], deps = [ ":utils", - ":webrtc_peer_id", - ":webrtc_socket", + ":webrtc", "//connections:core_types", "//connections/implementation:types", "//connections/implementation/flags:connections_flags", @@ -59,8 +58,6 @@ cc_library( "//connections/implementation/mediums/ble:ble_advertisement_header", "//connections/implementation/mediums/ble:ble_socket", "//connections/implementation/mediums/ble:bloom_filter", - "//connections/implementation/mediums/webrtc", - "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/flags:nearby_flags", "//internal/platform:base", "//internal/platform:cancellation_flag", @@ -72,21 +69,22 @@ cc_library( "//internal/platform/flags:platform_flags", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", - "//proto/mediums:web_rtc_signaling_frames_cc_proto", - # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep - # "//third_party/webrtc/files/stable/webrtc/api:jsep", "@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", "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/functional:bind_front", "@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", - ], + ] + select({ + "//:webrtc_enabled": [ + "//connections/implementation/mediums/webrtc:webrtc_impl", + ], + "//conditions:default": [], + }), ) cc_library( @@ -144,6 +142,20 @@ cc_library( ], ) +cc_library( + name = "webrtc", + hdrs = ["webrtc.h"], + visibility = ["//connections/implementation:__subpackages__"], + deps = [ + ":webrtc_peer_id", + ":webrtc_socket", + "//connections/implementation/proto:offline_wire_formats_cc_proto", + "//internal/platform:base", + "//internal/platform:cancellation_flag", + "@com_google_absl//absl/functional:any_invocable", + ], +) + cc_test( name = "core_internal_mediums_test", size = "small", @@ -191,7 +203,6 @@ cc_test( size = "small", srcs = [ "webrtc_peer_id_test.cc", - "webrtc_test.cc", ], shard_count = 16, tags = [ @@ -199,7 +210,6 @@ cc_test( "requires-net:external", ], deps = [ - ":mediums", ":webrtc_peer_id", ":webrtc_socket", "//internal/platform:base", diff --git a/connections/implementation/mediums/mediums.cc b/connections/implementation/mediums/mediums.cc index 8dd6dccd..4e0ff7bf 100644 --- a/connections/implementation/mediums/mediums.cc +++ b/connections/implementation/mediums/mediums.cc @@ -14,10 +14,15 @@ #include "connections/implementation/mediums/mediums.h" +#include + #include "connections/implementation/mediums/awdl.h" #include "connections/implementation/mediums/ble.h" #include "connections/implementation/mediums/bluetooth_classic.h" #include "connections/implementation/mediums/bluetooth_radio.h" +#ifndef NO_WEBRTC +#include "connections/implementation/mediums/webrtc/webrtc_impl.h" +#endif #include "connections/implementation/mediums/webrtc.h" #include "connections/implementation/mediums/wifi.h" #include "connections/implementation/mediums/wifi_direct.h" @@ -27,6 +32,14 @@ namespace nearby { namespace connections { +Mediums::Mediums() { +#ifndef NO_WEBRTC + webrtc_ = std::make_unique(); +#else + webrtc_ = std::make_unique(); +#endif +} + BluetoothRadio& Mediums::GetBluetoothRadio() { return bluetooth_radio_; } BluetoothClassic& Mediums::GetBluetoothClassic() { return bluetooth_classic_; } @@ -41,7 +54,7 @@ WifiHotspot& Mediums::GetWifiHotspot() { return wifi_hotspot_; } WifiDirect& Mediums::GetWifiDirect() { return wifi_direct_; } -mediums::WebRtc& Mediums::GetWebRtc() { return webrtc_; } +mediums::WebRtc& Mediums::GetWebRtc() { return *webrtc_; } Awdl& Mediums::GetAwdl() { return awdl_; } diff --git a/connections/implementation/mediums/mediums.h b/connections/implementation/mediums/mediums.h index 9cacfc31..bc125964 100644 --- a/connections/implementation/mediums/mediums.h +++ b/connections/implementation/mediums/mediums.h @@ -15,15 +15,13 @@ #ifndef CORE_INTERNAL_MEDIUMS_MEDIUMS_H_ #define CORE_INTERNAL_MEDIUMS_MEDIUMS_H_ +#include + #include "connections/implementation/mediums/awdl.h" #include "connections/implementation/mediums/ble.h" #include "connections/implementation/mediums/bluetooth_classic.h" #include "connections/implementation/mediums/bluetooth_radio.h" -#ifdef NO_WEBRTC -#include "connections/implementation/mediums/webrtc_stub.h" -#else #include "connections/implementation/mediums/webrtc.h" -#endif #include "connections/implementation/mediums/wifi.h" #include "connections/implementation/mediums/wifi_direct.h" #include "connections/implementation/mediums/wifi_hotspot.h" @@ -35,7 +33,7 @@ namespace connections { // Facilitates convenient and reliable usage of various wireless mediums. class Mediums { public: - Mediums() = default; + Mediums(); ~Mediums() = default; // Returns a handle to the Bluetooth radio. @@ -81,7 +79,7 @@ class Mediums { WifiLan wifi_lan_; WifiHotspot wifi_hotspot_; WifiDirect wifi_direct_; - mediums::WebRtc webrtc_; + std::unique_ptr webrtc_; Awdl awdl_; }; diff --git a/connections/implementation/mediums/webrtc.h b/connections/implementation/mediums/webrtc.h index 47fcbc52..579bccde 100644 --- a/connections/implementation/mediums/webrtc.h +++ b/connections/implementation/mediums/webrtc.h @@ -15,262 +15,74 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_H_ -#ifndef NO_WEBRTC - -#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/webrtc/connection_flow.h" -#include "connections/implementation/mediums/webrtc/session_description_wrapper.h" #include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/mediums/webrtc_socket.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/cancelable_alarm.h" +#include "connections/implementation/proto/offline_wire_formats.pb.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" -#include "internal/platform/future.h" -#include "internal/platform/mutex.h" -#include "internal/platform/runnable.h" -#include "internal/platform/scheduled_executor.h" -#include "internal/platform/webrtc.h" -#include "proto/mediums/web_rtc_signaling_frames.pb.h" -#include "webrtc/api/jsep.h" namespace nearby { namespace connections { namespace mediums { -// Entry point for connecting a data channel between two devices via WebRtc. +// A non-working base implementation for connecting a data channel between two +// devices via WebRtc. class WebRtc { public: // Callback that is invoked when a new connection is accepted. using AcceptedConnectionCallback = absl::AnyInvocable socket)>; - WebRtc(); - ~WebRtc(); + virtual ~WebRtc() = default; // Gets the default two-letter country code associated with current locale. // For example, en_US locale resolves to "US". - std::string GetDefaultCountryCode(); + virtual std::string GetDefaultCountryCode() { return ""; } // Returns if WebRtc is available as a medium for nearby to transport data. // Runs on @MainThread. - bool IsAvailable(); + virtual bool IsAvailable() { return false; } // Returns if the device is accepting connection with specific service id. // Runs on @MainThread. - bool IsAcceptingConnections(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); + virtual bool IsAcceptingConnections(const std::string& service_id) { + return false; + } // Prepares the device to accept incoming WebRtc connections. Returns a // boolean value indicating if the device has started accepting connections. // Runs on @MainThread. - bool StartAcceptingConnections( + virtual bool StartAcceptingConnections( const std::string& service_id, const WebrtcPeerId& self_peer_id, const location::nearby::connections::LocationHint& location_hint, - AcceptedConnectionCallback callback, bool non_cellular) - ABSL_LOCKS_EXCLUDED(mutex_); + AcceptedConnectionCallback callback, bool non_cellular) { + return false; + } // Try to stop (accepting) the specific connection with provided service id. // Runs on @MainThread - void StopAcceptingConnections(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); + virtual void StopAcceptingConnections(const std::string& service_id) {} // Initiates a WebRtc connection with peer device identified by |peer_id| // with internal retry for maximum attempts of kConnectAttemptsLimit. // Runs on @MainThread. - ErrorOr> Connect( + virtual ErrorOr> Connect( const std::string& service_id, const WebrtcPeerId& peer_id, const location::nearby::connections::LocationHint& location_hint, - CancellationFlag* cancellation_flag, bool non_cellular) - ABSL_LOCKS_EXCLUDED(mutex_); + CancellationFlag* cancellation_flag, bool non_cellular) { + return {Error(location::nearby::proto::connections::OperationResultCode:: + DETAIL_UNKNOWN)}; + } - bool IsUsingCellular() ABSL_LOCKS_EXCLUDED(mutex_); - - protected: - // Use for unit tests only to inject a WebRtcMedium. - explicit WebRtc(std::unique_ptr medium); - - // Used in unit tests to determine how many calls to `AttemptToConnect` - // occured during a call to `Connect`, per service id. - std::map service_id_to_connect_attempts_count_map_; - - private: - static constexpr int kConnectAttemptsLimit = 3; - static constexpr int kRestartAcceptConnectionsLimit = 3; - - enum class Role { - kNone = 0, - kOfferer = 1, - kAnswerer = 2, - }; - - struct AcceptingConnectionsInfo { - // The self_peer_id is generated from the BT/WiFi advertisements and allows - // the scanner to message us over Tachyon. - WebrtcPeerId self_peer_id; - - // The registered callback. When there's an incoming connection, this - // callback is notified. - AcceptedConnectionCallback accepted_connection_callback; - - // Allows us to communicate with the Tachyon web server. - std::unique_ptr signaling_messenger; - - // Restarts the tachyon inbox receives messages streaming rpc if the - // streaming rpc times out. The streaming rpc times out after 60s while - // advertising. Non-null when listening for WebRTC connections as an - // offerer. - std::unique_ptr restart_tachyon_receive_messages_alarm; - - // Tracks the number of times we've restarted receiving messages after a - // failure. We limit the number to prevent endless restarts if we are - // repeatedly unable to communicate with Tachyon. - int restart_accept_connections_count = 0; - }; - - struct ConnectionRequestInfo { - // The self_peer_id is randomly generated and allows the advertiser to - // message us over Tachyon. - WebrtcPeerId self_peer_id; - - // Allows us to communicate with the Tachyon web server. - std::unique_ptr signaling_messenger; - - // The pending DataChannel future. Our client will be blocked on this while - // they wait for us to set up the channel over Tachyon. - Future> socket_future; - }; - - // Attempt to initiates a WebRtc connection with peer device identified by - // |peer_id|. - // Runs on @MainThread. - ErrorOr> AttemptToConnect( - const std::string& service_id, const WebrtcPeerId& peer_id, - const location::nearby::connections::LocationHint& location_hint, - CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns if the device is accepting connection with specific service id. - // Runs on @MainThread. - bool IsAcceptingConnectionsLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Receives a message from the signaling messenger. - void OnSignalingMessage(const std::string& service_id, - const ByteArray& message); - - // Decides whether to restart receiving messages. - void OnSignalingComplete(const std::string& service_id, bool success); - - // Runs on |single_thread_executor_|. - void ProcessTachyonInboxMessage(const std::string& service_id, - const ByteArray& message) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void SendOffer(const std::string& service_id, - const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ReceiveOffer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper offer) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void SendAnswer(const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ReceiveAnswer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper answer) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ReceiveIceCandidates( - const WebrtcPeerId& remote_peer_id, - std::vector> ice_candidates) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - std::unique_ptr CreateConnectionFlow( - const std::string& service_id, const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - std::unique_ptr GetConnectionFlow( - const WebrtcPeerId& remote_peer_id) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessDataChannelOpen(const std::string& service_id, - const WebrtcPeerId& remote_peer_id, - std::shared_ptr socket_wrapper) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessLocalIceCandidate( - const std::string& service_id, const WebrtcPeerId& remote_peer_id, - const location::nearby::mediums::IceCandidate ice_candidate) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessRestartTachyonReceiveMessages(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void RestartTachyonReceiveMessages(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void AdapterTypeChangedHandler(webrtc::AdapterType adapter_type) - ABSL_LOCKS_EXCLUDED(mutex_); - - void OffloadFromThread(const std::string& name, Runnable runnable); - - Mutex mutex_; - - std::unique_ptr medium_; - - // The single thread we throw the potentially blocking work on to. - ScheduledExecutor single_thread_executor_; - - // A map of ServiceID -> State for all services that are listening for - // incoming connections. - absl::flat_hash_map - accepting_connections_info_ ABSL_GUARDED_BY(mutex_); - - // A map of a remote PeerId -> State for pending connection requests. As - // messages from Tachyon come in, this lets us look up the connection request - // info to handle the interaction. - absl::flat_hash_map - requesting_connections_info_ ABSL_GUARDED_BY(mutex_); - - // A map of a remote PeerId -> ConnectionFlow. For each connection, we create - // a unique ConnectionFlow. - absl::flat_hash_map> - connection_flows_ ABSL_GUARDED_BY(mutex_); - - bool is_using_cellular_ ABSL_GUARDED_BY(mutex_) = true; + virtual bool IsUsingCellular() { return false; } }; } // namespace mediums } // namespace connections } // namespace nearby -#endif - #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_H_ diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index 3c20133b..357bf5e3 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -18,38 +18,37 @@ licenses(["notice"]) cc_library( name = "webrtc", - srcs = [ - "connection_flow.cc", - "signaling_frames.cc", - ], hdrs = [ - "connection_flow.h", "data_channel_listener.h", "local_ice_candidate_listener.h", "session_description_wrapper.h", - "signaling_frames.h", - ], - copts = [ - "-DCORE_ADAPTER_DLL", - "-DNO_WEBRTC", - ], - visibility = [ - "//connections/implementation:__subpackages__", ], + copts = ["-DNO_WEBRTC"], deps = [ - ":webrtc_socket_impl", "//connections:core_types", - "//connections/implementation/mediums:webrtc_peer_id", + "//connections/implementation/mediums:webrtc_socket", + # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep + # "//third_party/webrtc/files/stable/webrtc/api:jsep", + # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + "@com_google_absl//absl/functional:any_invocable", + ], +) + +cc_library( + name = "connection_flow", + srcs = ["connection_flow.cc"], + hdrs = ["connection_flow.h"], + deps = [ + ":webrtc", + ":webrtc_socket_impl", "//connections/implementation/mediums:webrtc_socket", "//internal/platform:base", "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:types", - "//proto/mediums:web_rtc_signaling_frames_cc_proto", - # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", # "//third_party/webrtc/files/stable/webrtc/api:jsep", - # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/memory", @@ -57,6 +56,18 @@ cc_library( ], ) +cc_library( + name = "signaling_frames", + srcs = ["signaling_frames.cc"], + hdrs = ["signaling_frames.h"], + deps = [ + "//connections/implementation/mediums:webrtc_peer_id", + "//internal/platform:base", + "//proto/mediums:web_rtc_signaling_frames_cc_proto", + # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + ], +) + cc_library( name = "webrtc_socket_impl", srcs = ["webrtc_socket_impl.cc"], @@ -76,28 +87,65 @@ cc_library( ], ) +cc_library( + name = "webrtc_impl", + srcs = ["webrtc_impl.cc"], + hdrs = ["webrtc_impl.h"], + visibility = [ + "//connections/implementation:__subpackages__", + ], + deps = [ + ":connection_flow", + ":signaling_frames", + ":webrtc", + "//connections/implementation/mediums:webrtc", + "//connections/implementation/mediums:webrtc_peer_id", + "//connections/implementation/mediums:webrtc_socket", + "//internal/platform:base", + "//internal/platform:cancellation_flag", + "//internal/platform:comm", + "//internal/platform:logging", + "//internal/platform:types", + "//proto/mediums:web_rtc_signaling_frames_cc_proto", + # "//third_party/webrtc/files/stable/webrtc/api:jsep", + "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", + "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/container:flat_hash_set", + "@com_google_absl//absl/functional:bind_front", + "@com_google_absl//absl/time", + ], +) + cc_test( name = "webrtc_test", timeout = "short", srcs = [ "connection_flow_test.cc", "signaling_frames_test.cc", + "webrtc_impl_test.cc", "webrtc_socket_impl_test.cc", ], + shard_count = 16, tags = [ "notsan", # NOTE(b/139734036): known data race in usrsctplib. "requires-net:external", ], deps = [ + ":connection_flow", + ":signaling_frames", ":webrtc", + ":webrtc_impl", ":webrtc_socket_impl", "//connections/implementation/mediums:webrtc_peer_id", "//connections/implementation/mediums:webrtc_socket", "//internal/platform:base", + "//internal/platform:cancellation_flag", "//internal/platform:comm", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # buildcleaner: keep + "//internal/test", # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", # "//third_party/webrtc/files/stable/webrtc/api:jsep", # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", diff --git a/connections/implementation/mediums/webrtc.cc b/connections/implementation/mediums/webrtc/webrtc_impl.cc similarity index 89% rename from connections/implementation/mediums/webrtc.cc rename to connections/implementation/mediums/webrtc/webrtc_impl.cc index 1c412e8c..372c8434 100644 --- a/connections/implementation/mediums/webrtc.cc +++ b/connections/implementation/mediums/webrtc/webrtc_impl.cc @@ -14,7 +14,7 @@ #ifndef NO_WEBRTC -#include "connections/implementation/mediums/webrtc.h" +#include "connections/implementation/mediums/webrtc/webrtc_impl.h" #include #include @@ -43,6 +43,7 @@ #include "internal/platform/runnable.h" #include "internal/platform/webrtc.h" #include "webrtc/api/jsep.h" +#include "webrtc/rtc_base/network_constants.h" namespace nearby { namespace connections { @@ -60,12 +61,12 @@ constexpr absl::Duration kRestartReceiveMessagesDuration = absl::Seconds(60); } // namespace -WebRtc::WebRtc() : WebRtc(std::make_unique()) {} +WebRtcImpl::WebRtcImpl() : WebRtcImpl(std::make_unique()) {} -WebRtc::WebRtc(std::unique_ptr medium) +WebRtcImpl::WebRtcImpl(std::unique_ptr medium) : medium_(std::move(medium)) {} -WebRtc::~WebRtc() { +WebRtcImpl::~WebRtcImpl() { // This ensures that all pending callbacks are run before we reset the medium // and we are not accepting new runnables. single_thread_executor_.Shutdown(); @@ -80,26 +81,26 @@ WebRtc::~WebRtc() { } } -std::string WebRtc::GetDefaultCountryCode() { +std::string WebRtcImpl::GetDefaultCountryCode() { return medium_->GetDefaultCountryCode(); } -bool WebRtc::IsAvailable() { return medium_->IsValid(); } +bool WebRtcImpl::IsAvailable() { return medium_->IsValid(); } -bool WebRtc::IsAcceptingConnections(const std::string& service_id) { +bool WebRtcImpl::IsAcceptingConnections(const std::string& service_id) { MutexLock lock(&mutex_); return IsAcceptingConnectionsLocked(service_id); } -bool WebRtc::IsAcceptingConnectionsLocked(const std::string& service_id) { +bool WebRtcImpl::IsAcceptingConnectionsLocked(const std::string& service_id) { return accepting_connections_info_.contains(service_id); } -bool WebRtc::StartAcceptingConnections(const std::string& service_id, - const WebrtcPeerId& self_peer_id, - const LocationHint& location_hint, - AcceptedConnectionCallback callback, - bool non_cellular) { +bool WebRtcImpl::StartAcceptingConnections(const std::string& service_id, + const WebrtcPeerId& self_peer_id, + const LocationHint& location_hint, + AcceptedConnectionCallback callback, + bool non_cellular) { MutexLock lock(&mutex_); if (!IsAvailable()) { LOG(WARNING) << "Cannot start accepting WebRTC connections because " @@ -131,8 +132,9 @@ bool WebRtc::StartAcceptingConnections(const std::string& service_id, // This registers ourselves w/ Tachyon, creating a room from the PeerId. // This allows a remote device to message us over Tachyon. if (!info.signaling_messenger->StartReceivingMessages( - absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id), - absl::bind_front(&WebRtc::OnSignalingComplete, this, service_id))) { + absl::bind_front(&WebRtcImpl::OnSignalingMessage, this, service_id), + absl::bind_front(&WebRtcImpl::OnSignalingComplete, this, + service_id))) { info.signaling_messenger.reset(); return false; } @@ -142,7 +144,7 @@ bool WebRtc::StartAcceptingConnections(const std::string& service_id, info.restart_tachyon_receive_messages_alarm = std::make_unique( "restart_receiving_messages_webrtc", - std::bind(&WebRtc::ProcessRestartTachyonReceiveMessages, this, + std::bind(&WebRtcImpl::ProcessRestartTachyonReceiveMessages, this, service_id), kRestartReceiveMessagesDuration, &single_thread_executor_); @@ -154,7 +156,7 @@ bool WebRtc::StartAcceptingConnections(const std::string& service_id, return true; } -void WebRtc::StopAcceptingConnections(const std::string& service_id) { +void WebRtcImpl::StopAcceptingConnections(const std::string& service_id) { MutexLock lock(&mutex_); if (!IsAcceptingConnectionsLocked(service_id)) { LOG(WARNING) << "Cannot stop accepting WebRTC connections because service " @@ -207,7 +209,7 @@ void WebRtc::StopAcceptingConnections(const std::string& service_id) { << service_id; } -ErrorOr> WebRtc::Connect( +ErrorOr> WebRtcImpl::Connect( const std::string& service_id, const WebrtcPeerId& remote_peer_id, const LocationHint& location_hint, CancellationFlag* cancellation_flag, bool non_cellular) { @@ -242,7 +244,7 @@ ErrorOr> WebRtc::Connect( return {Error(wrapper_result.error().operation_result_code().value())}; } -ErrorOr> WebRtc::AttemptToConnect( +ErrorOr> WebRtcImpl::AttemptToConnect( const std::string& service_id, const WebrtcPeerId& remote_peer_id, const LocationHint& location_hint, CancellationFlag* cancellation_flag) { ConnectionRequestInfo info = ConnectionRequestInfo(); @@ -298,7 +300,7 @@ ErrorOr> WebRtc::AttemptToConnect( } }; if (!info.signaling_messenger->StartReceivingMessages( - absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id), + absl::bind_front(&WebRtcImpl::OnSignalingMessage, this, service_id), signaling_complete_callback)) { LOG(INFO) << "Cannot connect to WebRTC peer " << remote_peer_id.GetId() @@ -360,7 +362,7 @@ ErrorOr> WebRtc::AttemptToConnect( } } -void WebRtc::ProcessLocalIceCandidate( +void WebRtcImpl::ProcessLocalIceCandidate( const std::string& service_id, const WebrtcPeerId& remote_peer_id, const location::nearby::mediums::IceCandidate ice_candidate) { MutexLock lock(&mutex_); @@ -407,14 +409,15 @@ void WebRtc::ProcessLocalIceCandidate( << service_id; } -void WebRtc::OnSignalingMessage(const std::string& service_id, - const ByteArray& message) { +void WebRtcImpl::OnSignalingMessage(const std::string& service_id, + const ByteArray& message) { OffloadFromThread("rtc-on-signaling-message", [this, service_id, message]() { ProcessTachyonInboxMessage(service_id, message); }); } -void WebRtc::OnSignalingComplete(const std::string& service_id, bool success) { +void WebRtcImpl::OnSignalingComplete(const std::string& service_id, + bool success) { LOG(INFO) << "Signaling completed with status: " << success; if (success) { return; @@ -438,8 +441,8 @@ void WebRtc::OnSignalingComplete(const std::string& service_id, bool success) { }); } -void WebRtc::ProcessTachyonInboxMessage(const std::string& service_id, - const ByteArray& message) { +void WebRtcImpl::ProcessTachyonInboxMessage(const std::string& service_id, + const ByteArray& message) { MutexLock lock(&mutex_); // Attempt to parse the incoming message as a WebRtcSignalingFrame. @@ -492,8 +495,8 @@ void WebRtc::ProcessTachyonInboxMessage(const std::string& service_id, } } -void WebRtc::SendOffer(const std::string& service_id, - const WebrtcPeerId& remote_peer_id) { +void WebRtcImpl::SendOffer(const std::string& service_id, + const WebrtcPeerId& remote_peer_id) { std::unique_ptr connection_flow = CreateConnectionFlow(service_id, remote_peer_id); if (!connection_flow) { @@ -534,8 +537,8 @@ void WebRtc::SendOffer(const std::string& service_id, LOG(INFO) << "Sent offer to " << remote_peer_id.GetId(); } -void WebRtc::ReceiveOffer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper offer) { +void WebRtcImpl::ReceiveOffer(const WebrtcPeerId& remote_peer_id, + SessionDescriptionWrapper offer) { const auto& entry = connection_flows_.find(remote_peer_id.GetId()); if (entry == connection_flows_.end()) { LOG(INFO) << "Unable to receive offer. Failed to create a ConnectionFlow."; @@ -548,7 +551,7 @@ void WebRtc::ReceiveOffer(const WebrtcPeerId& remote_peer_id, } } -void WebRtc::SendAnswer(const WebrtcPeerId& remote_peer_id) { +void WebRtcImpl::SendAnswer(const WebrtcPeerId& remote_peer_id) { const auto& entry = connection_flows_.find(remote_peer_id.GetId()); if (entry == connection_flows_.end()) { LOG(INFO) << "Unable to send answer. Failed to create a ConnectionFlow."; @@ -596,8 +599,8 @@ void WebRtc::SendAnswer(const WebrtcPeerId& remote_peer_id) { LOG(INFO) << "Sent answer to " << remote_peer_id.GetId(); } -void WebRtc::ReceiveAnswer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper answer) { +void WebRtcImpl::ReceiveAnswer(const WebrtcPeerId& remote_peer_id, + SessionDescriptionWrapper answer) { const auto& entry = connection_flows_.find(remote_peer_id.GetId()); if (entry == connection_flows_.end()) { LOG(INFO) << "Unable to receive answer. Failed to create a ConnectionFlow."; @@ -610,7 +613,7 @@ void WebRtc::ReceiveAnswer(const WebrtcPeerId& remote_peer_id, } } -void WebRtc::ReceiveIceCandidates( +void WebRtcImpl::ReceiveIceCandidates( const WebrtcPeerId& remote_peer_id, std::vector> ice_candidates) { const auto& entry = connection_flows_.find(remote_peer_id.GetId()); @@ -623,13 +626,13 @@ void WebRtc::ReceiveIceCandidates( entry->second->OnRemoteIceCandidatesReceived(std::move(ice_candidates)); } -void WebRtc::ProcessRestartTachyonReceiveMessages( +void WebRtcImpl::ProcessRestartTachyonReceiveMessages( const std::string& service_id) { MutexLock lock(&mutex_); RestartTachyonReceiveMessages(service_id); } -void WebRtc::RestartTachyonReceiveMessages(const std::string& service_id) { +void WebRtcImpl::RestartTachyonReceiveMessages(const std::string& service_id) { if (!IsAcceptingConnectionsLocked(service_id)) { LOG(INFO) << "Skipping restart listening for tachyon inbox messages since we are " @@ -646,8 +649,9 @@ void WebRtc::RestartTachyonReceiveMessages(const std::string& service_id) { // Attempt to re-register. if (!info.signaling_messenger->StartReceivingMessages( - absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id), - absl::bind_front(&WebRtc::OnSignalingComplete, this, service_id))) { + absl::bind_front(&WebRtcImpl::OnSignalingMessage, this, service_id), + absl::bind_front(&WebRtcImpl::OnSignalingComplete, this, + service_id))) { LOG(WARNING) << "Failed to restart listening for tachyon inbox messages for " "service " @@ -660,7 +664,7 @@ void WebRtc::RestartTachyonReceiveMessages(const std::string& service_id) { << service_id; } -void WebRtc::ProcessDataChannelOpen( +void WebRtcImpl::ProcessDataChannelOpen( const std::string& service_id, const WebrtcPeerId& remote_peer_id, std::shared_ptr socket_wrapper) { MutexLock lock(&mutex_); @@ -689,7 +693,7 @@ void WebRtc::ProcessDataChannelOpen( << service_id; } -void WebRtc::ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) { +void WebRtcImpl::ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) { MutexLock lock(&mutex_); LOG(INFO) << "Data channel has closed, removing connection flow for peer " << remote_peer_id.GetId(); @@ -697,7 +701,7 @@ void WebRtc::ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) { RemoveConnectionFlow(remote_peer_id); } -std::unique_ptr WebRtc::CreateConnectionFlow( +std::unique_ptr WebRtcImpl::CreateConnectionFlow( const std::string& service_id, const WebrtcPeerId& remote_peer_id) { RemoveConnectionFlow(remote_peer_id); @@ -749,7 +753,7 @@ std::unique_ptr WebRtc::CreateConnectionFlow( *medium_); } -void WebRtc::AdapterTypeChangedHandler(webrtc::AdapterType adapter_type) { +void WebRtcImpl::AdapterTypeChangedHandler(webrtc::AdapterType adapter_type) { MutexLock lock(&mutex_); is_using_cellular_ = adapter_type == webrtc::ADAPTER_TYPE_CELLULAR || adapter_type == webrtc::ADAPTER_TYPE_CELLULAR_2G || @@ -758,7 +762,7 @@ void WebRtc::AdapterTypeChangedHandler(webrtc::AdapterType adapter_type) { adapter_type == webrtc::ADAPTER_TYPE_CELLULAR_5G; } -void WebRtc::RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) { +void WebRtcImpl::RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) { if (!connection_flows_.erase(remote_peer_id.GetId())) { return; } @@ -773,11 +777,11 @@ void WebRtc::RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) { } } -void WebRtc::OffloadFromThread(const std::string& name, Runnable runnable) { +void WebRtcImpl::OffloadFromThread(const std::string& name, Runnable runnable) { single_thread_executor_.Execute(name, std::move(runnable)); } -bool WebRtc::IsUsingCellular() { +bool WebRtcImpl::IsUsingCellular() { MutexLock lock(&mutex_); return is_using_cellular_; } @@ -786,4 +790,4 @@ bool WebRtc::IsUsingCellular() { } // namespace connections } // namespace nearby -#endif +#endif // NO_WEBRTC diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.h b/connections/implementation/mediums/webrtc/webrtc_impl.h new file mode 100644 index 00000000..5bc91189 --- /dev/null +++ b/connections/implementation/mediums/webrtc/webrtc_impl.h @@ -0,0 +1,254 @@ +// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_ +#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_ + +#ifndef NO_WEBRTC + +#include +#include +#include +#include + +#include "absl/base/thread_annotations.h" +#include "absl/container/flat_hash_map.h" +#include "connections/implementation/mediums/webrtc.h" +#include "connections/implementation/mediums/webrtc/connection_flow.h" +#include "connections/implementation/mediums/webrtc/session_description_wrapper.h" +#include "connections/implementation/mediums/webrtc_peer_id.h" +#include "connections/implementation/mediums/webrtc_socket.h" +#include "internal/platform/byte_array.h" +#include "internal/platform/cancelable_alarm.h" +#include "internal/platform/cancellation_flag.h" +#include "internal/platform/expected.h" +#include "internal/platform/future.h" +#include "internal/platform/mutex.h" +#include "internal/platform/runnable.h" +#include "internal/platform/scheduled_executor.h" +#include "internal/platform/webrtc.h" +#include "proto/mediums/web_rtc_signaling_frames.pb.h" +#include "webrtc/api/jsep.h" +#include "webrtc/rtc_base/network_constants.h" + +namespace nearby { +namespace connections { +namespace mediums { + +// Entry point for connecting a data channel between two devices via WebRtc. +class WebRtcImpl : public WebRtc { + public: + WebRtcImpl(); + ~WebRtcImpl() override; + + // Overrides for WebRtc: + std::string GetDefaultCountryCode() override; + bool IsAvailable() override; + bool IsAcceptingConnections(const std::string& service_id) override + ABSL_LOCKS_EXCLUDED(mutex_); + bool StartAcceptingConnections( + const std::string& service_id, const WebrtcPeerId& self_peer_id, + const location::nearby::connections::LocationHint& location_hint, + AcceptedConnectionCallback callback, bool non_cellular) override + ABSL_LOCKS_EXCLUDED(mutex_); + void StopAcceptingConnections(const std::string& service_id) override + ABSL_LOCKS_EXCLUDED(mutex_); + ErrorOr> Connect( + const std::string& service_id, const WebrtcPeerId& peer_id, + const location::nearby::connections::LocationHint& location_hint, + CancellationFlag* cancellation_flag, bool non_cellular) override + ABSL_LOCKS_EXCLUDED(mutex_); + bool IsUsingCellular() override ABSL_LOCKS_EXCLUDED(mutex_); + + protected: + // Use for unit tests only to inject a WebRtcMedium. + explicit WebRtcImpl(std::unique_ptr medium); + + // Used in unit tests to determine how many calls to `AttemptToConnect` + // occured during a call to `Connect`, per service id. + std::map service_id_to_connect_attempts_count_map_; + + private: + static constexpr int kConnectAttemptsLimit = 3; + static constexpr int kRestartAcceptConnectionsLimit = 3; + + enum class Role { + kNone = 0, + kOfferer = 1, + kAnswerer = 2, + }; + + struct AcceptingConnectionsInfo { + // The self_peer_id is generated from the BT/WiFi advertisements and allows + // the scanner to message us over Tachyon. + WebrtcPeerId self_peer_id; + + // The registered callback. When there's an incoming connection, this + // callback is notified. + AcceptedConnectionCallback accepted_connection_callback; + + // Allows us to communicate with the Tachyon web server. + std::unique_ptr signaling_messenger; + + // Restarts the tachyon inbox receives messages streaming rpc if the + // streaming rpc times out. The streaming rpc times out after 60s while + // advertising. Non-null when listening for WebRTC connections as an + // offerer. + std::unique_ptr restart_tachyon_receive_messages_alarm; + + // Tracks the number of times we've restarted receiving messages after a + // failure. We limit the number to prevent endless restarts if we are + // repeatedly unable to communicate with Tachyon. + int restart_accept_connections_count = 0; + }; + + struct ConnectionRequestInfo { + // The self_peer_id is randomly generated and allows the advertiser to + // message us over Tachyon. + WebrtcPeerId self_peer_id; + + // Allows us to communicate with the Tachyon web server. + std::unique_ptr signaling_messenger; + + // The pending DataChannel future. Our client will be blocked on this while + // they wait for us to set up the channel over Tachyon. + Future> socket_future; + }; + + // Attempt to initiates a WebRtc connection with peer device identified by + // |peer_id|. + // Runs on @MainThread. + ErrorOr> AttemptToConnect( + const std::string& service_id, const WebrtcPeerId& peer_id, + const location::nearby::connections::LocationHint& location_hint, + CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_); + + // Returns if the device is accepting connection with specific service id. + // Runs on @MainThread. + bool IsAcceptingConnectionsLocked(const std::string& service_id) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Receives a message from the signaling messenger. + void OnSignalingMessage(const std::string& service_id, + const ByteArray& message); + + // Decides whether to restart receiving messages. + void OnSignalingComplete(const std::string& service_id, bool success); + + // Runs on |single_thread_executor_|. + void ProcessTachyonInboxMessage(const std::string& service_id, + const ByteArray& message) + ABSL_LOCKS_EXCLUDED(mutex_); + + // Runs on |single_thread_executor_|. + void SendOffer(const std::string& service_id, + const WebrtcPeerId& remote_peer_id) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Runs on |single_thread_executor_|. + void ReceiveOffer(const WebrtcPeerId& remote_peer_id, + SessionDescriptionWrapper offer) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Runs on |single_thread_executor_|. + void SendAnswer(const WebrtcPeerId& remote_peer_id) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Runs on |single_thread_executor_|. + void ReceiveAnswer(const WebrtcPeerId& remote_peer_id, + SessionDescriptionWrapper answer) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Runs on |single_thread_executor_|. + void ReceiveIceCandidates( + const WebrtcPeerId& remote_peer_id, + std::vector> ice_candidates) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Runs on |single_thread_executor_|. + std::unique_ptr CreateConnectionFlow( + const std::string& service_id, const WebrtcPeerId& remote_peer_id) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Runs on |single_thread_executor_|. + std::unique_ptr GetConnectionFlow( + const WebrtcPeerId& remote_peer_id) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Runs on |single_thread_executor_|. + void RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Runs on |single_thread_executor_|. + void ProcessDataChannelOpen(const std::string& service_id, + const WebrtcPeerId& remote_peer_id, + std::shared_ptr socket_wrapper) + ABSL_LOCKS_EXCLUDED(mutex_); + + // Runs on |single_thread_executor_|. + void ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) + ABSL_LOCKS_EXCLUDED(mutex_); + + // Runs on |single_thread_executor_|. + void ProcessLocalIceCandidate( + const std::string& service_id, const WebrtcPeerId& remote_peer_id, + location::nearby::mediums::IceCandidate ice_candidate) + ABSL_LOCKS_EXCLUDED(mutex_); + + // Runs on |single_thread_executor_|. + void ProcessRestartTachyonReceiveMessages(const std::string& service_id) + ABSL_LOCKS_EXCLUDED(mutex_); + + // Runs on |single_thread_executor_|. + void RestartTachyonReceiveMessages(const std::string& service_id) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Runs on |single_thread_executor_|. + void AdapterTypeChangedHandler(webrtc::AdapterType adapter_type) + ABSL_LOCKS_EXCLUDED(mutex_); + + void OffloadFromThread(const std::string& name, Runnable runnable); + + Mutex mutex_; + + std::unique_ptr medium_; + + // The single thread we throw the potentially blocking work on to. + ScheduledExecutor single_thread_executor_; + + // A map of ServiceID -> State for all services that are listening for + // incoming connections. + absl::flat_hash_map + accepting_connections_info_ ABSL_GUARDED_BY(mutex_); + + // A map of a remote PeerId -> State for pending connection requests. As + // messages from Tachyon come in, this lets us look up the connection request + // info to handle the interaction. + absl::flat_hash_map + requesting_connections_info_ ABSL_GUARDED_BY(mutex_); + + // A map of a remote PeerId -> ConnectionFlow. For each connection, we create + // a unique ConnectionFlow. + absl::flat_hash_map> + connection_flows_ ABSL_GUARDED_BY(mutex_); + + bool is_using_cellular_ ABSL_GUARDED_BY(mutex_) = true; +}; + +} // namespace mediums +} // namespace connections +} // namespace nearby + +#endif // NO_WEBRTC + +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_ diff --git a/connections/implementation/mediums/webrtc_test.cc b/connections/implementation/mediums/webrtc/webrtc_impl_test.cc similarity index 96% rename from connections/implementation/mediums/webrtc_test.cc rename to connections/implementation/mediums/webrtc/webrtc_impl_test.cc index fbd4da27..ce58c3ff 100644 --- a/connections/implementation/mediums/webrtc_test.cc +++ b/connections/implementation/mediums/webrtc/webrtc_impl_test.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/mediums/webrtc.h" +#include "connections/implementation/mediums/webrtc/webrtc_impl.h" #include #include @@ -48,10 +48,10 @@ struct WebRtcTestParams { bool non_cellular; }; -class TestWebRtc : public WebRtc { +class TestWebRtc : public WebRtcImpl { public: explicit TestWebRtc(std::unique_ptr medium) - : WebRtc(std::move(medium)) {} + : WebRtcImpl(std::move(medium)) {} int connect_attempts_count(std::string service_id) { return service_id_to_connect_attempts_count_map_[service_id]; @@ -72,7 +72,7 @@ TEST_P(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) { env_.Start({.webrtc_enabled = true}); WebRtcTestParams params = GetParam(); env_.SetFeatureFlags(params.feature_flags); - WebRtc receiver, sender; + WebRtcImpl receiver, sender; std::shared_ptr receiver_socket; const WebrtcPeerId self_id("self_id"); const std::string service_id("NearbySharing"); @@ -93,7 +93,7 @@ TEST_P(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) { CancellationFlag flag; ErrorOr> sender_socket_result = sender.Connect( service_id, self_id, location_hint, &flag, params.non_cellular); - EXPECT_TRUE(sender_socket_result.has_value()); + ASSERT_TRUE(sender_socket_result.has_value()); EXPECT_TRUE(sender_socket_result.value()->IsValid()); ExceptionOr devices_connected = connected.Get(); @@ -115,7 +115,7 @@ TEST_P(WebRtcTest, CanCancelConnect) { env_.Start({.webrtc_enabled = true}); WebRtcTestParams params = GetParam(); env_.SetFeatureFlags(params.feature_flags); - WebRtc receiver, sender; + WebRtcImpl receiver, sender; std::shared_ptr receiver_socket; const WebrtcPeerId self_id("self_id"); const std::string service_id("NearbySharing"); @@ -138,7 +138,7 @@ TEST_P(WebRtcTest, CanCancelConnect) { service_id, self_id, location_hint, &flag, params.non_cellular); // If FeatureFlag is disabled, Cancelled is false as no-op. if (!params.feature_flags.enable_cancellation_flag) { - EXPECT_TRUE(sender_socket_result.has_value()); + ASSERT_TRUE(sender_socket_result.has_value()); EXPECT_TRUE(sender_socket_result.value()->IsValid()); ExceptionOr devices_connected = connected.Get(); @@ -161,7 +161,7 @@ TEST_P(WebRtcTest, CanCancelConnect) { // Basic test to check that device is accepting connections when initialized. TEST_P(WebRtcTest, NotAcceptingConnections) { env_.Start({.webrtc_enabled = true}); - WebRtc webrtc; + WebRtcImpl webrtc; ASSERT_TRUE(webrtc.IsAvailable()); EXPECT_FALSE(webrtc.IsAcceptingConnections(std::string{})); env_.Stop(); @@ -173,7 +173,7 @@ TEST_P(WebRtcTest, StartAcceptingConnectionTwice) { env_.Start({.webrtc_enabled = true}); WebRtcTestParams params = GetParam(); testing::StrictMock mock_accepted_callback_; - WebRtc webrtc; + WebRtcImpl webrtc; WebrtcPeerId self_id("peer_id"); const std::string service_id("NearbySharing"); LocationHint location_hint{}; @@ -195,7 +195,7 @@ TEST_P(WebRtcTest, StartAcceptingConnectionTwice) { TEST_P(WebRtcTest, Connect_NoPeer) { env_.Start({.webrtc_enabled = true}); WebRtcTestParams params = GetParam(); - WebRtc webrtc; + WebRtcImpl webrtc; WebrtcPeerId peer_id("peer_id"); const std::string service_id("NearbySharing"); LocationHint location_hint; @@ -217,7 +217,7 @@ TEST_P(WebRtcTest, StartAcceptingConnection_ThenConnect) { env_.Start({.webrtc_enabled = true}); testing::StrictMock mock_accepted_callback_; WebRtcTestParams params = GetParam(); - WebRtc webrtc; + WebRtcImpl webrtc; WebrtcPeerId self_id("peer_id"); const std::string service_id("NearbySharing"); LocationHint location_hint; @@ -244,7 +244,7 @@ TEST_P(WebRtcTest, StartAndStopAcceptingConnections) { env_.Start({.webrtc_enabled = true}); testing::StrictMock mock_accepted_callback_; WebRtcTestParams params = GetParam(); - WebRtc webrtc; + WebRtcImpl webrtc; WebrtcPeerId self_id("peer_id"); const std::string service_id("NearbySharing"); LocationHint location_hint; @@ -263,7 +263,7 @@ TEST_P(WebRtcTest, StartAndStopAcceptingConnections) { // without disconnecting in between. TEST_P(WebRtcTest, ConnectTwice) { env_.Start({.webrtc_enabled = true}); - WebRtc receiver, sender, device_c; + WebRtcImpl receiver, sender, device_c; std::shared_ptr receiver_socket; WebRtcTestParams params = GetParam(); const WebrtcPeerId self_id("self_id"), other_id("other_id"); @@ -291,7 +291,7 @@ TEST_P(WebRtcTest, ConnectTwice) { CancellationFlag flag; ErrorOr> sender_socket_result = sender.Connect( service_id, self_id, location_hint, &flag, params.non_cellular); - EXPECT_TRUE(sender_socket_result.has_value()); + ASSERT_TRUE(sender_socket_result.has_value()); EXPECT_TRUE(sender_socket_result.value()->IsValid()); ExceptionOr devices_connected = connected.Get(); @@ -305,7 +305,7 @@ TEST_P(WebRtcTest, ConnectTwice) { socket_result.value()->Close(); EXPECT_TRUE(receiver_socket->IsValid()); - EXPECT_TRUE(sender_socket_result.has_value()); + ASSERT_TRUE(sender_socket_result.has_value()); EXPECT_TRUE(sender_socket_result.value()->IsValid()); sender_socket_result.value()->GetOutputStream().Write(message); @@ -322,7 +322,7 @@ TEST_P(WebRtcTest, ConnectTwice) { // other but disconnect before being able to send/receive the actual data. TEST_P(WebRtcTest, ConnectBothDevicesAndAbort) { env_.Start({.webrtc_enabled = true}); - WebRtc receiver, sender; + WebRtcImpl receiver, sender; std::shared_ptr receiver_socket, sender_socket; WebRtcTestParams params = GetParam(); const WebrtcPeerId self_id("self_id"); @@ -343,7 +343,7 @@ TEST_P(WebRtcTest, ConnectBothDevicesAndAbort) { CancellationFlag flag; ErrorOr> sender_socket_result = sender.Connect( service_id, self_id, location_hint, &flag, params.non_cellular); - EXPECT_TRUE(sender_socket_result.has_value()); + ASSERT_TRUE(sender_socket_result.has_value()); EXPECT_TRUE(sender_socket_result.value()->IsValid()); ExceptionOr devices_connected = connected.Get(); @@ -358,7 +358,7 @@ TEST_P(WebRtcTest, ConnectBothDevicesAndAbort) { // other and the actual data is exchanged successfully between the devices. TEST_P(WebRtcTest, ConnectBothDevicesAndSendData) { env_.Start({.webrtc_enabled = true}); - WebRtc receiver, sender; + WebRtcImpl receiver, sender; std::shared_ptr receiver_socket; WebRtcTestParams params = GetParam(); const WebrtcPeerId self_id("self_id"); @@ -380,7 +380,7 @@ TEST_P(WebRtcTest, ConnectBothDevicesAndSendData) { CancellationFlag flag; ErrorOr> sender_socket_result = sender.Connect( service_id, self_id, location_hint, &flag, params.non_cellular); - EXPECT_TRUE(sender_socket_result.has_value()); + ASSERT_TRUE(sender_socket_result.has_value()); EXPECT_TRUE(sender_socket_result.value()->IsValid()); ExceptionOr devices_connected = connected.Get(); @@ -404,7 +404,7 @@ TEST_P(WebRtcTest, Connect_NullPeerConnection) { env_.SetUseValidPeerConnection( /*use_valid_peer_connection=*/false); - WebRtc webrtc; + WebRtcImpl webrtc; const std::string service_id("NearbySharing"); WebrtcPeerId self_id("peer_id"); LocationHint location_hint; @@ -424,7 +424,7 @@ TEST_P(WebRtcTest, ContinueAcceptingConnectionsOnComplete) { env_.Start({.webrtc_enabled = true}); testing::StrictMock mock_accepted_callback_; WebRtcTestParams params = GetParam(); - WebRtc webrtc; + WebRtcImpl webrtc; WebrtcPeerId self_id("peer_id"); const std::string service_id("NearbySharing"); LocationHint location_hint; @@ -595,7 +595,7 @@ TEST_P(WebRtcTest, CancelDuringConnect_MultipleConnect) { // Simulate a successful connect for the endpoint of NearbySharing. ErrorOr> sender_socket_result = sender->Connect( ns_service_id, self_id, location_hint, &flag, params.non_cellular); - EXPECT_TRUE(sender_socket_result.has_value()); + ASSERT_TRUE(sender_socket_result.has_value()); EXPECT_TRUE(sender_socket_result.value()->IsValid()); // Calls `CancellationFlag::Cancel` during a call to `GetSignalingMessenger` diff --git a/connections/implementation/mediums/webrtc_stub.cc b/connections/implementation/mediums/webrtc_stub.cc deleted file mode 100644 index b50a7bf4..00000000 --- a/connections/implementation/mediums/webrtc_stub.cc +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2020 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. - -#ifdef NO_WEBRTC - -#include "connections/implementation/mediums/webrtc_stub.h" - -#include -#include - -#include "connections/implementation/mediums/webrtc_socket.h" -#include "internal/platform/cancelable_alarm.h" -#include "internal/platform/expected.h" -#include "internal/platform/future.h" -#include "internal/platform/listeners.h" - -namespace nearby { -namespace connections { -namespace mediums { -using ::location::nearby::connections::LocationHint; -using ::location::nearby::proto::connections::OperationResultCode; - -WebRtc::WebRtc() = default; - -WebRtc::~WebRtc() {} - -std::string WebRtc::GetDefaultCountryCode() { return "US"; } - -bool WebRtc::IsAvailable() { return false; } - -bool WebRtc::IsAcceptingConnections(const std::string& service_id) { - return false; -} - -bool WebRtc::StartAcceptingConnections(const std::string& service_id, - const WebrtcPeerId& self_peer_id, - const LocationHint& location_hint, - AcceptedConnectionCallback callback) { - return false; -} - -void WebRtc::StopAcceptingConnections(const std::string& service_id) {} - -ErrorOr> WebRtc::Connect( - const std::string& service_id, const WebrtcPeerId& remote_peer_id, - const LocationHint& location_hint, CancellationFlag* cancellation_flag) { - return {Error(OperationResultCode::DETAIL_UNKNOWN)}; -} - -bool WebRtc::IsUsingCellular() { return false; } - -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif diff --git a/connections/implementation/mediums/webrtc_stub.h b/connections/implementation/mediums/webrtc_stub.h deleted file mode 100644 index ef5ddfb9..00000000 --- a/connections/implementation/mediums/webrtc_stub.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_STUB_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_STUB_H_ - -#ifdef NO_WEBRTC - -#include -#include -#include -#include - -#include "connections/implementation/mediums/webrtc_peer_id.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "connections/implementation/proto/offline_wire_formats.pb.h" -#include "internal/platform/cancellation_flag.h" -#include "internal/platform/expected.h" -#include "internal/platform/listeners.h" - -namespace nearby { -namespace connections { -namespace mediums { - -// Entry point for connecting a data channel between two devices via WebRtc. -class WebRtc { - public: - // Callback that is invoked when a new connection is accepted. - using AcceptedConnectionCallback = - absl::AnyInvocable socket)>; - WebRtc(); - ~WebRtc(); - - // Gets the default two-letter country code associated with current locale. - // For example, en_US locale resolves to "US". - std::string GetDefaultCountryCode(); - - // Returns if WebRtc is available as a medium for nearby to transport data. - // Runs on @MainThread. - bool IsAvailable(); - - // Returns if the device is accepting connection with specific service id. - // Runs on @MainThread. - bool IsAcceptingConnections(const std::string& service_id); - - // Prepares the device to accept incoming WebRtc connections. Returns a - // boolean value indicating if the device has started accepting connections. - // Runs on @MainThread. - bool StartAcceptingConnections( - const std::string& service_id, const WebrtcPeerId& self_peer_id, - const location::nearby::connections::LocationHint& location_hint, - AcceptedConnectionCallback callback); - - // Try to stop (accepting) the specific connection with provided service id. - // Runs on @MainThread - void StopAcceptingConnections(const std::string& service_id); - - // Initiates a WebRtc connection with peer device identified by |peer_id| - // with internal retry for maximum attempts of kConnectAttemptsLimit. - // Runs on @MainThread. - ErrorOr> Connect( - const std::string& service_id, const WebrtcPeerId& peer_id, - const location::nearby::connections::LocationHint& location_hint, - CancellationFlag* cancellation_flag); - - bool IsUsingCellular(); -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_STUB_H_ diff --git a/connections/implementation/p2p_cluster_pcp_handler.h b/connections/implementation/p2p_cluster_pcp_handler.h index 7dac0be2..712f362f 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.h +++ b/connections/implementation/p2p_cluster_pcp_handler.h @@ -55,11 +55,7 @@ #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_stub.h" -#else #include "connections/implementation/mediums/webrtc.h" -#endif #include "connections/implementation/pcp.h" #include "connections/implementation/wifi_lan_service_info.h" #include "internal/platform/byte_array.h" From 9e00f2ece821b40d949719b276016aec492f6744 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 19 May 2026 13:53:44 -0700 Subject: [PATCH 101/151] Cleanup webrtc files. PiperOrigin-RevId: 918011253 --- .../implementation/mediums/webrtc/BUILD | 18 +++++++++--------- .../mediums/webrtc/connection_flow.cc | 12 +++++++----- .../mediums/webrtc/connection_flow.h | 7 +++---- .../mediums/webrtc/data_channel_listener.h | 4 ---- .../webrtc/local_ice_candidate_listener.h | 8 ++------ .../webrtc/session_description_wrapper.h | 8 +++----- .../mediums/webrtc/signaling_frames.cc | 10 +++++++--- .../mediums/webrtc/signaling_frames.h | 7 ++----- .../mediums/webrtc/webrtc_impl.cc | 4 ---- .../mediums/webrtc/webrtc_impl.h | 4 ---- .../mediums/webrtc/webrtc_socket_impl.cc | 4 ---- .../mediums/webrtc/webrtc_socket_impl.h | 4 ---- .../mediums/webrtc/webrtc_socket_impl_test.cc | 2 ++ 13 files changed, 35 insertions(+), 57 deletions(-) diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index 357bf5e3..26c8f243 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -25,11 +25,9 @@ cc_library( ], copts = ["-DNO_WEBRTC"], deps = [ - "//connections:core_types", "//connections/implementation/mediums:webrtc_socket", - # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep + "//internal/platform:base", # "//third_party/webrtc/files/stable/webrtc/api:jsep", - # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "@com_google_absl//absl/functional:any_invocable", ], ) @@ -49,6 +47,11 @@ cc_library( # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", # "//third_party/webrtc/files/stable/webrtc/api:jsep", # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + # "//third_party/webrtc/files/stable/webrtc/api:rtc_error", + # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", + "//third_party/webrtc/files/stable/webrtc/rtc_base:refcount", + "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/memory", @@ -72,9 +75,6 @@ cc_library( name = "webrtc_socket_impl", srcs = ["webrtc_socket_impl.cc"], hdrs = ["webrtc_socket_impl.h"], - visibility = [ - "//connections/implementation:__subpackages__", - ], deps = [ "//connections/implementation/mediums:webrtc_socket", "//internal/platform:base", @@ -92,7 +92,7 @@ cc_library( srcs = ["webrtc_impl.cc"], hdrs = ["webrtc_impl.h"], visibility = [ - "//connections/implementation:__subpackages__", + "//connections/implementation/mediums:__pkg__", ], deps = [ ":connection_flow", @@ -128,7 +128,6 @@ cc_test( ], shard_count = 16, tags = [ - "notsan", # NOTE(b/139734036): known data race in usrsctplib. "requires-net:external", ], deps = [ @@ -144,11 +143,12 @@ cc_test( "//internal/platform:comm", "//internal/platform:test_util", "//internal/platform:types", - "//internal/platform/implementation/g3", # buildcleaner: keep + "//internal/platform/implementation:platform_impl", "//internal/test", # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", # "//third_party/webrtc/files/stable/webrtc/api:jsep", # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/rtc_base:refcount", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/time", diff --git a/connections/implementation/mediums/webrtc/connection_flow.cc b/connections/implementation/mediums/webrtc/connection_flow.cc index bff8e441..02f31b20 100644 --- a/connections/implementation/mediums/webrtc/connection_flow.cc +++ b/connections/implementation/mediums/webrtc/connection_flow.cc @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef NO_WEBRTC - #include "connections/implementation/mediums/webrtc/connection_flow.h" #include @@ -27,7 +25,6 @@ #include "connections/implementation/mediums/webrtc/local_ice_candidate_listener.h" #include "connections/implementation/mediums/webrtc/session_description_wrapper.h" #include "connections/implementation/mediums/webrtc/webrtc_socket_impl.h" -#include "connections/implementation/mediums/webrtc_socket.h" #include "internal/platform/exception.h" #include "internal/platform/future.h" #include "internal/platform/logging.h" @@ -36,6 +33,13 @@ #include "internal/platform/webrtc.h" #include "webrtc/api/data_channel_interface.h" #include "webrtc/api/jsep.h" +#include "webrtc/api/peer_connection_interface.h" +#include "webrtc/api/rtc_error.h" +#include "webrtc/api/scoped_refptr.h" +#include "webrtc/api/set_local_description_observer_interface.h" +#include "webrtc/api/set_remote_description_observer_interface.h" +#include "webrtc/rtc_base/ref_counted_object.h" +#include "webrtc/rtc_base/thread.h" namespace nearby { namespace connections { @@ -579,5 +583,3 @@ ConnectionFlow::GetAndResetPeerConnection() { } // namespace mediums } // namespace connections } // namespace nearby - -#endif diff --git a/connections/implementation/mediums/webrtc/connection_flow.h b/connections/implementation/mediums/webrtc/connection_flow.h index 73e8294e..b83cfe0b 100644 --- a/connections/implementation/mediums/webrtc/connection_flow.h +++ b/connections/implementation/mediums/webrtc/connection_flow.h @@ -15,8 +15,6 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_CONNECTION_FLOW_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_CONNECTION_FLOW_H_ -#ifndef NO_WEBRTC - #include #include @@ -34,7 +32,10 @@ #include "internal/platform/runnable.h" #include "internal/platform/webrtc.h" #include "webrtc/api/data_channel_interface.h" +#include "webrtc/api/jsep.h" #include "webrtc/api/peer_connection_interface.h" +#include "webrtc/api/scoped_refptr.h" +#include "webrtc/rtc_base/network_constants.h" namespace nearby { namespace connections { @@ -246,6 +247,4 @@ class ConnectionFlow : public webrtc::PeerConnectionObserver { } // namespace connections } // namespace nearby -#endif - #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_CONNECTION_FLOW_H_ diff --git a/connections/implementation/mediums/webrtc/data_channel_listener.h b/connections/implementation/mediums/webrtc/data_channel_listener.h index ec679940..cb4e39b3 100644 --- a/connections/implementation/mediums/webrtc/data_channel_listener.h +++ b/connections/implementation/mediums/webrtc/data_channel_listener.h @@ -15,8 +15,6 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_ -#ifndef NO_WEBRTC - #include #include "absl/functional/any_invocable.h" @@ -41,6 +39,4 @@ struct DataChannelListener { } // namespace connections } // namespace nearby -#endif // NO_WEBRTC - #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_ diff --git a/connections/implementation/mediums/webrtc/local_ice_candidate_listener.h b/connections/implementation/mediums/webrtc/local_ice_candidate_listener.h index da71236f..a3b10fd0 100644 --- a/connections/implementation/mediums/webrtc/local_ice_candidate_listener.h +++ b/connections/implementation/mediums/webrtc/local_ice_candidate_listener.h @@ -15,11 +15,9 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_LOCAL_ICE_CANDIDATE_LISTENER_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_LOCAL_ICE_CANDIDATE_LISTENER_H_ -#ifndef NO_WEBRTC - -#include "connections/listeners.h" +#include "absl/functional/any_invocable.h" +#include "internal/platform/listeners.h" #include "webrtc/api/jsep.h" -#include "webrtc/api/peer_connection_interface.h" namespace nearby { namespace connections { @@ -37,6 +35,4 @@ struct LocalIceCandidateListener { } // namespace connections } // namespace nearby -#endif - #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_LOCAL_ICE_CANDIDATE_LISTENER_H_ diff --git a/connections/implementation/mediums/webrtc/session_description_wrapper.h b/connections/implementation/mediums/webrtc/session_description_wrapper.h index ef468120..a099b175 100644 --- a/connections/implementation/mediums/webrtc/session_description_wrapper.h +++ b/connections/implementation/mediums/webrtc/session_description_wrapper.h @@ -15,9 +15,9 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_SESSION_DESCRIPTION_WRAPPER_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_SESSION_DESCRIPTION_WRAPPER_H_ -#ifndef NO_WEBRTC - -#include "webrtc/api/peer_connection_interface.h" +#include +#include +#include "webrtc/api/jsep.h" // Wrapper object around SessionDescriptionInterface*. // This object owns the SessionDescriptionInterface* unless Release() has been @@ -63,6 +63,4 @@ class SessionDescriptionWrapper { std::unique_ptr impl_; }; -#endif - #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_SESSION_DESCRIPTION_WRAPPER_H_ diff --git a/connections/implementation/mediums/webrtc/signaling_frames.cc b/connections/implementation/mediums/webrtc/signaling_frames.cc index 8991c60a..b59f8c7d 100644 --- a/connections/implementation/mediums/webrtc/signaling_frames.cc +++ b/connections/implementation/mediums/webrtc/signaling_frames.cc @@ -12,9 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef NO_WEBRTC +#include +#include +#include +#include #include "connections/implementation/mediums/webrtc/signaling_frames.h" +#include "connections/implementation/mediums/webrtc_peer_id.h" +#include "internal/platform/byte_array.h" +#include "webrtc/api/jsep.h" namespace nearby { namespace connections { @@ -131,5 +137,3 @@ location::nearby::mediums::IceCandidate EncodeIceCandidate( } // namespace mediums } // namespace connections } // namespace nearby - -#endif diff --git a/connections/implementation/mediums/webrtc/signaling_frames.h b/connections/implementation/mediums/webrtc/signaling_frames.h index 6e13645d..c6579463 100644 --- a/connections/implementation/mediums/webrtc/signaling_frames.h +++ b/connections/implementation/mediums/webrtc/signaling_frames.h @@ -15,14 +15,13 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_SIGNALING_FRAMES_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_SIGNALING_FRAMES_H_ -#ifndef NO_WEBRTC - +#include #include #include "connections/implementation/mediums/webrtc_peer_id.h" #include "internal/platform/byte_array.h" #include "proto/mediums/web_rtc_signaling_frames.pb.h" -#include "webrtc/api/peer_connection_interface.h" +#include "webrtc/api/jsep.h" namespace nearby { namespace connections { @@ -55,6 +54,4 @@ std::vector> DecodeIceCandidates( } // namespace connections } // namespace nearby -#endif - #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_SIGNALING_FRAMES_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.cc b/connections/implementation/mediums/webrtc/webrtc_impl.cc index 372c8434..85202f7c 100644 --- a/connections/implementation/mediums/webrtc/webrtc_impl.cc +++ b/connections/implementation/mediums/webrtc/webrtc_impl.cc @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef NO_WEBRTC - #include "connections/implementation/mediums/webrtc/webrtc_impl.h" #include @@ -789,5 +787,3 @@ bool WebRtcImpl::IsUsingCellular() { } // namespace mediums } // namespace connections } // namespace nearby - -#endif // NO_WEBRTC diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.h b/connections/implementation/mediums/webrtc/webrtc_impl.h index 5bc91189..349581bd 100644 --- a/connections/implementation/mediums/webrtc/webrtc_impl.h +++ b/connections/implementation/mediums/webrtc/webrtc_impl.h @@ -15,8 +15,6 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_ -#ifndef NO_WEBRTC - #include #include #include @@ -249,6 +247,4 @@ class WebRtcImpl : public WebRtc { } // namespace connections } // namespace nearby -#endif // NO_WEBRTC - #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc b/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc index c34160c5..ff8a3a03 100644 --- a/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc +++ b/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef NO_WEBRTC - #include "connections/implementation/mediums/webrtc/webrtc_socket_impl.h" #include @@ -203,5 +201,3 @@ void WebRtcSocketImpl::OffloadFromSignalingThread(Runnable runnable) { } // namespace mediums } // namespace connections } // namespace nearby - -#endif // NO_WEBRTC diff --git a/connections/implementation/mediums/webrtc/webrtc_socket_impl.h b/connections/implementation/mediums/webrtc/webrtc_socket_impl.h index 071522ef..b3605462 100644 --- a/connections/implementation/mediums/webrtc/webrtc_socket_impl.h +++ b/connections/implementation/mediums/webrtc/webrtc_socket_impl.h @@ -15,8 +15,6 @@ #ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_IMPL_H_ #define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_IMPL_H_ -#ifndef NO_WEBRTC - #include #include #include @@ -131,6 +129,4 @@ class WebRtcSocketImpl : public WebRtcSocket, } // namespace connections } // namespace nearby -#endif // NO_WEBRTC - #endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_IMPL_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc b/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc index b7f46c3a..fdffc732 100644 --- a/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc +++ b/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc @@ -24,6 +24,8 @@ #include "internal/platform/byte_array.h" #include "internal/platform/exception.h" #include "webrtc/api/data_channel_interface.h" +#include "webrtc/api/scoped_refptr.h" +#include "webrtc/rtc_base/ref_counted_object.h" namespace nearby { namespace connections { From 9fb24226f00b982b460e9678724414ac64ada905 Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 19 May 2026 22:01:02 -0700 Subject: [PATCH 102/151] ...text... PiperOrigin-RevId: 918210878 --- proto/sharing_enums.proto | 2 -- sharing/proto/wire_format.proto | 1 - 2 files changed, 3 deletions(-) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index e8c3b121..7adafdd3 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -845,8 +845,6 @@ enum SharingUseCase { USE_CASE_NEARBY_SHARE_WITH_QR_CODE = 7 [deprecated = true]; // The user was redirected from Bluetooth sharing UI to Nearby Share USE_CASE_REDIRECTED_FROM_BLUETOOTH_SHARE = 8; - USE_CASE_TAP_TO_SHARE = 9; - USE_CASE_TAP_TO_SHARE_FROM_TTX_FLOW = 10; } // Used only for Windows App now. diff --git a/sharing/proto/wire_format.proto b/sharing/proto/wire_format.proto index a8d7396f..b0db8294 100644 --- a/sharing/proto/wire_format.proto +++ b/sharing/proto/wire_format.proto @@ -220,7 +220,6 @@ message IntroductionFrame { NEARBY_SHARE = 1; REMOTE_COPY = 2; TAP_TO_SHARE = 9; - TAP_TO_SHARE_FROM_TTX_FLOW = 10; } repeated FileMetadata file_metadata = 1; From 042b19f94cacb60b5ffa72090db87d5986990870 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 20 May 2026 10:20:03 -0700 Subject: [PATCH 103/151] Clean up BUILD targets. PiperOrigin-RevId: 918518571 --- connections/BUILD | 3 ++- connections/c/BUILD | 1 + connections/implementation/BUILD | 1 + internal/platform/BUILD | 7 ++++--- sharing/BUILD | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/connections/BUILD b/connections/BUILD index 3c5966d4..c759b732 100644 --- a/connections/BUILD +++ b/connections/BUILD @@ -94,9 +94,9 @@ cc_library( "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/interop:authentication_status", "//internal/platform:base", + "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:mac_address", - "//internal/platform:types", "//internal/platform:util", "//proto:connections_enums_cc_proto", "@com_google_absl//absl/functional:any_invocable", @@ -123,6 +123,7 @@ cc_test( "//connections/implementation:internal_test", "//connections/v3:v3_types", "//internal/platform:base", + "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep diff --git a/connections/c/BUILD b/connections/c/BUILD index b25c23e5..7d74e9bd 100644 --- a/connections/c/BUILD +++ b/connections/c/BUILD @@ -56,6 +56,7 @@ cc_library( "//internal/flags:flag_reader", "//internal/flags:nearby_flags", "//internal/platform:base", + "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:mac_address", "//internal/platform:types", diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index a1912375..92038756 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -584,6 +584,7 @@ cc_test( "//connections:core_types", "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/platform:base", + "//internal/platform:comm", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep "@com_github_protobuf_matchers//protobuf-matchers", diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 677206a7..c7d13d0f 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -231,7 +231,6 @@ cc_library( "count_down_latch.h", "crypto.h", "direct_executor.h", - "file.h", "future.h", "lockable.h", "monitored_runnable.h", @@ -335,6 +334,7 @@ cc_library( "bluetooth_adapter.h", "bluetooth_classic.h", "credential_storage_impl.h", + "file.h", "webrtc.h", "wifi.h", "wifi_direct.h", @@ -349,7 +349,7 @@ cc_library( "//connections:__subpackages__", "//internal/platform/implementation:__subpackages__", "//internal/test:__subpackages__", - "//third_party/nearby/presence:__subpackages__", + "//sharing:__subpackages__", ], deps = [ ":base", @@ -363,6 +363,7 @@ cc_library( "//internal/flags:nearby_flags", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", + "//internal/platform/implementation:types", "//internal/platform/implementation:wifi_utils", # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", @@ -608,6 +609,7 @@ cc_test( shard_count = 16, deps = [ ":base", + ":comm", ":connection_info", ":logging", ":mac_address", @@ -619,7 +621,6 @@ cc_test( "//internal/crypto_cros", "//internal/platform/implementation:platform_impl", "//internal/platform/implementation:types", - "//internal/test", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/status", diff --git a/sharing/BUILD b/sharing/BUILD index 674ab9f6..2533b34b 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -395,6 +395,7 @@ cc_library( "//internal/flags:nearby_flags", "//internal/network:url", "//internal/platform:base", + "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:mac_address", "//internal/platform:types", @@ -999,7 +1000,7 @@ cc_test( ":nearby_sharing_service", "//connections:core_types", "//internal/platform:base", - "//internal/platform:types", + "//internal/platform:comm", "//internal/platform/implementation:platform_impl", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_googletest//:gtest_main", From ab45551b7359e93087ab5a51b03fe94ae81a6c90 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 20 May 2026 11:27:34 -0700 Subject: [PATCH 104/151] Make WebRtcMedium private to mediums/webrtc. PiperOrigin-RevId: 918557620 --- .../implementation/mediums/webrtc/BUILD | 33 +++++++++++++++++-- .../mediums/webrtc/connection_flow.cc | 2 +- .../mediums/webrtc/connection_flow.h | 2 +- .../mediums/webrtc/connection_flow_test.cc | 3 +- .../mediums/webrtc}/fake_webrtc.cc | 10 ++++-- .../mediums/webrtc}/fake_webrtc.h | 14 ++++---- .../implementation/mediums/webrtc}/webrtc.h | 24 ++++++-------- .../mediums/webrtc/webrtc_impl.cc | 2 +- .../mediums/webrtc/webrtc_impl.h | 2 +- .../mediums/webrtc/webrtc_impl_test.cc | 5 +-- internal/platform/BUILD | 3 -- internal/platform/implementation/g3/wifi.h | 3 ++ .../platform/implementation/windows/BUILD | 6 ---- internal/test/BUILD | 1 - 14 files changed, 68 insertions(+), 42 deletions(-) rename {internal/test => connections/implementation/mediums/webrtc}/fake_webrtc.cc (78%) rename {internal/test => connections/implementation/mediums/webrtc}/fake_webrtc.h (78%) rename {internal/platform => connections/implementation/mediums/webrtc}/webrtc.h (89%) diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index 26c8f243..23dfffce 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -38,6 +38,7 @@ cc_library( hdrs = ["connection_flow.h"], deps = [ ":webrtc", + ":webrtc_medium", ":webrtc_socket_impl", "//connections/implementation/mediums:webrtc_socket", "//internal/platform:base", @@ -87,6 +88,19 @@ cc_library( ], ) +cc_library( + name = "webrtc_medium", + hdrs = ["webrtc.h"], + deps = [ + "//internal/platform:base", + "//internal/platform/implementation:comm", + "//internal/platform/implementation:platform", + # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", + "@com_google_absl//absl/strings:string_view", + ], +) + cc_library( name = "webrtc_impl", srcs = ["webrtc_impl.cc"], @@ -98,6 +112,7 @@ cc_library( ":connection_flow", ":signaling_frames", ":webrtc", + ":webrtc_medium", "//connections/implementation/mediums:webrtc", "//connections/implementation/mediums:webrtc_peer_id", "//connections/implementation/mediums:webrtc_socket", @@ -117,6 +132,18 @@ cc_library( ], ) +cc_library( + name = "fake_webrtc", + testonly = True, + srcs = ["fake_webrtc.cc"], + hdrs = ["fake_webrtc.h"], + deps = [ + ":webrtc_medium", + "//internal/platform:cancellation_flag", + "@com_google_absl//absl/strings:string_view", + ], +) + cc_test( name = "webrtc_test", timeout = "short", @@ -132,22 +159,24 @@ cc_test( ], deps = [ ":connection_flow", + ":fake_webrtc", ":signaling_frames", ":webrtc", ":webrtc_impl", + ":webrtc_medium", ":webrtc_socket_impl", + "//connections/implementation/mediums:webrtc", "//connections/implementation/mediums:webrtc_peer_id", "//connections/implementation/mediums:webrtc_socket", "//internal/platform:base", "//internal/platform:cancellation_flag", - "//internal/platform:comm", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation:platform_impl", - "//internal/test", # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", # "//third_party/webrtc/files/stable/webrtc/api:jsep", # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", "//third_party/webrtc/files/stable/webrtc/rtc_base:refcount", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", diff --git a/connections/implementation/mediums/webrtc/connection_flow.cc b/connections/implementation/mediums/webrtc/connection_flow.cc index 02f31b20..d8a2578d 100644 --- a/connections/implementation/mediums/webrtc/connection_flow.cc +++ b/connections/implementation/mediums/webrtc/connection_flow.cc @@ -24,13 +24,13 @@ #include "connections/implementation/mediums/webrtc/data_channel_listener.h" #include "connections/implementation/mediums/webrtc/local_ice_candidate_listener.h" #include "connections/implementation/mediums/webrtc/session_description_wrapper.h" +#include "connections/implementation/mediums/webrtc/webrtc.h" #include "connections/implementation/mediums/webrtc/webrtc_socket_impl.h" #include "internal/platform/exception.h" #include "internal/platform/future.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" #include "internal/platform/runnable.h" -#include "internal/platform/webrtc.h" #include "webrtc/api/data_channel_interface.h" #include "webrtc/api/jsep.h" #include "webrtc/api/peer_connection_interface.h" diff --git a/connections/implementation/mediums/webrtc/connection_flow.h b/connections/implementation/mediums/webrtc/connection_flow.h index b83cfe0b..01c808c1 100644 --- a/connections/implementation/mediums/webrtc/connection_flow.h +++ b/connections/implementation/mediums/webrtc/connection_flow.h @@ -24,13 +24,13 @@ #include "connections/implementation/mediums/webrtc/data_channel_listener.h" #include "connections/implementation/mediums/webrtc/local_ice_candidate_listener.h" #include "connections/implementation/mediums/webrtc/session_description_wrapper.h" +#include "connections/implementation/mediums/webrtc/webrtc.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/future.h" #include "internal/platform/listeners.h" #include "internal/platform/mutex.h" #include "internal/platform/runnable.h" -#include "internal/platform/webrtc.h" #include "webrtc/api/data_channel_interface.h" #include "webrtc/api/jsep.h" #include "webrtc/api/peer_connection_interface.h" diff --git a/connections/implementation/mediums/webrtc/connection_flow_test.cc b/connections/implementation/mediums/webrtc/connection_flow_test.cc index e08aa5ae..0145fb47 100644 --- a/connections/implementation/mediums/webrtc/connection_flow_test.cc +++ b/connections/implementation/mediums/webrtc/connection_flow_test.cc @@ -24,15 +24,16 @@ #include "connections/implementation/mediums/webrtc/data_channel_listener.h" #include "connections/implementation/mediums/webrtc/local_ice_candidate_listener.h" #include "connections/implementation/mediums/webrtc/session_description_wrapper.h" +#include "connections/implementation/mediums/webrtc/webrtc.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" #include "internal/platform/future.h" #include "internal/platform/medium_environment.h" -#include "internal/platform/webrtc.h" #include "webrtc/api/jsep.h" #include "webrtc/api/scoped_refptr.h" +#include "webrtc/rtc_base/network_constants.h" namespace nearby { namespace connections { diff --git a/internal/test/fake_webrtc.cc b/connections/implementation/mediums/webrtc/fake_webrtc.cc similarity index 78% rename from internal/test/fake_webrtc.cc rename to connections/implementation/mediums/webrtc/fake_webrtc.cc index e3850c86..6f829d94 100644 --- a/internal/test/fake_webrtc.cc +++ b/connections/implementation/mediums/webrtc/fake_webrtc.cc @@ -12,11 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "internal/test/fake_webrtc.h" +#include "connections/implementation/mediums/webrtc/fake_webrtc.h" #include -namespace nearby { +#include "absl/strings/string_view.h" +#include "connections/implementation/mediums/webrtc/webrtc.h" +#include "internal/platform/cancellation_flag.h" + +namespace nearby::connections::mediums { FakeWebRtcMedium::FakeWebRtcMedium(CancellationFlag* flag) : WebRtcMedium(), flag_(flag) {} @@ -34,4 +38,4 @@ FakeWebRtcMedium::GetSignalingMessenger( return WebRtcMedium::GetSignalingMessenger(self_id, location_hint); } -} // namespace nearby +} // namespace nearby::connections::mediums diff --git a/internal/test/fake_webrtc.h b/connections/implementation/mediums/webrtc/fake_webrtc.h similarity index 78% rename from internal/test/fake_webrtc.h rename to connections/implementation/mediums/webrtc/fake_webrtc.h index b1f54c5c..65f9e3f5 100644 --- a/internal/test/fake_webrtc.h +++ b/connections/implementation/mediums/webrtc/fake_webrtc.h @@ -12,14 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_WEBRTC_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_WEBRTC_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_FAKE_WEBRTC_H_ +#define CORE_INTERNAL_MEDIUMS_WEBRTC_FAKE_WEBRTC_H_ #include -#include "internal/platform/webrtc.h" +#include "absl/strings/string_view.h" +#include "connections/implementation/mediums/webrtc/webrtc.h" +#include "internal/platform/cancellation_flag.h" -namespace nearby { +namespace nearby::connections::mediums { class FakeWebRtcMedium : public WebRtcMedium { public: @@ -48,6 +50,6 @@ class FakeWebRtcMedium : public WebRtcMedium { bool cancel_during_get_signaling_messenger_ = false; }; -} // namespace nearby +} // namespace nearby::connections::mediums -#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_WEBRTC_H_ +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_FAKE_WEBRTC_H_ diff --git a/internal/platform/webrtc.h b/connections/implementation/mediums/webrtc/webrtc.h similarity index 89% rename from internal/platform/webrtc.h rename to connections/implementation/mediums/webrtc/webrtc.h index 1eef3d26..adccaa55 100644 --- a/internal/platform/webrtc.h +++ b/connections/implementation/mediums/webrtc/webrtc.h @@ -12,10 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef PLATFORM_PUBLIC_WEBRTC_H_ -#define PLATFORM_PUBLIC_WEBRTC_H_ - -#ifndef NO_WEBRTC +#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_H_ +#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_H_ #include #include @@ -28,8 +26,9 @@ #include "internal/platform/implementation/platform.h" #include "internal/platform/implementation/webrtc.h" #include "webrtc/api/peer_connection_interface.h" +#include "webrtc/rtc_base/network_constants.h" -namespace nearby { +namespace nearby::connections::mediums { class WebRtcSignalingMessenger { public: @@ -67,11 +66,9 @@ class WebRtcSignalingMessenger { class WebRtcMedium { public: - using PeerConnectionCallback = api::WebRtcMedium::PeerConnectionCallback; - WebRtcMedium() : impl_(api::ImplementationPlatform::CreateWebRtcMedium()) {} virtual ~WebRtcMedium() = default; - WebRtcMedium(WebRtcMedium&&) = delete; + WebRtcMedium(WebRtcMedium&&) = default; WebRtcMedium& operator=(WebRtcMedium&&) = delete; // Gets the default two-letter country code associated with current locale. @@ -84,8 +81,9 @@ class WebRtcMedium { // Creates and returns a new webrtc::PeerConnectionInterface object via // |callback|. - void CreatePeerConnection(webrtc::PeerConnectionObserver* observer, - PeerConnectionCallback callback) { + void CreatePeerConnection( + webrtc::PeerConnectionObserver* observer, + api::WebRtcMedium::PeerConnectionCallback callback) { if (FeatureFlags::GetInstance() .GetFlags() .support_web_rtc_non_cellular_medium && non_cellular_) { @@ -112,8 +110,6 @@ class WebRtcMedium { bool non_cellular_ = false; }; -} // namespace nearby +} // namespace nearby::connections::mediums -#endif - -#endif // PLATFORM_PUBLIC_WEBRTC_H_ +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.cc b/connections/implementation/mediums/webrtc/webrtc_impl.cc index 85202f7c..b7487bf7 100644 --- a/connections/implementation/mediums/webrtc/webrtc_impl.cc +++ b/connections/implementation/mediums/webrtc/webrtc_impl.cc @@ -26,6 +26,7 @@ #include "connections/implementation/mediums/webrtc/connection_flow.h" #include "connections/implementation/mediums/webrtc/session_description_wrapper.h" #include "connections/implementation/mediums/webrtc/signaling_frames.h" +#include "connections/implementation/mediums/webrtc/webrtc.h" #include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "internal/platform/byte_array.h" @@ -39,7 +40,6 @@ #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" #include "internal/platform/runnable.h" -#include "internal/platform/webrtc.h" #include "webrtc/api/jsep.h" #include "webrtc/rtc_base/network_constants.h" diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.h b/connections/implementation/mediums/webrtc/webrtc_impl.h index 349581bd..b4ec12fb 100644 --- a/connections/implementation/mediums/webrtc/webrtc_impl.h +++ b/connections/implementation/mediums/webrtc/webrtc_impl.h @@ -25,6 +25,7 @@ #include "connections/implementation/mediums/webrtc.h" #include "connections/implementation/mediums/webrtc/connection_flow.h" #include "connections/implementation/mediums/webrtc/session_description_wrapper.h" +#include "connections/implementation/mediums/webrtc/webrtc.h" #include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "internal/platform/byte_array.h" @@ -35,7 +36,6 @@ #include "internal/platform/mutex.h" #include "internal/platform/runnable.h" #include "internal/platform/scheduled_executor.h" -#include "internal/platform/webrtc.h" #include "proto/mediums/web_rtc_signaling_frames.pb.h" #include "webrtc/api/jsep.h" #include "webrtc/rtc_base/network_constants.h" diff --git a/connections/implementation/mediums/webrtc/webrtc_impl_test.cc b/connections/implementation/mediums/webrtc/webrtc_impl_test.cc index ce58c3ff..6b50243b 100644 --- a/connections/implementation/mediums/webrtc/webrtc_impl_test.cc +++ b/connections/implementation/mediums/webrtc/webrtc_impl_test.cc @@ -22,6 +22,9 @@ #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/strings/string_view.h" +#include "connections/implementation/mediums/webrtc.h" +#include "connections/implementation/mediums/webrtc/fake_webrtc.h" +#include "connections/implementation/mediums/webrtc/webrtc.h" #include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "internal/platform/byte_array.h" @@ -31,8 +34,6 @@ #include "internal/platform/feature_flags.h" #include "internal/platform/future.h" #include "internal/platform/medium_environment.h" -#include "internal/platform/webrtc.h" -#include "internal/test/fake_webrtc.h" namespace nearby { namespace connections { diff --git a/internal/platform/BUILD b/internal/platform/BUILD index c7d13d0f..e293cc42 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -335,7 +335,6 @@ cc_library( "bluetooth_classic.h", "credential_storage_impl.h", "file.h", - "webrtc.h", "wifi.h", "wifi_direct.h", "wifi_hotspot.h", @@ -365,8 +364,6 @@ cc_library( "//internal/platform/implementation:platform", "//internal/platform/implementation:types", "//internal/platform/implementation:wifi_utils", - # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep - # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", diff --git a/internal/platform/implementation/g3/wifi.h b/internal/platform/implementation/g3/wifi.h index f1439ace..48e287b6 100644 --- a/internal/platform/implementation/g3/wifi.h +++ b/internal/platform/implementation/g3/wifi.h @@ -17,6 +17,9 @@ #include +#include "absl/base/thread_annotations.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" #include "absl/synchronization/mutex.h" #include "internal/platform/implementation/wifi.h" #include "internal/platform/medium_environment.h" diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 90b7528c..077a83b7 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -363,12 +363,6 @@ cc_library( "//internal/platform/implementation/shared:count_down_latch", "//internal/platform/implementation/windows/generated:types", "//third_party/intel/pie", - # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", - # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", - # "//third_party/webrtc/files/stable/webrtc/api:rtc_error", - # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", - "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/base:nullability", "@com_google_absl//absl/container:flat_hash_map", diff --git a/internal/test/BUILD b/internal/test/BUILD index 589e9f35..7046cd8d 100644 --- a/internal/test/BUILD +++ b/internal/test/BUILD @@ -42,7 +42,6 @@ cc_library( "//internal/base:file_path", "//internal/base:files", "//internal/network:types", - "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:types", "//internal/platform/implementation:types", From bc4cb39dc583d3a190da25e34aad13b182c13f61 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 20 May 2026 18:22:45 -0700 Subject: [PATCH 105/151] Move BwuHandler impls into mediums. PiperOrigin-RevId: 918751107 --- Package.swift | 30 +-- connections/BUILD | 2 + connections/implementation/BUILD | 250 +++++++++++------- connections/implementation/bwu_manager.cc | 14 +- connections/implementation/fuzzers/BUILD | 2 +- connections/implementation/mediums/BUILD | 81 +++++- .../{ => mediums}/awdl_bwu_handler.cc | 4 +- .../{ => mediums}/awdl_bwu_handler.h | 7 +- .../{ => mediums}/awdl_bwu_handler_test.cc | 4 +- .../{ => mediums}/awdl_endpoint_channel.cc | 2 +- .../{ => mediums}/awdl_endpoint_channel.h | 7 +- .../{ => mediums}/ble_endpoint_channel.cc | 2 +- .../{ => mediums}/ble_endpoint_channel.h | 6 +- .../ble_l2cap_endpoint_channel.cc | 4 +- .../ble_l2cap_endpoint_channel.h | 6 +- .../{ => mediums}/bluetooth_bwu_handler.cc | 4 +- .../{ => mediums}/bluetooth_bwu_handler.h | 6 +- .../bluetooth_bwu_handler_test.cc} | 3 +- .../bluetooth_endpoint_channel.cc | 2 +- .../bluetooth_endpoint_channel.h | 6 +- .../{ => mediums}/webrtc_bwu_handler.cc | 4 +- .../{ => mediums}/webrtc_bwu_handler.h | 6 +- .../{ => mediums}/webrtc_bwu_handler_stub.cc | 12 +- .../{ => mediums}/webrtc_bwu_handler_stub.h | 6 +- .../{ => mediums}/webrtc_endpoint_channel.cc | 2 +- .../{ => mediums}/webrtc_endpoint_channel.h | 6 +- .../{ => mediums}/wifi_direct_bwu_handler.cc | 4 +- .../{ => mediums}/wifi_direct_bwu_handler.h | 6 +- .../wifi_direct_bwu_handler_test.cc} | 3 +- .../wifi_direct_endpoint_channel.cc | 2 +- .../wifi_direct_endpoint_channel.h | 7 +- .../{ => mediums}/wifi_hotspot_bwu_handler.cc | 4 +- .../{ => mediums}/wifi_hotspot_bwu_handler.h | 6 +- .../wifi_hotspot_bwu_handler_test.cc} | 3 +- .../wifi_hotspot_endpoint_channel.cc | 2 +- .../wifi_hotspot_endpoint_channel.h | 7 +- .../{ => mediums}/wifi_lan_bwu_handler.cc | 4 +- .../{ => mediums}/wifi_lan_bwu_handler.h | 6 +- .../wifi_lan_bwu_handler_test.cc | 2 +- .../wifi_lan_endpoint_channel.cc | 2 +- .../{ => mediums}/wifi_lan_endpoint_channel.h | 6 +- .../implementation/p2p_cluster_pcp_handler.cc | 10 +- 42 files changed, 352 insertions(+), 200 deletions(-) rename connections/implementation/{ => mediums}/awdl_bwu_handler.cc (98%) rename connections/implementation/{ => mediums}/awdl_bwu_handler.h (95%) rename connections/implementation/{ => mediums}/awdl_bwu_handler_test.cc (99%) rename connections/implementation/{ => mediums}/awdl_endpoint_channel.cc (97%) rename connections/implementation/{ => mediums}/awdl_endpoint_channel.h (88%) rename connections/implementation/{ => mediums}/ble_endpoint_channel.cc (98%) rename connections/implementation/{ => mediums}/ble_endpoint_channel.h (91%) rename connections/implementation/{ => mediums}/ble_l2cap_endpoint_channel.cc (98%) rename connections/implementation/{ => mediums}/ble_l2cap_endpoint_channel.h (91%) rename connections/implementation/{ => mediums}/bluetooth_bwu_handler.cc (98%) rename connections/implementation/{ => mediums}/bluetooth_bwu_handler.h (94%) rename connections/implementation/{bluetooth_bwu_test.cc => mediums/bluetooth_bwu_handler_test.cc} (98%) rename connections/implementation/{ => mediums}/bluetooth_endpoint_channel.cc (97%) rename connections/implementation/{ => mediums}/bluetooth_endpoint_channel.h (88%) rename connections/implementation/{ => mediums}/webrtc_bwu_handler.cc (98%) rename connections/implementation/{ => mediums}/webrtc_bwu_handler.h (94%) rename connections/implementation/{ => mediums}/webrtc_bwu_handler_stub.cc (89%) rename connections/implementation/{ => mediums}/webrtc_bwu_handler_stub.h (94%) rename connections/implementation/{ => mediums}/webrtc_endpoint_channel.cc (95%) rename connections/implementation/{ => mediums}/webrtc_endpoint_channel.h (88%) rename connections/implementation/{ => mediums}/wifi_direct_bwu_handler.cc (98%) rename connections/implementation/{ => mediums}/wifi_direct_bwu_handler.h (95%) rename connections/implementation/{wifi_direct_bwu_test.cc => mediums/wifi_direct_bwu_handler_test.cc} (98%) rename connections/implementation/{ => mediums}/wifi_direct_endpoint_channel.cc (95%) rename connections/implementation/{ => mediums}/wifi_direct_endpoint_channel.h (89%) rename connections/implementation/{ => mediums}/wifi_hotspot_bwu_handler.cc (98%) rename connections/implementation/{ => mediums}/wifi_hotspot_bwu_handler.h (94%) rename connections/implementation/{wifi_hotspot_bwu_test.cc => mediums/wifi_hotspot_bwu_handler_test.cc} (98%) rename connections/implementation/{ => mediums}/wifi_hotspot_endpoint_channel.cc (95%) rename connections/implementation/{ => mediums}/wifi_hotspot_endpoint_channel.h (89%) rename connections/implementation/{ => mediums}/wifi_lan_bwu_handler.cc (98%) rename connections/implementation/{ => mediums}/wifi_lan_bwu_handler.h (94%) rename connections/implementation/{ => mediums}/wifi_lan_bwu_handler_test.cc (99%) rename connections/implementation/{ => mediums}/wifi_lan_endpoint_channel.cc (96%) rename connections/implementation/{ => mediums}/wifi_lan_endpoint_channel.h (87%) diff --git a/Package.swift b/Package.swift index 54d62c41..973d26c5 100644 --- a/Package.swift +++ b/Package.swift @@ -92,7 +92,7 @@ let package = Package( .target( name: "protobuf-utf8", dependencies: [ - .product(name: "abseil", package: "abseil-cpp-SwiftPM"), + .product(name: "abseil", package: "abseil-cpp-SwiftPM") ], path: "third_party/protobuf/third_party/utf8_range", sources: [ @@ -102,13 +102,13 @@ let package = Package( ], publicHeadersPath: ".", cSettings: [ - .headerSearchPath("./"), + .headerSearchPath("./") ], ), .target( name: "protobuf", dependencies: [ - "protobuf-utf8", + "protobuf-utf8" ], path: "third_party/protobuf/src", exclude: [ @@ -282,11 +282,11 @@ let package = Package( "google/protobuf/io/zero_copy_sink_test.cc", ], sources: [ - "google/protobuf", + "google/protobuf" ], publicHeadersPath: ".", cSettings: [ - .headerSearchPath("./"), + .headerSearchPath("./") ] ), .target( @@ -368,17 +368,13 @@ let package = Package( "connections/implementation/payload_manager_test.cc", "connections/implementation/offline_frames_validator_test.cc", "connections/implementation/service_controller_router_test.cc", - "connections/implementation/awdl_bwu_handler_test.cc", - "connections/implementation/bluetooth_bwu_test.cc", - "connections/implementation/wifi_direct_bwu_test.cc", - "connections/implementation/wifi_hotspot_bwu_test.cc", - "connections/implementation/wifi_lan_bwu_handler_test.cc", "connections/implementation/analytics/analytics_recorder_test.cc", "connections/implementation/analytics/throughput_recorder_test.cc", "connections/implementation/mediums/advertisements/data_element_test.cc", "connections/implementation/mediums/advertisements/dct_advertisement_test.cc", "connections/implementation/mediums/advertisements/advertisement_util_test.cc", "connections/implementation/mediums/awdl_test.cc", + "connections/implementation/mediums/awdl_bwu_handler_test.cc", "connections/implementation/mediums/ble_test.cc", "connections/implementation/mediums/ble/bloom_filter_test.cc", "connections/implementation/mediums/ble/ble_l2cap_packet_test.cc", @@ -391,15 +387,19 @@ let package = Package( "connections/implementation/mediums/ble/discovered_peripheral_tracker_test.cc", "connections/implementation/mediums/ble/instant_on_lost_advertisement_test.cc", "connections/implementation/mediums/ble/instant_on_lost_manager_test.cc", - "connections/implementation/mediums/webrtc_peer_id_test.cc", - "connections/implementation/mediums/wifi_lan_test.cc", - "connections/implementation/mediums/bluetooth_classic_test.cc", "connections/implementation/mediums/ble_test.cc", - "connections/implementation/mediums/webrtc_test.cc", - "connections/implementation/mediums/lost_entity_tracker_test.cc", + "connections/implementation/mediums/bluetooth_bwu_handler_test.cc", + "connections/implementation/mediums/bluetooth_classic_test.cc", "connections/implementation/mediums/bluetooth_radio_test.cc", + "connections/implementation/mediums/lost_entity_tracker_test.cc", + "connections/implementation/mediums/webrtc_peer_id_test.cc", + "connections/implementation/mediums/webrtc_test.cc", + "connections/implementation/mediums/wifi_direct_bwu_handler_test.cc", "connections/implementation/mediums/wifi_direct_test.cc", + "connections/implementation/mediums/wifi_hotspot_bwu_handler_test.cc", "connections/implementation/mediums/wifi_hotspot_test.cc", + "connections/implementation/mediums/wifi_lan_bwu_handler_test.cc", + "connections/implementation/mediums/wifi_lan_test.cc", "connections/implementation/mediums/wifi_test.cc", "connections/implementation/endpoint_channel_manager_test.cc", "connections/implementation/bwu_manager_test.cc", diff --git a/connections/BUILD b/connections/BUILD index c759b732..78928b9e 100644 --- a/connections/BUILD +++ b/connections/BUILD @@ -43,7 +43,9 @@ cc_library( ], deps = [ ":core_types", + "//connections/implementation:client_proxy", "//connections/implementation:internal", + "//connections/implementation:service_id_constants", "//connections/v3:v3_types", "//internal/analytics:event_logger", "//internal/interop:device", diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 92038756..9f820647 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -49,30 +49,147 @@ cc_library( ], ) +cc_library( + name = "service_id_constants", + hdrs = ["service_id_constants.h"], + visibility = ["//connections:__subpackages__"], + deps = [ + "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:string_view", + ], +) + +cc_library( + name = "bwu_handler", + srcs = ["base_bwu_handler.cc"], + hdrs = [ + "base_bwu_handler.h", + "bwu_handler.h", + ], + visibility = ["//connections:__subpackages__"], + deps = [ + ":client_proxy", + ":endpoint_channel", + ":service_id_constants", + "//internal/platform:base", + "//internal/platform:logging", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/container:flat_hash_set", + "@com_google_absl//absl/functional:any_invocable", + ], +) + +cc_library( + name = "offline_frames", + srcs = [ + "offline_frames.cc", + "offline_frames_validator.cc", + ], + hdrs = [ + "internal_payload.h", + "offline_frames.h", + "offline_frames_validator.h", + ], + visibility = ["//connections:__subpackages__"], + deps = [ + "//connections:core_types", + "//connections/implementation/flags:connections_flags", + "//connections/implementation/proto:offline_wire_formats_cc_proto", + "//internal/flags:nearby_flags", + "//internal/platform:base", + "//internal/platform:logging", + "//internal/platform:mac_address", + "@com_google_absl//absl/strings:string_view", + "@com_google_absl//absl/time", + ], +) + +cc_library( + name = "client_proxy", + srcs = ["client_proxy.cc"], + hdrs = ["client_proxy.h"], + visibility = ["//connections:__subpackages__"], + deps = [ + "//connections:core_types", + "//connections/implementation/analytics", + "//connections/implementation/flags:connections_flags", + "//connections/implementation/mediums/advertisements:dct_advertisement", + "//connections/implementation/proto:offline_wire_formats_cc_proto", + "//connections/v3:v3_types", + "//internal/analytics:event_logger", + "//internal/base:file_path", + "//internal/base:files", + "//internal/flags:nearby_flags", + "//internal/interop:device", + "//internal/platform:base", + "//internal/platform:cancellation_flag", + "//internal/platform:error_code_recorder", + "//internal/platform:logging", + "//internal/platform:mac_address", + "//internal/platform:types", + "//internal/platform/implementation:comm", + "//internal/platform/implementation:platform", + "//internal/platform/implementation:types", + "//internal/proto/analytics:connections_log_cc_proto", + "//proto:connections_enums_cc_proto", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/container:flat_hash_set", + "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/random", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:string_view", + "@com_google_absl//absl/time", + "@com_google_absl//absl/types:span", + ], +) + +cc_library( + name = "endpoint_channel", + srcs = [ + "base_endpoint_channel.cc", + "endpoint_channel_manager.cc", + ], + hdrs = [ + "base_endpoint_channel.h", + "endpoint_channel.h", + "endpoint_channel_manager.h", + ], + visibility = ["//connections:__subpackages__"], + deps = [ + ":client_proxy", + ":offline_frames", + ":types", + "//connections:core_types", + "//connections/implementation/analytics", + "//connections/implementation/flags:connections_flags", + "//internal/flags:nearby_flags", + "//internal/platform:base", + "//internal/platform:logging", + "//internal/platform:types", + "//internal/platform/implementation:types", + "//internal/proto/analytics:connections_log_cc_proto", + "//proto:connections_enums_cc_proto", + "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:string_view", + "@com_google_absl//absl/time", + "@com_google_ukey2//:ukey2", + ], +) + cc_library( name = "internal", srcs = [ - "awdl_bwu_handler.cc", - "awdl_endpoint_channel.cc", - "base_bwu_handler.cc", - "base_endpoint_channel.cc", "base_pcp_handler.cc", - "ble_endpoint_channel.cc", - "ble_l2cap_endpoint_channel.cc", - "bluetooth_bwu_handler.cc", "bluetooth_device_name.cc", - "bluetooth_endpoint_channel.cc", "bwu_manager.cc", - "client_proxy.cc", "connections_authentication_transport.cc", "encryption_runner.cc", - "endpoint_channel_manager.cc", "endpoint_manager.cc", "injected_bluetooth_device_store.cc", "internal_payload.cc", "internal_payload_factory.cc", - "offline_frames.cc", - "offline_frames_validator.cc", "offline_service_controller.cc", "p2p_cluster_pcp_handler.cc", "p2p_point_to_point_pcp_handler.cc", @@ -80,41 +197,17 @@ cc_library( "payload_manager.cc", "pcp_manager.cc", "service_controller_router.cc", - "webrtc_bwu_handler.cc", - "webrtc_bwu_handler_stub.cc", - "webrtc_endpoint_channel.cc", - "wifi_direct_bwu_handler.cc", - "wifi_direct_endpoint_channel.cc", - "wifi_hotspot_bwu_handler.cc", - "wifi_hotspot_endpoint_channel.cc", - "wifi_lan_bwu_handler.cc", - "wifi_lan_endpoint_channel.cc", "wifi_lan_service_info.cc", ], hdrs = [ - "awdl_bwu_handler.h", - "awdl_endpoint_channel.h", - "base_bwu_handler.h", - "base_endpoint_channel.h", "base_pcp_handler.h", - "ble_endpoint_channel.h", - "ble_l2cap_endpoint_channel.h", - "bluetooth_bwu_handler.h", "bluetooth_device_name.h", - "bluetooth_endpoint_channel.h", - "bwu_handler.h", "bwu_manager.h", - "client_proxy.h", "connections_authentication_transport.h", "encryption_runner.h", - "endpoint_channel.h", - "endpoint_channel_manager.h", "endpoint_manager.h", "injected_bluetooth_device_store.h", - "internal_payload.h", "internal_payload_factory.h", - "offline_frames.h", - "offline_frames_validator.h", "offline_service_controller.h", "p2p_cluster_pcp_handler.h", "p2p_point_to_point_pcp_handler.h", @@ -124,16 +217,6 @@ cc_library( "pcp_manager.h", "service_controller.h", "service_controller_router.h", - "service_id_constants.h", - "webrtc_bwu_handler.h", - "webrtc_bwu_handler_stub.h", - "webrtc_endpoint_channel.h", - "wifi_direct_bwu_handler.h", - "wifi_direct_endpoint_channel.h", - "wifi_hotspot_bwu_handler.h", - "wifi_hotspot_endpoint_channel.h", - "wifi_lan_bwu_handler.h", - "wifi_lan_endpoint_channel.h", "wifi_lan_service_info.h", ], copts = [ @@ -149,6 +232,11 @@ cc_library( ], deps = [ ":ble_advertisement", + ":bwu_handler", + ":client_proxy", + ":endpoint_channel", + ":offline_frames", + ":service_id_constants", ":types", "//connections:core_types", "//connections/implementation/analytics", @@ -157,26 +245,19 @@ cc_library( "//connections/implementation/mediums:utils", "//connections/implementation/mediums:webrtc", "//connections/implementation/mediums:webrtc_peer_id", - "//connections/implementation/mediums:webrtc_socket", "//connections/implementation/mediums/advertisements:dct_advertisement", "//connections/implementation/mediums/advertisements:util", "//connections/implementation/mediums/ble:ble_advertisement_header", "//connections/implementation/mediums/ble:ble_socket", "//connections/implementation/proto:offline_wire_formats_cc_proto", "//connections/v3:v3_types", - "//internal/analytics:event_logger", - "//internal/base:file_path", - "//internal/base:files", - "//internal/base:masker", "//internal/flags:nearby_flags", "//internal/interop:authentication_status", "//internal/interop:authentication_transport_interface", "//internal/interop:device", "//internal/platform:base", - "//internal/platform:cancellation_flag", "//internal/platform:comm", "//internal/platform:connection_info", - "//internal/platform:error_code_recorder", "//internal/platform:logging", "//internal/platform:mac_address", "//internal/platform:types", @@ -193,7 +274,6 @@ 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/random", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", @@ -225,7 +305,11 @@ cc_library( "//connections:__subpackages__", ], deps = [ + ":bwu_handler", + ":client_proxy", + ":endpoint_channel", ":internal", + ":offline_frames", "//connections:core_types", "//connections/implementation/analytics", "//connections/implementation/flags:connections_flags", @@ -248,30 +332,26 @@ cc_library( cc_test( name = "bwu_test", srcs = [ - "awdl_bwu_handler_test.cc", "base_bwu_handler_test.cc", - "bluetooth_bwu_test.cc", "bwu_manager_test.cc", - "wifi_direct_bwu_test.cc", - "wifi_hotspot_bwu_test.cc", ], deps = [ + ":bwu_handler", + ":client_proxy", + ":endpoint_channel", ":internal", ":internal_test", + ":offline_frames", + ":service_id_constants", "//connections:core_types", "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums", - "//internal/analytics:mock_event_logger", "//internal/flags:nearby_flags", "//internal/platform:base", - "//internal/platform:cancellation_flag", - "//internal/platform:comm", "//internal/platform:logging", - "//internal/platform:mock_platform", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/flags:platform_flags", - "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", # build_cleaner: keep "//internal/platform/implementation/g3", # build_cleaner: keep "//internal/proto/analytics:connections_log_cc_proto", @@ -288,6 +368,7 @@ cc_test( name = "pcp_manager_test", srcs = ["pcp_manager_test.cc"], deps = [ + ":endpoint_channel", ":internal", ":internal_test", "//connections:core_types", @@ -313,8 +394,11 @@ cc_test( ], shard_count = 8, deps = [ + ":client_proxy", + ":endpoint_channel", ":internal", ":internal_test", + ":offline_frames", ":types", "//connections:core_types", "//connections/implementation/flags:connections_flags", @@ -370,7 +454,7 @@ cc_test( name = "offline_frames_test", srcs = ["offline_frames_validator_test.cc"], deps = [ - ":internal", + ":offline_frames", "//connections:core_types", "//connections/implementation/flags:connections_flags", "//connections/implementation/proto:offline_wire_formats_cc_proto", @@ -390,8 +474,7 @@ cc_test( "client_proxy_test.cc", ], deps = [ - ":internal", - "//base:casts", + ":client_proxy", "//connections:core_types", "//connections/implementation/flags:connections_flags", "//connections/v3:v3_types", @@ -419,6 +502,8 @@ cc_test( "encryption_runner_test.cc", ], deps = [ + ":client_proxy", + ":endpoint_channel", ":internal", "//connections/implementation/analytics", "//internal/platform:base", @@ -440,8 +525,11 @@ cc_test( "endpoint_manager_test.cc", ], deps = [ + ":client_proxy", + ":endpoint_channel", ":internal", ":internal_test", + ":offline_frames", "//connections:core_types", "//connections/implementation/flags:connections_flags", "//internal/flags:nearby_flags", @@ -467,7 +555,10 @@ cc_test( "endpoint_channel_manager_test.cc", ], deps = [ + ":client_proxy", + ":endpoint_channel", ":internal", + ":offline_frames", "//connections/implementation/flags:connections_flags", "//internal/flags:nearby_flags", "//internal/platform:base", @@ -509,8 +600,8 @@ cc_test( deps = [ ":internal", ":internal_test", + ":offline_frames", "//connections:core_types", - "//connections/implementation/analytics", "//internal/platform:base", "//internal/platform:logging", "//internal/platform:test_util", @@ -531,6 +622,7 @@ cc_test( "service_controller_router_test.cc", ], deps = [ + ":client_proxy", ":internal", ":internal_test", "//connections:core_types", @@ -581,6 +673,7 @@ cc_test( ], deps = [ ":internal", + ":offline_frames", "//connections:core_types", "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/platform:base", @@ -593,26 +686,3 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) - -cc_test( - name = "wifi_lan_bwu_handler_test", - srcs = [ - "wifi_lan_bwu_handler_test.cc", - ], - 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/bwu_manager.cc b/connections/implementation/bwu_manager.cc index d43a2329..a1082763 100644 --- a/connections/implementation/bwu_manager.cc +++ b/connections/implementation/bwu_manager.cc @@ -26,26 +26,26 @@ #include "absl/strings/str_cat.h" #include "absl/time/time.h" #include "connections/implementation/analytics/connection_attempt_metadata_params.h" -#include "connections/implementation/awdl_bwu_handler.h" -#include "connections/implementation/bluetooth_bwu_handler.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #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/awdl_bwu_handler.h" +#include "connections/implementation/mediums/bluetooth_bwu_handler.h" #include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/mediums/wifi_lan_bwu_handler.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" +#include "connections/implementation/mediums/webrtc_bwu_handler_stub.h" #else -#include "connections/implementation/webrtc_bwu_handler.h" +#include "connections/implementation/mediums/webrtc_bwu_handler.h" #endif -#include "connections/implementation/wifi_direct_bwu_handler.h" -#include "connections/implementation/wifi_hotspot_bwu_handler.h" -#include "connections/implementation/wifi_lan_bwu_handler.h" +#include "connections/implementation/mediums/wifi_direct_bwu_handler.h" +#include "connections/implementation/mediums/wifi_hotspot_bwu_handler.h" #include "connections/medium_selector.h" #include "internal/platform/cancelable_alarm.h" #include "internal/platform/count_down_latch.h" diff --git a/connections/implementation/fuzzers/BUILD b/connections/implementation/fuzzers/BUILD index 2d0c0629..490dac2f 100644 --- a/connections/implementation/fuzzers/BUILD +++ b/connections/implementation/fuzzers/BUILD @@ -24,7 +24,7 @@ cc_test( ], tags = ["componentid:148515"], deps = [ - "//connections/implementation:internal", + "//connections/implementation:offline_frames", "//internal/platform/implementation/g3", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index d5c8189f..e10be0fe 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -21,24 +21,54 @@ cc_library( name = "mediums", srcs = [ "awdl.cc", + "awdl_bwu_handler.cc", + "awdl_endpoint_channel.cc", "ble.cc", + "ble_endpoint_channel.cc", + "ble_l2cap_endpoint_channel.cc", + "bluetooth_bwu_handler.cc", "bluetooth_classic.cc", + "bluetooth_endpoint_channel.cc", "bluetooth_radio.cc", "mediums.cc", + "webrtc_bwu_handler.cc", + "webrtc_bwu_handler_stub.cc", + "webrtc_endpoint_channel.cc", "wifi_direct.cc", + "wifi_direct_bwu_handler.cc", + "wifi_direct_endpoint_channel.cc", "wifi_hotspot.cc", + "wifi_hotspot_bwu_handler.cc", + "wifi_hotspot_endpoint_channel.cc", "wifi_lan.cc", + "wifi_lan_bwu_handler.cc", + "wifi_lan_endpoint_channel.cc", ], hdrs = [ "awdl.h", + "awdl_bwu_handler.h", + "awdl_endpoint_channel.h", "ble.h", + "ble_endpoint_channel.h", + "ble_l2cap_endpoint_channel.h", + "bluetooth_bwu_handler.h", "bluetooth_classic.h", + "bluetooth_endpoint_channel.h", "bluetooth_radio.h", "mediums.h", + "webrtc_bwu_handler.h", + "webrtc_bwu_handler_stub.h", + "webrtc_endpoint_channel.h", "wifi.h", "wifi_direct.h", + "wifi_direct_bwu_handler.h", + "wifi_direct_endpoint_channel.h", "wifi_hotspot.h", + "wifi_hotspot_bwu_handler.h", + "wifi_hotspot_endpoint_channel.h", "wifi_lan.h", + "wifi_lan_bwu_handler.h", + "wifi_lan_endpoint_channel.h", ], copts = ["-DNO_WEBRTC"], local_defines = select({ @@ -51,13 +81,22 @@ cc_library( deps = [ ":utils", ":webrtc", + ":webrtc_peer_id", + ":webrtc_socket", "//connections:core_types", + "//connections/implementation:bwu_handler", + "//connections/implementation:client_proxy", + "//connections/implementation:endpoint_channel", + "//connections/implementation:offline_frames", + "//connections/implementation:service_id_constants", "//connections/implementation:types", "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums/ble", "//connections/implementation/mediums/ble:ble_advertisement_header", "//connections/implementation/mediums/ble:ble_socket", "//connections/implementation/mediums/ble:bloom_filter", + "//connections/implementation/proto:offline_wire_formats_cc_proto", + "//internal/base:masker", "//internal/flags:nearby_flags", "//internal/platform:base", "//internal/platform:cancellation_flag", @@ -69,11 +108,13 @@ cc_library( "//internal/platform/flags:platform_flags", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", + "//internal/platform/implementation:wifi_utils", "@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", "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/functional:bind_front", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", @@ -191,13 +232,51 @@ cc_test( "//internal/platform/implementation:types", "//internal/platform/implementation/g3", # build_cleaner: keep "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/strings", "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], ) +cc_test( + name = "bwu_handler_test", + size = "small", + srcs = [ + "awdl_bwu_handler_test.cc", + "bluetooth_bwu_handler_test.cc", + "wifi_direct_bwu_handler_test.cc", + "wifi_hotspot_bwu_handler_test.cc", + "wifi_lan_bwu_handler_test.cc", + ], + deps = [ + ":mediums", + "//connections:core_types", + "//connections/implementation:bwu_handler", + "//connections/implementation:client_proxy", + "//connections/implementation:endpoint_channel", + "//connections/implementation:offline_frames", + "//connections/implementation/flags:connections_flags", + "//internal/analytics:mock_event_logger", + "//internal/flags:nearby_flags", + "//internal/platform:base", + "//internal/platform:cancellation_flag", + "//internal/platform:comm", + "//internal/platform:logging", + "//internal/platform:mock_platform", + "//internal/platform:test_util", + "//internal/platform:types", + "//internal/platform/flags:platform_flags", + "//internal/platform/implementation:comm", + "//internal/platform/implementation:platform", + "//internal/platform/implementation/g3", # build_cleaner: keep + "//internal/proto/analytics:connections_log_cc_proto", + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_absl//absl/strings:string_view", + "@com_google_absl//absl/time", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "core_internal_mediums_webrtc_test", size = "small", diff --git a/connections/implementation/awdl_bwu_handler.cc b/connections/implementation/mediums/awdl_bwu_handler.cc similarity index 98% rename from connections/implementation/awdl_bwu_handler.cc rename to connections/implementation/mediums/awdl_bwu_handler.cc index da96bc0c..6aa9bca5 100644 --- a/connections/implementation/awdl_bwu_handler.cc +++ b/connections/implementation/mediums/awdl_bwu_handler.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/awdl_bwu_handler.h" +#include "connections/implementation/mediums/awdl_bwu_handler.h" #include #include @@ -23,11 +23,11 @@ #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" -#include "connections/implementation/awdl_endpoint_channel.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/awdl.h" +#include "connections/implementation/mediums/awdl_endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/utils.h" #include "connections/implementation/offline_frames.h" diff --git a/connections/implementation/awdl_bwu_handler.h b/connections/implementation/mediums/awdl_bwu_handler.h similarity index 95% rename from connections/implementation/awdl_bwu_handler.h rename to connections/implementation/mediums/awdl_bwu_handler.h index 1a42a844..c3c27985 100644 --- a/connections/implementation/awdl_bwu_handler.h +++ b/connections/implementation/mediums/awdl_bwu_handler.h @@ -12,12 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_AWDL_BWU_HANDLER_H_ -#define CORE_INTERNAL_AWDL_BWU_HANDLER_H_ +#ifndef CORE_INTERNAL_MEDIUMS_AWDL_BWU_HANDLER_H_ +#define CORE_INTERNAL_MEDIUMS_AWDL_BWU_HANDLER_H_ #include #include -#include #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/bwu_handler.h" @@ -89,4 +88,4 @@ class AwdlBwuHandler : public BaseBwuHandler { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_AWDL_BWU_HANDLER_H_ +#endif // CORE_INTERNAL_MEDIUMS_AWDL_BWU_HANDLER_H_ diff --git a/connections/implementation/awdl_bwu_handler_test.cc b/connections/implementation/mediums/awdl_bwu_handler_test.cc similarity index 99% rename from connections/implementation/awdl_bwu_handler_test.cc rename to connections/implementation/mediums/awdl_bwu_handler_test.cc index 3fdba73a..2908cf25 100644 --- a/connections/implementation/awdl_bwu_handler_test.cc +++ b/connections/implementation/mediums/awdl_bwu_handler_test.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/awdl_bwu_handler.h" +#include "connections/implementation/mediums/awdl_bwu_handler.h" #include #include @@ -26,10 +26,10 @@ #include "absl/strings/string_view.h" #include "absl/time/clock.h" #include "absl/time/time.h" -#include "connections/implementation/awdl_endpoint_channel.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/mediums/awdl.h" +#include "connections/implementation/mediums/awdl_endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" #include "connections/strategy.h" #include "internal/analytics/mock_event_logger.h" diff --git a/connections/implementation/awdl_endpoint_channel.cc b/connections/implementation/mediums/awdl_endpoint_channel.cc similarity index 97% rename from connections/implementation/awdl_endpoint_channel.cc rename to connections/implementation/mediums/awdl_endpoint_channel.cc index 74ac3564..46cac068 100644 --- a/connections/implementation/awdl_endpoint_channel.cc +++ b/connections/implementation/mediums/awdl_endpoint_channel.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/awdl_endpoint_channel.h" +#include "connections/implementation/mediums/awdl_endpoint_channel.h" #include #include diff --git a/connections/implementation/awdl_endpoint_channel.h b/connections/implementation/mediums/awdl_endpoint_channel.h similarity index 88% rename from connections/implementation/awdl_endpoint_channel.h rename to connections/implementation/mediums/awdl_endpoint_channel.h index 1cd8da5b..ff22735a 100644 --- a/connections/implementation/awdl_endpoint_channel.h +++ b/connections/implementation/mediums/awdl_endpoint_channel.h @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_AWDL_ENDPOINT_CHANNEL_H_ -#define CORE_INTERNAL_AWDL_ENDPOINT_CHANNEL_H_ +#ifndef CORE_INTERNAL_MEDIUMS_AWDL_ENDPOINT_CHANNEL_H_ +#define CORE_INTERNAL_MEDIUMS_AWDL_ENDPOINT_CHANNEL_H_ #include #include "connections/implementation/base_endpoint_channel.h" #include "connections/implementation/mediums/awdl.h" +#include "internal/platform/awdl.h" namespace nearby { namespace connections { @@ -48,4 +49,4 @@ class AwdlEndpointChannel final : public BaseEndpointChannel { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_AWDL_ENDPOINT_CHANNEL_H_ +#endif // CORE_INTERNAL_MEDIUMS_AWDL_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/ble_endpoint_channel.cc b/connections/implementation/mediums/ble_endpoint_channel.cc similarity index 98% rename from connections/implementation/ble_endpoint_channel.cc rename to connections/implementation/mediums/ble_endpoint_channel.cc index 4146b7ac..a261ab89 100644 --- a/connections/implementation/ble_endpoint_channel.cc +++ b/connections/implementation/mediums/ble_endpoint_channel.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/ble_endpoint_channel.h" +#include "connections/implementation/mediums/ble_endpoint_channel.h" #include #include diff --git a/connections/implementation/ble_endpoint_channel.h b/connections/implementation/mediums/ble_endpoint_channel.h similarity index 91% rename from connections/implementation/ble_endpoint_channel.h rename to connections/implementation/mediums/ble_endpoint_channel.h index 7ad7fc4e..82805a98 100644 --- a/connections/implementation/ble_endpoint_channel.h +++ b/connections/implementation/mediums/ble_endpoint_channel.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CONNECTIONS_IMPLEMENTATION_BLE_ENDPOINT_CHANNEL_H_ -#define CONNECTIONS_IMPLEMENTATION_BLE_ENDPOINT_CHANNEL_H_ +#ifndef CORE_INTERNAL_MEDIUMS_BLE_ENDPOINT_CHANNEL_H_ +#define CORE_INTERNAL_MEDIUMS_BLE_ENDPOINT_CHANNEL_H_ #include #include @@ -57,4 +57,4 @@ class BleEndpointChannel final : public BaseEndpointChannel { } // namespace connections } // namespace nearby -#endif // CONNECTIONS_IMPLEMENTATION_BLE_ENDPOINT_CHANNEL_H_ +#endif // CORE_INTERNAL_MEDIUMS_BLE_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/ble_l2cap_endpoint_channel.cc b/connections/implementation/mediums/ble_l2cap_endpoint_channel.cc similarity index 98% rename from connections/implementation/ble_l2cap_endpoint_channel.cc rename to connections/implementation/mediums/ble_l2cap_endpoint_channel.cc index 33056d69..6f92010e 100644 --- a/connections/implementation/ble_l2cap_endpoint_channel.cc +++ b/connections/implementation/mediums/ble_l2cap_endpoint_channel.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/ble_l2cap_endpoint_channel.h" +#include "connections/implementation/mediums/ble_l2cap_endpoint_channel.h" #include #include @@ -22,11 +22,11 @@ #include "connections/implementation/base_endpoint_channel.h" #include "connections/implementation/mediums/ble/ble_socket.h" #include "internal/platform/ble.h" +#include "internal/platform/byte_array.h" #include "internal/platform/exception.h" #include "internal/platform/input_stream.h" #include "internal/platform/logging.h" #include "internal/platform/output_stream.h" -#include "internal/platform/byte_array.h" namespace nearby { namespace connections { diff --git a/connections/implementation/ble_l2cap_endpoint_channel.h b/connections/implementation/mediums/ble_l2cap_endpoint_channel.h similarity index 91% rename from connections/implementation/ble_l2cap_endpoint_channel.h rename to connections/implementation/mediums/ble_l2cap_endpoint_channel.h index 292d67ea..00b84c8b 100644 --- a/connections/implementation/ble_l2cap_endpoint_channel.h +++ b/connections/implementation/mediums/ble_l2cap_endpoint_channel.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_BLE_L2CAP_ENDPOINT_CHANNEL_H_ -#define CORE_INTERNAL_BLE_L2CAP_ENDPOINT_CHANNEL_H_ +#ifndef CORE_INTERNAL_MEDIUMS_BLE_L2CAP_ENDPOINT_CHANNEL_H_ +#define CORE_INTERNAL_MEDIUMS_BLE_L2CAP_ENDPOINT_CHANNEL_H_ #include #include @@ -60,4 +60,4 @@ class BleL2capEndpointChannel final : public BaseEndpointChannel { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_BLE_L2CAP_ENDPOINT_CHANNEL_H_ +#endif // CORE_INTERNAL_MEDIUMS_BLE_L2CAP_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/bluetooth_bwu_handler.cc b/connections/implementation/mediums/bluetooth_bwu_handler.cc similarity index 98% rename from connections/implementation/bluetooth_bwu_handler.cc rename to connections/implementation/mediums/bluetooth_bwu_handler.cc index 00c059a9..f2643049 100644 --- a/connections/implementation/bluetooth_bwu_handler.cc +++ b/connections/implementation/mediums/bluetooth_bwu_handler.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/bluetooth_bwu_handler.h" +#include "connections/implementation/mediums/bluetooth_bwu_handler.h" #include #include @@ -20,9 +20,9 @@ #include "absl/functional/bind_front.h" #include "connections/implementation/base_bwu_handler.h" -#include "connections/implementation/bluetooth_endpoint_channel.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" +#include "connections/implementation/mediums/bluetooth_endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/offline_frames.h" #include "internal/platform/bluetooth_adapter.h" diff --git a/connections/implementation/bluetooth_bwu_handler.h b/connections/implementation/mediums/bluetooth_bwu_handler.h similarity index 94% rename from connections/implementation/bluetooth_bwu_handler.h rename to connections/implementation/mediums/bluetooth_bwu_handler.h index b468a54a..3c1a7b10 100644 --- a/connections/implementation/bluetooth_bwu_handler.h +++ b/connections/implementation/mediums/bluetooth_bwu_handler.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_BLUETOOTH_BWU_HANDLER_H_ -#define CORE_INTERNAL_BLUETOOTH_BWU_HANDLER_H_ +#ifndef CORE_INTERNAL_MEDIUMS_BLUETOOTH_BWU_HANDLER_H_ +#define CORE_INTERNAL_MEDIUMS_BLUETOOTH_BWU_HANDLER_H_ #include #include @@ -83,4 +83,4 @@ class BluetoothBwuHandler : public BaseBwuHandler { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_BLUETOOTH_BWU_HANDLER_H_ +#endif // CORE_INTERNAL_MEDIUMS_BLUETOOTH_BWU_HANDLER_H_ diff --git a/connections/implementation/bluetooth_bwu_test.cc b/connections/implementation/mediums/bluetooth_bwu_handler_test.cc similarity index 98% rename from connections/implementation/bluetooth_bwu_test.cc rename to connections/implementation/mediums/bluetooth_bwu_handler_test.cc index 52ad5fe5..2144ed9d 100644 --- a/connections/implementation/bluetooth_bwu_test.cc +++ b/connections/implementation/mediums/bluetooth_bwu_handler_test.cc @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "connections/implementation/mediums/bluetooth_bwu_handler.h" + #include #include #include #include "gtest/gtest.h" #include "absl/time/time.h" -#include "connections/implementation/bluetooth_bwu_handler.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" diff --git a/connections/implementation/bluetooth_endpoint_channel.cc b/connections/implementation/mediums/bluetooth_endpoint_channel.cc similarity index 97% rename from connections/implementation/bluetooth_endpoint_channel.cc rename to connections/implementation/mediums/bluetooth_endpoint_channel.cc index 73d09d9c..643a65c7 100644 --- a/connections/implementation/bluetooth_endpoint_channel.cc +++ b/connections/implementation/mediums/bluetooth_endpoint_channel.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/bluetooth_endpoint_channel.h" +#include "connections/implementation/mediums/bluetooth_endpoint_channel.h" #include #include diff --git a/connections/implementation/bluetooth_endpoint_channel.h b/connections/implementation/mediums/bluetooth_endpoint_channel.h similarity index 88% rename from connections/implementation/bluetooth_endpoint_channel.h rename to connections/implementation/mediums/bluetooth_endpoint_channel.h index b2176388..a28a7cdf 100644 --- a/connections/implementation/bluetooth_endpoint_channel.h +++ b/connections/implementation/mediums/bluetooth_endpoint_channel.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_BLUETOOTH_ENDPOINT_CHANNEL_H_ -#define CORE_INTERNAL_BLUETOOTH_ENDPOINT_CHANNEL_H_ +#ifndef CORE_INTERNAL_MEDIUMS_BLUETOOTH_ENDPOINT_CHANNEL_H_ +#define CORE_INTERNAL_MEDIUMS_BLUETOOTH_ENDPOINT_CHANNEL_H_ #include @@ -46,4 +46,4 @@ class BluetoothEndpointChannel final : public BaseEndpointChannel { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_BLUETOOTH_ENDPOINT_CHANNEL_H_ +#endif // CORE_INTERNAL_MEDIUMS_BLUETOOTH_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/webrtc_bwu_handler.cc b/connections/implementation/mediums/webrtc_bwu_handler.cc similarity index 98% rename from connections/implementation/webrtc_bwu_handler.cc rename to connections/implementation/mediums/webrtc_bwu_handler.cc index 5ec2c1c0..31605073 100644 --- a/connections/implementation/webrtc_bwu_handler.cc +++ b/connections/implementation/mediums/webrtc_bwu_handler.cc @@ -14,7 +14,7 @@ #ifndef NO_WEBRTC -#include "connections/implementation/webrtc_bwu_handler.h" +#include "connections/implementation/mediums/webrtc_bwu_handler.h" #include #include @@ -25,11 +25,11 @@ #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/mediums/webrtc_endpoint_channel.h" #include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" -#include "connections/implementation/webrtc_endpoint_channel.h" #include "internal/platform/expected.h" #include "internal/platform/logging.h" diff --git a/connections/implementation/webrtc_bwu_handler.h b/connections/implementation/mediums/webrtc_bwu_handler.h similarity index 94% rename from connections/implementation/webrtc_bwu_handler.h rename to connections/implementation/mediums/webrtc_bwu_handler.h index c4918ad2..725486ff 100644 --- a/connections/implementation/webrtc_bwu_handler.h +++ b/connections/implementation/mediums/webrtc_bwu_handler.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_WEBRTC_BWU_HANDLER_H_ -#define CORE_INTERNAL_WEBRTC_BWU_HANDLER_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_H_ +#define CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_H_ #ifndef NO_WEBRTC @@ -87,4 +87,4 @@ class WebrtcBwuHandler : public BaseBwuHandler { #endif -#endif // CORE_INTERNAL_WEBRTC_BWU_HANDLER_H_ +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_H_ diff --git a/connections/implementation/webrtc_bwu_handler_stub.cc b/connections/implementation/mediums/webrtc_bwu_handler_stub.cc similarity index 89% rename from connections/implementation/webrtc_bwu_handler_stub.cc rename to connections/implementation/mediums/webrtc_bwu_handler_stub.cc index d116d100..5c3e4c57 100644 --- a/connections/implementation/webrtc_bwu_handler_stub.cc +++ b/connections/implementation/mediums/webrtc_bwu_handler_stub.cc @@ -14,17 +14,17 @@ #ifdef NO_WEBRTC -#include "connections/implementation/webrtc_bwu_handler_stub.h" +#include "connections/implementation/mediums/webrtc_bwu_handler_stub.h" +#include #include #include -#include "absl/functional/bind_front.h" +#include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" -#include "connections/implementation/mediums/utils.h" -#include "connections/implementation/mediums/webrtc_peer_id.h" -#include "connections/implementation/offline_frames.h" -#include "connections/implementation/webrtc_endpoint_channel.h" +#include "connections/implementation/endpoint_channel.h" +#include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/mediums/webrtc_socket.h" #include "internal/platform/expected.h" namespace nearby { diff --git a/connections/implementation/webrtc_bwu_handler_stub.h b/connections/implementation/mediums/webrtc_bwu_handler_stub.h similarity index 94% rename from connections/implementation/webrtc_bwu_handler_stub.h rename to connections/implementation/mediums/webrtc_bwu_handler_stub.h index 7c959cd9..859eb6c6 100644 --- a/connections/implementation/webrtc_bwu_handler_stub.h +++ b/connections/implementation/mediums/webrtc_bwu_handler_stub.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_WEBRTC_BWU_HANDLER_STUB_H_ -#define CORE_INTERNAL_WEBRTC_BWU_HANDLER_STUB_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_STUB_H_ +#define CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_STUB_H_ #ifdef NO_WEBRTC @@ -83,4 +83,4 @@ class WebrtcBwuHandler : public BaseBwuHandler { #endif -#endif // CORE_INTERNAL_WEBRTC_BWU_HANDLER_STUB_H_ +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_STUB_H_ diff --git a/connections/implementation/webrtc_endpoint_channel.cc b/connections/implementation/mediums/webrtc_endpoint_channel.cc similarity index 95% rename from connections/implementation/webrtc_endpoint_channel.cc rename to connections/implementation/mediums/webrtc_endpoint_channel.cc index a95c4027..e054c416 100644 --- a/connections/implementation/webrtc_endpoint_channel.cc +++ b/connections/implementation/mediums/webrtc_endpoint_channel.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/webrtc_endpoint_channel.h" +#include "connections/implementation/mediums/webrtc_endpoint_channel.h" #include #include diff --git a/connections/implementation/webrtc_endpoint_channel.h b/connections/implementation/mediums/webrtc_endpoint_channel.h similarity index 88% rename from connections/implementation/webrtc_endpoint_channel.h rename to connections/implementation/mediums/webrtc_endpoint_channel.h index dd11bdf6..e7d396d5 100644 --- a/connections/implementation/webrtc_endpoint_channel.h +++ b/connections/implementation/mediums/webrtc_endpoint_channel.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_WEBRTC_ENDPOINT_CHANNEL_H_ -#define CORE_INTERNAL_WEBRTC_ENDPOINT_CHANNEL_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_ENDPOINT_CHANNEL_H_ +#define CORE_INTERNAL_MEDIUMS_WEBRTC_ENDPOINT_CHANNEL_H_ #include #include @@ -41,4 +41,4 @@ class WebRtcEndpointChannel final : public BaseEndpointChannel { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_WEBRTC_ENDPOINT_CHANNEL_H_ +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/wifi_direct_bwu_handler.cc b/connections/implementation/mediums/wifi_direct_bwu_handler.cc similarity index 98% rename from connections/implementation/wifi_direct_bwu_handler.cc rename to connections/implementation/mediums/wifi_direct_bwu_handler.cc index ce314b09..ad501815 100644 --- a/connections/implementation/wifi_direct_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_direct_bwu_handler.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/wifi_direct_bwu_handler.h" +#include "connections/implementation/mediums/wifi_direct_bwu_handler.h" #include #include @@ -24,8 +24,8 @@ #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/mediums/wifi_direct_endpoint_channel.h" #include "connections/implementation/offline_frames.h" -#include "connections/implementation/wifi_direct_endpoint_channel.h" #include "connections/strategy.h" #include "internal/base/masker.h" #include "internal/platform/expected.h" diff --git a/connections/implementation/wifi_direct_bwu_handler.h b/connections/implementation/mediums/wifi_direct_bwu_handler.h similarity index 95% rename from connections/implementation/wifi_direct_bwu_handler.h rename to connections/implementation/mediums/wifi_direct_bwu_handler.h index 823edc12..2f6b86b9 100644 --- a/connections/implementation/wifi_direct_bwu_handler.h +++ b/connections/implementation/mediums/wifi_direct_bwu_handler.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_WIFI_DIRECT_BWU_HANDLER_H_ -#define CORE_INTERNAL_WIFI_DIRECT_BWU_HANDLER_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WIFI_DIRECT_BWU_HANDLER_H_ +#define CORE_INTERNAL_MEDIUMS_WIFI_DIRECT_BWU_HANDLER_H_ #include #include @@ -92,4 +92,4 @@ class WifiDirectBwuHandler : public BaseBwuHandler { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_WIFI_DIRECT_BWU_HANDLER_H_ +#endif // CORE_INTERNAL_MEDIUMS_WIFI_DIRECT_BWU_HANDLER_H_ diff --git a/connections/implementation/wifi_direct_bwu_test.cc b/connections/implementation/mediums/wifi_direct_bwu_handler_test.cc similarity index 98% rename from connections/implementation/wifi_direct_bwu_test.cc rename to connections/implementation/mediums/wifi_direct_bwu_handler_test.cc index e125c418..00689ac9 100644 --- a/connections/implementation/wifi_direct_bwu_test.cc +++ b/connections/implementation/mediums/wifi_direct_bwu_handler_test.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "connections/implementation/mediums/wifi_direct_bwu_handler.h" + #include #include #include @@ -26,7 +28,6 @@ #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/offline_frames.h" -#include "connections/implementation/wifi_direct_bwu_handler.h" #include "internal/flags/nearby_flags.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" diff --git a/connections/implementation/wifi_direct_endpoint_channel.cc b/connections/implementation/mediums/wifi_direct_endpoint_channel.cc similarity index 95% rename from connections/implementation/wifi_direct_endpoint_channel.cc rename to connections/implementation/mediums/wifi_direct_endpoint_channel.cc index 379112b8..b271d475 100644 --- a/connections/implementation/wifi_direct_endpoint_channel.cc +++ b/connections/implementation/mediums/wifi_direct_endpoint_channel.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/wifi_direct_endpoint_channel.h" +#include "connections/implementation/mediums/wifi_direct_endpoint_channel.h" #include #include diff --git a/connections/implementation/wifi_direct_endpoint_channel.h b/connections/implementation/mediums/wifi_direct_endpoint_channel.h similarity index 89% rename from connections/implementation/wifi_direct_endpoint_channel.h rename to connections/implementation/mediums/wifi_direct_endpoint_channel.h index 9cf735b6..45d4d6f9 100644 --- a/connections/implementation/wifi_direct_endpoint_channel.h +++ b/connections/implementation/mediums/wifi_direct_endpoint_channel.h @@ -12,9 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. - -#ifndef CORE_INTERNAL_WIFI_DIRECT_ENDPOINT_CHANNEL_H_ -#define CORE_INTERNAL_WIFI_DIRECT_ENDPOINT_CHANNEL_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WIFI_DIRECT_ENDPOINT_CHANNEL_H_ +#define CORE_INTERNAL_MEDIUMS_WIFI_DIRECT_ENDPOINT_CHANNEL_H_ #include @@ -48,4 +47,4 @@ class WifiDirectEndpointChannel final : public BaseEndpointChannel { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_WIFI_DIRECT_ENDPOINT_CHANNEL_H_ +#endif // CORE_INTERNAL_MEDIUMS_WIFI_DIRECT_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/wifi_hotspot_bwu_handler.cc b/connections/implementation/mediums/wifi_hotspot_bwu_handler.cc similarity index 98% rename from connections/implementation/wifi_hotspot_bwu_handler.cc rename to connections/implementation/mediums/wifi_hotspot_bwu_handler.cc index 9d2da68d..95b457a7 100644 --- a/connections/implementation/wifi_hotspot_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_hotspot_bwu_handler.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/wifi_hotspot_bwu_handler.h" +#include "connections/implementation/mediums/wifi_hotspot_bwu_handler.h" #if !defined(_WIN32) #include @@ -32,9 +32,9 @@ #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/mediums/wifi_hotspot_endpoint_channel.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" -#include "connections/implementation/wifi_hotspot_endpoint_channel.h" #include "connections/strategy.h" #include "internal/base/masker.h" #include "internal/platform/expected.h" diff --git a/connections/implementation/wifi_hotspot_bwu_handler.h b/connections/implementation/mediums/wifi_hotspot_bwu_handler.h similarity index 94% rename from connections/implementation/wifi_hotspot_bwu_handler.h rename to connections/implementation/mediums/wifi_hotspot_bwu_handler.h index 9af42e93..134c5cc2 100644 --- a/connections/implementation/wifi_hotspot_bwu_handler.h +++ b/connections/implementation/mediums/wifi_hotspot_bwu_handler.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_WIFI_HOTSPOT_BWU_HANDLER_H_ -#define CORE_INTERNAL_WIFI_HOTSPOT_BWU_HANDLER_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WIFI_HOTSPOT_BWU_HANDLER_H_ +#define CORE_INTERNAL_MEDIUMS_WIFI_HOTSPOT_BWU_HANDLER_H_ #include #include @@ -84,4 +84,4 @@ class WifiHotspotBwuHandler : public BaseBwuHandler { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_WIFI_HOTSPOT_BWU_HANDLER_H_ +#endif // CORE_INTERNAL_MEDIUMS_WIFI_HOTSPOT_BWU_HANDLER_H_ diff --git a/connections/implementation/wifi_hotspot_bwu_test.cc b/connections/implementation/mediums/wifi_hotspot_bwu_handler_test.cc similarity index 98% rename from connections/implementation/wifi_hotspot_bwu_test.cc rename to connections/implementation/mediums/wifi_hotspot_bwu_handler_test.cc index f1d300d6..03978050 100644 --- a/connections/implementation/wifi_hotspot_bwu_test.cc +++ b/connections/implementation/mediums/wifi_hotspot_bwu_handler_test.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "connections/implementation/mediums/wifi_hotspot_bwu_handler.h" + #include #include #include @@ -25,7 +27,6 @@ #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/offline_frames.h" -#include "connections/implementation/wifi_hotspot_bwu_handler.h" #include "internal/flags/nearby_flags.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" diff --git a/connections/implementation/wifi_hotspot_endpoint_channel.cc b/connections/implementation/mediums/wifi_hotspot_endpoint_channel.cc similarity index 95% rename from connections/implementation/wifi_hotspot_endpoint_channel.cc rename to connections/implementation/mediums/wifi_hotspot_endpoint_channel.cc index 53e99fbe..0b355d36 100644 --- a/connections/implementation/wifi_hotspot_endpoint_channel.cc +++ b/connections/implementation/mediums/wifi_hotspot_endpoint_channel.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/wifi_hotspot_endpoint_channel.h" +#include "connections/implementation/mediums/wifi_hotspot_endpoint_channel.h" #include #include diff --git a/connections/implementation/wifi_hotspot_endpoint_channel.h b/connections/implementation/mediums/wifi_hotspot_endpoint_channel.h similarity index 89% rename from connections/implementation/wifi_hotspot_endpoint_channel.h rename to connections/implementation/mediums/wifi_hotspot_endpoint_channel.h index b44da4de..2cb2b67f 100644 --- a/connections/implementation/wifi_hotspot_endpoint_channel.h +++ b/connections/implementation/mediums/wifi_hotspot_endpoint_channel.h @@ -12,9 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. - -#ifndef CORE_INTERNAL_WIFI_HOTSPOT_ENDPOINT_CHANNEL_H_ -#define CORE_INTERNAL_WIFI_HOTSPOT_ENDPOINT_CHANNEL_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WIFI_HOTSPOT_ENDPOINT_CHANNEL_H_ +#define CORE_INTERNAL_MEDIUMS_WIFI_HOTSPOT_ENDPOINT_CHANNEL_H_ #include @@ -48,4 +47,4 @@ class WifiHotspotEndpointChannel final : public BaseEndpointChannel { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_WIFI_HOTSPOT_ENDPOINT_CHANNEL_H_ +#endif // CORE_INTERNAL_MEDIUMS_WIFI_HOTSPOT_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/wifi_lan_bwu_handler.cc b/connections/implementation/mediums/wifi_lan_bwu_handler.cc similarity index 98% rename from connections/implementation/wifi_lan_bwu_handler.cc rename to connections/implementation/mediums/wifi_lan_bwu_handler.cc index bedac087..7b6e5604 100644 --- a/connections/implementation/wifi_lan_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_lan_bwu_handler.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/wifi_lan_bwu_handler.h" +#include "connections/implementation/mediums/wifi_lan_bwu_handler.h" #include #include @@ -25,8 +25,8 @@ #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/mediums/wifi_lan_endpoint_channel.h" #include "connections/implementation/offline_frames.h" -#include "connections/implementation/wifi_lan_endpoint_channel.h" #include "internal/platform/expected.h" #include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/logging.h" diff --git a/connections/implementation/wifi_lan_bwu_handler.h b/connections/implementation/mediums/wifi_lan_bwu_handler.h similarity index 94% rename from connections/implementation/wifi_lan_bwu_handler.h rename to connections/implementation/mediums/wifi_lan_bwu_handler.h index abf0f26d..a94a0554 100644 --- a/connections/implementation/wifi_lan_bwu_handler.h +++ b/connections/implementation/mediums/wifi_lan_bwu_handler.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_WIFI_LAN_BWU_HANDLER_H_ -#define CORE_INTERNAL_WIFI_LAN_BWU_HANDLER_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WIFI_LAN_BWU_HANDLER_H_ +#define CORE_INTERNAL_MEDIUMS_WIFI_LAN_BWU_HANDLER_H_ #include #include @@ -84,4 +84,4 @@ class WifiLanBwuHandler : public BaseBwuHandler { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_WIFI_LAN_BWU_HANDLER_H_ +#endif // CORE_INTERNAL_MEDIUMS_WIFI_LAN_BWU_HANDLER_H_ diff --git a/connections/implementation/wifi_lan_bwu_handler_test.cc b/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc similarity index 99% rename from connections/implementation/wifi_lan_bwu_handler_test.cc rename to connections/implementation/mediums/wifi_lan_bwu_handler_test.cc index 27d31a22..ad03cd54 100644 --- a/connections/implementation/wifi_lan_bwu_handler_test.cc +++ b/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/wifi_lan_bwu_handler.h" +#include "connections/implementation/mediums/wifi_lan_bwu_handler.h" #include #include diff --git a/connections/implementation/wifi_lan_endpoint_channel.cc b/connections/implementation/mediums/wifi_lan_endpoint_channel.cc similarity index 96% rename from connections/implementation/wifi_lan_endpoint_channel.cc rename to connections/implementation/mediums/wifi_lan_endpoint_channel.cc index ec3e02b1..94fb69e4 100644 --- a/connections/implementation/wifi_lan_endpoint_channel.cc +++ b/connections/implementation/mediums/wifi_lan_endpoint_channel.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/wifi_lan_endpoint_channel.h" +#include "connections/implementation/mediums/wifi_lan_endpoint_channel.h" #include diff --git a/connections/implementation/wifi_lan_endpoint_channel.h b/connections/implementation/mediums/wifi_lan_endpoint_channel.h similarity index 87% rename from connections/implementation/wifi_lan_endpoint_channel.h rename to connections/implementation/mediums/wifi_lan_endpoint_channel.h index 587f5002..59d5d9e3 100644 --- a/connections/implementation/wifi_lan_endpoint_channel.h +++ b/connections/implementation/mediums/wifi_lan_endpoint_channel.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_WIFI_LAN_ENDPOINT_CHANNEL_H_ -#define CORE_INTERNAL_WIFI_LAN_ENDPOINT_CHANNEL_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WIFI_LAN_ENDPOINT_CHANNEL_H_ +#define CORE_INTERNAL_MEDIUMS_WIFI_LAN_ENDPOINT_CHANNEL_H_ #include @@ -41,4 +41,4 @@ class WifiLanEndpointChannel final : public BaseEndpointChannel { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_WIFI_LAN_ENDPOINT_CHANNEL_H_ +#endif // CORE_INTERNAL_MEDIUMS_WIFI_LAN_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/p2p_cluster_pcp_handler.cc b/connections/implementation/p2p_cluster_pcp_handler.cc index 73dc47f4..76bbe1bc 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.cc +++ b/connections/implementation/p2p_cluster_pcp_handler.cc @@ -29,13 +29,9 @@ #include "absl/strings/string_view.h" #include "connections/advertising_options.h" #include "connections/discovery_options.h" -#include "connections/implementation/awdl_endpoint_channel.h" #include "connections/implementation/base_pcp_handler.h" #include "connections/implementation/ble_advertisement.h" -#include "connections/implementation/ble_endpoint_channel.h" -#include "connections/implementation/ble_l2cap_endpoint_channel.h" #include "connections/implementation/bluetooth_device_name.h" -#include "connections/implementation/bluetooth_endpoint_channel.h" #include "connections/implementation/bwu_manager.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel_manager.h" @@ -44,16 +40,20 @@ #include "connections/implementation/injected_bluetooth_device_store.h" #include "connections/implementation/mediums/advertisements/advertisement_util.h" #include "connections/implementation/mediums/advertisements/dct_advertisement.h" +#include "connections/implementation/mediums/awdl_endpoint_channel.h" #include "connections/implementation/mediums/ble.h" #include "connections/implementation/mediums/ble/ble_advertisement_header.h" #include "connections/implementation/mediums/ble/ble_socket.h" +#include "connections/implementation/mediums/ble_endpoint_channel.h" +#include "connections/implementation/mediums/ble_l2cap_endpoint_channel.h" #include "connections/implementation/mediums/bluetooth_classic.h" +#include "connections/implementation/mediums/bluetooth_endpoint_channel.h" #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/utils.h" +#include "connections/implementation/mediums/wifi_lan_endpoint_channel.h" #include "connections/implementation/pcp.h" #include "connections/implementation/pcp_handler.h" #include "connections/implementation/webrtc_state.h" -#include "connections/implementation/wifi_lan_endpoint_channel.h" #include "connections/implementation/wifi_lan_service_info.h" #include "connections/medium_selector.h" #include "connections/out_of_band_connection_metadata.h" From 97ea46900666fac13d22763652342b233810f4d7 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 21 May 2026 11:07:13 -0700 Subject: [PATCH 106/151] Move BwuHandler creation into medium. PiperOrigin-RevId: 919149551 --- connections/implementation/bwu_manager.cc | 33 ++----- connections/implementation/mediums/BUILD | 6 +- connections/implementation/mediums/awdl.cc | 9 ++ connections/implementation/mediums/awdl.h | 5 ++ .../mediums/awdl_bwu_handler.cc | 7 +- .../implementation/mediums/awdl_bwu_handler.h | 9 +- .../mediums/awdl_bwu_handler_test.cc | 3 +- .../mediums/bluetooth_bwu_handler.cc | 11 ++- .../mediums/bluetooth_bwu_handler.h | 13 +-- .../mediums/bluetooth_bwu_handler_test.cc | 14 +-- .../mediums/bluetooth_classic.cc | 9 ++ .../mediums/bluetooth_classic.h | 4 + connections/implementation/mediums/webrtc.h | 6 ++ .../implementation/mediums/webrtc/BUILD | 19 +++- .../{ => webrtc}/webrtc_bwu_handler.cc | 14 ++- .../mediums/{ => webrtc}/webrtc_bwu_handler.h | 19 ++-- .../mediums/webrtc/webrtc_impl.cc | 8 ++ .../mediums/webrtc/webrtc_impl.h | 4 + .../mediums/webrtc_bwu_handler_stub.cc | 84 ------------------ .../mediums/webrtc_bwu_handler_stub.h | 86 ------------------- .../implementation/mediums/wifi_direct.cc | 10 +++ .../implementation/mediums/wifi_direct.h | 4 + .../mediums/wifi_direct_bwu_handler.cc | 8 +- .../mediums/wifi_direct_bwu_handler.h | 9 +- .../mediums/wifi_direct_bwu_handler_test.cc | 8 +- .../implementation/mediums/wifi_hotspot.cc | 11 +++ .../implementation/mediums/wifi_hotspot.h | 4 + .../mediums/wifi_hotspot_bwu_handler.cc | 8 +- .../mediums/wifi_hotspot_bwu_handler.h | 9 +- .../mediums/wifi_hotspot_bwu_handler_test.cc | 8 +- .../implementation/mediums/wifi_lan.cc | 10 +++ connections/implementation/mediums/wifi_lan.h | 5 ++ .../mediums/wifi_lan_bwu_handler.cc | 8 +- .../mediums/wifi_lan_bwu_handler.h | 9 +- .../mediums/wifi_lan_bwu_handler_test.cc | 3 +- 35 files changed, 202 insertions(+), 275 deletions(-) rename connections/implementation/mediums/{ => webrtc}/webrtc_bwu_handler.cc (95%) rename connections/implementation/mediums/{ => webrtc}/webrtc_bwu_handler.h (88%) delete mode 100644 connections/implementation/mediums/webrtc_bwu_handler_stub.cc delete mode 100644 connections/implementation/mediums/webrtc_bwu_handler_stub.h diff --git a/connections/implementation/bwu_manager.cc b/connections/implementation/bwu_manager.cc index a1082763..48a70718 100644 --- a/connections/implementation/bwu_manager.cc +++ b/connections/implementation/bwu_manager.cc @@ -32,20 +32,10 @@ #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/awdl_bwu_handler.h" -#include "connections/implementation/mediums/bluetooth_bwu_handler.h" #include "connections/implementation/mediums/mediums.h" -#include "connections/implementation/mediums/wifi_lan_bwu_handler.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/mediums/webrtc_bwu_handler_stub.h" -#else -#include "connections/implementation/mediums/webrtc_bwu_handler.h" -#endif -#include "connections/implementation/mediums/wifi_direct_bwu_handler.h" -#include "connections/implementation/mediums/wifi_hotspot_bwu_handler.h" #include "connections/medium_selector.h" #include "internal/platform/cancelable_alarm.h" #include "internal/platform/count_down_latch.h" @@ -134,43 +124,37 @@ void BwuManager::InitBwuHandlers() { if (config_.allow_upgrade_to.awdl) { handlers_.emplace( Medium::AWDL, - std::make_unique( - *mediums_, + mediums_->GetAwdl().CreateBwuHandler( absl::bind_front(&BwuManager::OnIncomingConnection, this))); } if (config_.allow_upgrade_to.wifi_hotspot) { handlers_.emplace( Medium::WIFI_HOTSPOT, - std::make_unique( - *mediums_, + mediums_->GetWifiHotspot().CreateBwuHandler( absl::bind_front(&BwuManager::OnIncomingConnection, this))); } if (config_.allow_upgrade_to.wifi_direct) { handlers_.emplace( Medium::WIFI_DIRECT, - std::make_unique( - *mediums_, + mediums_->GetWifiDirect().CreateBwuHandler( absl::bind_front(&BwuManager::OnIncomingConnection, this))); } if (config_.allow_upgrade_to.wifi_lan) { handlers_.emplace( Medium::WIFI_LAN, - std::make_unique( - *mediums_, + mediums_->GetWifiLan().CreateBwuHandler( absl::bind_front(&BwuManager::OnIncomingConnection, this))); } if (config_.allow_upgrade_to.web_rtc) { handlers_.emplace( Medium::WEB_RTC, - std::make_unique( - *mediums_, + mediums_->GetWebRtc().CreateBwuHandler( absl::bind_front(&BwuManager::OnIncomingConnection, this))); } if (config_.allow_upgrade_to.bluetooth) { handlers_.emplace( Medium::BLUETOOTH, - std::make_unique( - *mediums_, + mediums_->GetBluetoothClassic().CreateBwuHandler( absl::bind_front(&BwuManager::OnIncomingConnection, this))); } } @@ -196,8 +180,9 @@ void BwuManager::Shutdown() { medium_ = Medium::UNKNOWN_MEDIUM; endpoint_id_to_bwu_medium_.clear(); for (auto& medium_handler_pair : handlers_) { - assert(medium_handler_pair.second); - medium_handler_pair.second->RevertInitiatorState(); + if (medium_handler_pair.second != nullptr) { + medium_handler_pair.second->RevertInitiatorState(); + } } handlers_.clear(); diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index e10be0fe..f0af9ba8 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -31,8 +31,6 @@ cc_library( "bluetooth_endpoint_channel.cc", "bluetooth_radio.cc", "mediums.cc", - "webrtc_bwu_handler.cc", - "webrtc_bwu_handler_stub.cc", "webrtc_endpoint_channel.cc", "wifi_direct.cc", "wifi_direct_bwu_handler.cc", @@ -56,8 +54,6 @@ cc_library( "bluetooth_endpoint_channel.h", "bluetooth_radio.h", "mediums.h", - "webrtc_bwu_handler.h", - "webrtc_bwu_handler_stub.h", "webrtc_endpoint_channel.h", "wifi.h", "wifi_direct.h", @@ -110,6 +106,7 @@ cc_library( "//internal/platform/implementation:platform", "//internal/platform/implementation:wifi_utils", "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/base:nullability", "@com_google_absl//absl/container:btree", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", @@ -190,6 +187,7 @@ cc_library( deps = [ ":webrtc_peer_id", ":webrtc_socket", + "//connections/implementation:bwu_handler", "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/platform:base", "//internal/platform:cancellation_flag", diff --git a/connections/implementation/mediums/awdl.cc b/connections/implementation/mediums/awdl.cc index 81698ab3..ba2539f1 100644 --- a/connections/implementation/mediums/awdl.cc +++ b/connections/implementation/mediums/awdl.cc @@ -15,6 +15,7 @@ #include "connections/implementation/mediums/awdl.h" #include +#include #include #include #include @@ -22,6 +23,8 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" +#include "connections/implementation/bwu_handler.h" +#include "connections/implementation/mediums/awdl_bwu_handler.h" #include "connections/implementation/mediums/utils.h" #include "internal/platform/awdl.h" #include "internal/platform/byte_array.h" @@ -471,5 +474,11 @@ ErrorOr Awdl::InternalConnect( return socket; } +std::unique_ptr Awdl::CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback) { + return std::make_unique( + this, std::move(incoming_connection_callback)); +} + } // namespace connections } // namespace nearby diff --git a/connections/implementation/mediums/awdl.h b/connections/implementation/mediums/awdl.h index c6336946..cb4f1910 100644 --- a/connections/implementation/mediums/awdl.h +++ b/connections/implementation/mediums/awdl.h @@ -16,6 +16,7 @@ #define CORE_INTERNAL_MEDIUMS_AWDL_H_ #include +#include #include #include #include @@ -24,6 +25,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/functional/any_invocable.h" +#include "connections/implementation/bwu_handler.h" #include "internal/platform/awdl.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" @@ -129,6 +131,9 @@ class Awdl { AwdlCredential GetCredentials(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); + std::unique_ptr CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback); + private: struct AdvertisingInfo { bool Empty() const { return nsd_service_infos.empty(); } diff --git a/connections/implementation/mediums/awdl_bwu_handler.cc b/connections/implementation/mediums/awdl_bwu_handler.cc index 6aa9bca5..edff8dda 100644 --- a/connections/implementation/mediums/awdl_bwu_handler.cc +++ b/connections/implementation/mediums/awdl_bwu_handler.cc @@ -18,6 +18,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/functional/bind_front.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -28,7 +29,6 @@ #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/awdl.h" #include "connections/implementation/mediums/awdl_endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/utils.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/service_id_constants.h" @@ -56,9 +56,10 @@ constexpr absl::string_view kAwdlServiceIdSuffixForServiceType = "_AWDL"; } // namespace AwdlBwuHandler::AwdlBwuHandler( - Mediums& mediums, IncomingConnectionCallback incoming_connection_callback) + Awdl* absl_nonnull awdl_medium, + IncomingConnectionCallback incoming_connection_callback) : BaseBwuHandler(std::move(incoming_connection_callback)), - mediums_(mediums) {} + awdl_medium_(*awdl_medium) {} // Called by BWU target. Retrieves a new medium info from incoming message, // and establishes connection over AWDL using this info. diff --git a/connections/implementation/mediums/awdl_bwu_handler.h b/connections/implementation/mediums/awdl_bwu_handler.h index c3c27985..56a89290 100644 --- a/connections/implementation/mediums/awdl_bwu_handler.h +++ b/connections/implementation/mediums/awdl_bwu_handler.h @@ -18,12 +18,12 @@ #include #include +#include "absl/base/nullability.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/awdl.h" -#include "connections/implementation/mediums/mediums.h" #include "internal/platform/awdl.h" #include "internal/platform/expected.h" #include "internal/platform/nsd_service_info.h" @@ -35,8 +35,8 @@ namespace connections { // per-Medium-specific operations needed to upgrade an EndpointChannel. class AwdlBwuHandler : public BaseBwuHandler { public: - explicit AwdlBwuHandler( - Mediums& mediums, + AwdlBwuHandler( + Awdl* absl_nonnull awdl_medium, IncomingConnectionCallback incoming_connection_callback); private: @@ -80,8 +80,7 @@ class AwdlBwuHandler : public BaseBwuHandler { std::string GenerateServiceName(); std::string GeneratePassword(); - Mediums& mediums_; - Awdl& awdl_medium_{mediums_.GetAwdl()}; + Awdl& awdl_medium_; NsdServiceInfo nsd_service_info_; }; diff --git a/connections/implementation/mediums/awdl_bwu_handler_test.cc b/connections/implementation/mediums/awdl_bwu_handler_test.cc index 2908cf25..317f7b2c 100644 --- a/connections/implementation/mediums/awdl_bwu_handler_test.cc +++ b/connections/implementation/mediums/awdl_bwu_handler_test.cc @@ -127,7 +127,8 @@ constexpr absl::string_view kChannelName{"channel_name"}; class AwdlBwuHandlerTest : public ::testing::Test { protected: AwdlBwuHandlerTest() - : handler_(mediums_, incoming_connection_callback_.AsStdFunction()) {} + : handler_(&mediums_.GetAwdl(), + incoming_connection_callback_.AsStdFunction()) {} void SetUp() override { // By default, network is connected. diff --git a/connections/implementation/mediums/bluetooth_bwu_handler.cc b/connections/implementation/mediums/bluetooth_bwu_handler.cc index f2643049..2a7e9075 100644 --- a/connections/implementation/mediums/bluetooth_bwu_handler.cc +++ b/connections/implementation/mediums/bluetooth_bwu_handler.cc @@ -22,8 +22,10 @@ #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" +#include "connections/implementation/mediums/bluetooth_classic.h" #include "connections/implementation/mediums/bluetooth_endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" +#include "absl/base/nullability.h" +#include "connections/implementation/mediums/bluetooth_radio.h" #include "connections/implementation/offline_frames.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_classic.h" @@ -43,9 +45,12 @@ using ::location::nearby::proto::connections::OperationResultCode; } // namespace BluetoothBwuHandler::BluetoothBwuHandler( - Mediums& mediums, IncomingConnectionCallback incoming_connection_callback) + BluetoothRadio* absl_nonnull bluetooth_radio, + BluetoothClassic* absl_nonnull bluetooth_medium, + IncomingConnectionCallback incoming_connection_callback) : BaseBwuHandler(std::move(incoming_connection_callback)), - mediums_(mediums) {} + bluetooth_radio_(*bluetooth_radio), + bluetooth_medium_(*bluetooth_medium) {} // Called by BWU target. Retrieves a new medium info from incoming message, // and establishes connection over BT using this info. diff --git a/connections/implementation/mediums/bluetooth_bwu_handler.h b/connections/implementation/mediums/bluetooth_bwu_handler.h index 3c1a7b10..b1902362 100644 --- a/connections/implementation/mediums/bluetooth_bwu_handler.h +++ b/connections/implementation/mediums/bluetooth_bwu_handler.h @@ -18,12 +18,13 @@ #include #include +#include "absl/base/nullability.h" #include "connections/implementation/base_bwu_handler.h" +#include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/bluetooth_classic.h" #include "connections/implementation/mediums/bluetooth_radio.h" -#include "connections/implementation/mediums/mediums.h" #include "connections/medium_selector.h" #include "internal/platform/bluetooth_classic.h" #include "internal/platform/expected.h" @@ -35,8 +36,9 @@ namespace connections { // per-Medium-specific operations needed to upgrade an EndpointChannel. class BluetoothBwuHandler : public BaseBwuHandler { public: - explicit BluetoothBwuHandler( - Mediums& mediums, + BluetoothBwuHandler( + BluetoothRadio* absl_nonnull bluetooth_radio, + BluetoothClassic* absl_nonnull bluetooth_medium, IncomingConnectionCallback incoming_connection_callback); private: @@ -75,9 +77,8 @@ class BluetoothBwuHandler : public BaseBwuHandler { const std::string& upgrade_service_id, BluetoothSocket socket); - Mediums& mediums_; - BluetoothRadio& bluetooth_radio_{mediums_.GetBluetoothRadio()}; - BluetoothClassic& bluetooth_medium_{mediums_.GetBluetoothClassic()}; + BluetoothRadio& bluetooth_radio_; + BluetoothClassic& bluetooth_medium_; }; } // namespace connections diff --git a/connections/implementation/mediums/bluetooth_bwu_handler_test.cc b/connections/implementation/mediums/bluetooth_bwu_handler_test.cc index 2144ed9d..4a5bac2c 100644 --- a/connections/implementation/mediums/bluetooth_bwu_handler_test.cc +++ b/connections/implementation/mediums/bluetooth_bwu_handler_test.cc @@ -54,7 +54,8 @@ TEST_F(BluetoothBwuTest, CanCreateBwuHandler) { ClientProxy client; Mediums mediums; - auto handler = std::make_unique(mediums, nullptr); + auto handler = std::make_unique( + &mediums.GetBluetoothRadio(), &mediums.GetBluetoothClassic(), nullptr); handler->InitializeUpgradedMediumForEndpoint(&client, /*service_id=*/"B", /*endpoint_id=*/"2"); @@ -73,9 +74,10 @@ TEST_F(BluetoothBwuTest, SoftAPBWUInit_STACreateEndpointChannel) { ExceptionOr upgrade_frame; auto handler_1 = std::make_unique( - mediums_1, [&](ClientProxy* client, - std::unique_ptr - mutable_connection) { + &mediums_1.GetBluetoothRadio(), &mediums_1.GetBluetoothClassic(), + [&](ClientProxy* client, + std::unique_ptr + mutable_connection) { LOG(WARNING) << "Server socket connection accept call back"; accept_latch.CountDown(); EXPECT_TRUE(end_latch.Await(kWaitDuration).result()); @@ -99,7 +101,9 @@ TEST_F(BluetoothBwuTest, SoftAPBWUInit_STACreateEndpointChannel) { // Wait till client_1 started as Bluetooth and then connect to it EXPECT_TRUE(start_latch.Await(kWaitDuration).result()); std::unique_ptr handler_2 = - std::make_unique(mediums_2, nullptr); + std::make_unique( + &mediums_2.GetBluetoothRadio(), &mediums_2.GetBluetoothClassic(), + nullptr); client_executor.Execute([&]() { auto bwu_frame = diff --git a/connections/implementation/mediums/bluetooth_classic.cc b/connections/implementation/mediums/bluetooth_classic.cc index 2a971d8a..d0dc386d 100644 --- a/connections/implementation/mediums/bluetooth_classic.cc +++ b/connections/implementation/mediums/bluetooth_classic.cc @@ -18,7 +18,9 @@ #include #include +#include "connections/implementation/bwu_handler.h" #include "connections/implementation/mediums/bluetooth_radio.h" +#include "connections/implementation/mediums/bluetooth_bwu_handler.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_classic.h" #include "internal/platform/cancellation_flag.h" @@ -565,5 +567,12 @@ std::string BluetoothClassic::GenerateUuidFromString(const std::string& data) { return std::string(Uuid(data)); } +std::unique_ptr BluetoothClassic::CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback) { + MutexLock lock(&mutex_); + return std::make_unique( + &radio_, this, std::move(incoming_connection_callback)); +} + } // namespace connections } // namespace nearby diff --git a/connections/implementation/mediums/bluetooth_classic.h b/connections/implementation/mediums/bluetooth_classic.h index 37bf8bd3..63ae1e68 100644 --- a/connections/implementation/mediums/bluetooth_classic.h +++ b/connections/implementation/mediums/bluetooth_classic.h @@ -22,6 +22,7 @@ #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" +#include "connections/implementation/bwu_handler.h" #include "connections/implementation/mediums/bluetooth_radio.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_classic.h" @@ -126,6 +127,9 @@ class BluetoothClassic { bool IsDiscovering(const std::string& serviceId) const ABSL_LOCKS_EXCLUDED(mutex_); + std::unique_ptr CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback); + protected: // Use for unit tests only to inject a BluetoothClassicMedium. BluetoothClassic(BluetoothRadio& radio, diff --git a/connections/implementation/mediums/webrtc.h b/connections/implementation/mediums/webrtc.h index 579bccde..4e401036 100644 --- a/connections/implementation/mediums/webrtc.h +++ b/connections/implementation/mediums/webrtc.h @@ -19,6 +19,7 @@ #include #include "absl/functional/any_invocable.h" +#include "connections/implementation/bwu_handler.h" #include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" @@ -79,6 +80,11 @@ class WebRtc { } virtual bool IsUsingCellular() { return false; } + + virtual std::unique_ptr CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback) { + return nullptr; + } }; } // namespace mediums diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index 23dfffce..c1d34862 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -103,8 +103,14 @@ cc_library( cc_library( name = "webrtc_impl", - srcs = ["webrtc_impl.cc"], - hdrs = ["webrtc_impl.h"], + srcs = [ + "webrtc_bwu_handler.cc", + "webrtc_impl.cc", + ], + hdrs = [ + "webrtc_bwu_handler.h", + "webrtc_impl.h", + ], visibility = [ "//connections/implementation/mediums:__pkg__", ], @@ -113,18 +119,25 @@ cc_library( ":signaling_frames", ":webrtc", ":webrtc_medium", + "//connections:core_types", + "//connections/implementation:bwu_handler", + "//connections/implementation:client_proxy", + "//connections/implementation:endpoint_channel", + "//connections/implementation:offline_frames", + "//connections/implementation/mediums", "//connections/implementation/mediums:webrtc", "//connections/implementation/mediums:webrtc_peer_id", "//connections/implementation/mediums:webrtc_socket", + "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/platform:base", "//internal/platform:cancellation_flag", - "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:types", "//proto/mediums:web_rtc_signaling_frames_cc_proto", # "//third_party/webrtc/files/stable/webrtc/api:jsep", "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/base:nullability", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/functional:bind_front", diff --git a/connections/implementation/mediums/webrtc_bwu_handler.cc b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc similarity index 95% rename from connections/implementation/mediums/webrtc_bwu_handler.cc rename to connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc index 31605073..8b041220 100644 --- a/connections/implementation/mediums/webrtc_bwu_handler.cc +++ b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc @@ -12,9 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef NO_WEBRTC - -#include "connections/implementation/mediums/webrtc_bwu_handler.h" +#include "connections/implementation/mediums/webrtc/webrtc_bwu_handler.h" #include #include @@ -24,7 +22,8 @@ #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" +#include "absl/base/nullability.h" +#include "connections/implementation/mediums/webrtc.h" #include "connections/implementation/mediums/webrtc_endpoint_channel.h" #include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/mediums/webrtc_socket.h" @@ -68,9 +67,10 @@ void WebrtcBwuHandler::WebrtcIncomingSocket::Close() { socket_->Close(); } std::string WebrtcBwuHandler::WebrtcIncomingSocket::ToString() { return name_; } WebrtcBwuHandler::WebrtcBwuHandler( - Mediums& mediums, IncomingConnectionCallback incoming_connection_callback) + mediums::WebRtc* absl_nonnull webrtc_medium, + IncomingConnectionCallback incoming_connection_callback) : BaseBwuHandler(std::move(incoming_connection_callback)), - mediums_(mediums) {} + webrtc_(*webrtc_medium) {} // Called by BWU target. Retrieves a new medium info from incoming message, // and establishes connection over WebRTC using this info. @@ -179,5 +179,3 @@ void WebrtcBwuHandler::OnIncomingWebrtcConnection( } // namespace connections } // namespace nearby - -#endif diff --git a/connections/implementation/mediums/webrtc_bwu_handler.h b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.h similarity index 88% rename from connections/implementation/mediums/webrtc_bwu_handler.h rename to connections/implementation/mediums/webrtc/webrtc_bwu_handler.h index 725486ff..f7429a44 100644 --- a/connections/implementation/mediums/webrtc_bwu_handler.h +++ b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.h @@ -12,19 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_H_ - -#ifndef NO_WEBRTC +#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_BWU_HANDLER_H_ +#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_BWU_HANDLER_H_ #include #include +#include "absl/base/nullability.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/webrtc.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "connections/medium_selector.h" @@ -37,8 +35,8 @@ namespace connections { // per-Medium-specific operations needed to upgrade an EndpointChannel. class WebrtcBwuHandler : public BaseBwuHandler { public: - explicit WebrtcBwuHandler( - Mediums& mediums, + WebrtcBwuHandler( + mediums::WebRtc* absl_nonnull webrtc_medium, IncomingConnectionCallback incoming_connection_callback); private: @@ -78,13 +76,10 @@ class WebrtcBwuHandler : public BaseBwuHandler { ClientProxy* client, const std::string& upgrade_service_id, std::shared_ptr socket); - Mediums& mediums_; - mediums::WebRtc& webrtc_{mediums_.GetWebRtc()}; + mediums::WebRtc& webrtc_; }; } // namespace connections } // namespace nearby -#endif - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_H_ +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_BWU_HANDLER_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.cc b/connections/implementation/mediums/webrtc/webrtc_impl.cc index b7487bf7..4da2c2dd 100644 --- a/connections/implementation/mediums/webrtc/webrtc_impl.cc +++ b/connections/implementation/mediums/webrtc/webrtc_impl.cc @@ -23,10 +23,12 @@ #include "absl/container/flat_hash_set.h" #include "absl/functional/bind_front.h" #include "absl/time/time.h" +#include "connections/implementation/bwu_handler.h" #include "connections/implementation/mediums/webrtc/connection_flow.h" #include "connections/implementation/mediums/webrtc/session_description_wrapper.h" #include "connections/implementation/mediums/webrtc/signaling_frames.h" #include "connections/implementation/mediums/webrtc/webrtc.h" +#include "connections/implementation/mediums/webrtc/webrtc_bwu_handler.h" #include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "internal/platform/byte_array.h" @@ -784,6 +786,12 @@ bool WebRtcImpl::IsUsingCellular() { return is_using_cellular_; } +std::unique_ptr WebRtcImpl::CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback) { + return std::make_unique( + this, std::move(incoming_connection_callback)); +} + } // namespace mediums } // namespace connections } // namespace nearby diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.h b/connections/implementation/mediums/webrtc/webrtc_impl.h index b4ec12fb..979ebb48 100644 --- a/connections/implementation/mediums/webrtc/webrtc_impl.h +++ b/connections/implementation/mediums/webrtc/webrtc_impl.h @@ -22,6 +22,7 @@ #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" +#include "connections/implementation/bwu_handler.h" #include "connections/implementation/mediums/webrtc.h" #include "connections/implementation/mediums/webrtc/connection_flow.h" #include "connections/implementation/mediums/webrtc/session_description_wrapper.h" @@ -68,6 +69,9 @@ class WebRtcImpl : public WebRtc { CancellationFlag* cancellation_flag, bool non_cellular) override ABSL_LOCKS_EXCLUDED(mutex_); bool IsUsingCellular() override ABSL_LOCKS_EXCLUDED(mutex_); + std::unique_ptr CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback) + override; protected: // Use for unit tests only to inject a WebRtcMedium. diff --git a/connections/implementation/mediums/webrtc_bwu_handler_stub.cc b/connections/implementation/mediums/webrtc_bwu_handler_stub.cc deleted file mode 100644 index 5c3e4c57..00000000 --- a/connections/implementation/mediums/webrtc_bwu_handler_stub.cc +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2020 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. - -#ifdef NO_WEBRTC - -#include "connections/implementation/mediums/webrtc_bwu_handler_stub.h" - -#include -#include -#include - -#include "connections/implementation/base_bwu_handler.h" -#include "connections/implementation/client_proxy.h" -#include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "internal/platform/expected.h" - -namespace nearby { -namespace connections { - -namespace { -using ::location::nearby::connections::BandwidthUpgradeNegotiationFrame; -using ::location::nearby::proto::connections::OperationResultCode; -} // namespace - -WebrtcBwuHandler::WebrtcIncomingSocket::WebrtcIncomingSocket( - const std::string& name, std::shared_ptr socket) - : name_(name), socket_(std::move(socket)) {} - -void WebrtcBwuHandler::WebrtcIncomingSocket::Close() {} - -std::string WebrtcBwuHandler::WebrtcIncomingSocket::ToString() { return ""; } - -WebrtcBwuHandler::WebrtcBwuHandler( - Mediums& mediums, IncomingConnectionCallback incoming_connection_callback) - : BaseBwuHandler(std::move(incoming_connection_callback)), - mediums_(mediums) {} - -// Called by BWU target. Retrieves a new medium info from incoming message, -// and establishes connection over WebRTC using this info. -ErrorOr> -WebrtcBwuHandler::CreateUpgradedEndpointChannel( - ClientProxy* client, const std::string& service_id, - const std::string& endpoint_id, - const BandwidthUpgradeNegotiationFrame::UpgradePathInfo& - upgrade_path_info) { - return {Error(OperationResultCode::DETAIL_UNKNOWN)}; -} - -void WebrtcBwuHandler::HandleRevertInitiatorStateForService( - const std::string& upgrade_service_id) {} - -// Called by BWU initiator. Set up WebRTC upgraded medium for this endpoint, -// and returns a upgrade path info (PeerId, LocationHint) for remote party to -// perform discovery. -std::string WebrtcBwuHandler::HandleInitializeUpgradedMediumForEndpoint( - ClientProxy* client, const std::string& upgrade_service_id, - const std::string& endpoint_id) { - return {}; -} - -// Accept Connection Callback. -// Notifies that the remote party called WebRtc::Connect() -// for this socket. -void WebrtcBwuHandler::OnIncomingWebrtcConnection( - ClientProxy* client, const std::string& upgrade_service_id, - std::shared_ptr socket) {} - -} // namespace connections -} // namespace nearby - -#endif diff --git a/connections/implementation/mediums/webrtc_bwu_handler_stub.h b/connections/implementation/mediums/webrtc_bwu_handler_stub.h deleted file mode 100644 index 859eb6c6..00000000 --- a/connections/implementation/mediums/webrtc_bwu_handler_stub.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_STUB_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_STUB_H_ - -#ifdef NO_WEBRTC - -#include - -#include "connections/implementation/base_bwu_handler.h" -#include "connections/implementation/client_proxy.h" -#include "connections/implementation/endpoint_channel_manager.h" -#include "connections/implementation/mediums/mediums.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "internal/platform/expected.h" - -namespace nearby { -namespace connections { - -// Defines the set of methods that need to be implemented to handle the -// per-Medium-specific operations needed to upgrade an EndpointChannel. -class WebrtcBwuHandler : public BaseBwuHandler { - public: - explicit WebrtcBwuHandler( - Mediums& mediums, - IncomingConnectionCallback incoming_connection_callback); - - private: - class WebrtcIncomingSocket : public BwuHandler::IncomingSocket { - public: - explicit WebrtcIncomingSocket( - const std::string& name, std::shared_ptr socket); - - std::string ToString() override; - void Close() override; - - private: - std::string name_; - std::shared_ptr socket_; - }; - - // BwuHandler implementation: - ErrorOr> CreateUpgradedEndpointChannel( - ClientProxy* client, const std::string& service_id, - const std::string& endpoint_id, - const location::nearby::connections::BandwidthUpgradeNegotiationFrame:: - UpgradePathInfo& upgrade_path_info) final; - location::nearby::proto::connections::Medium GetUpgradeMedium() const final { - return Medium::WEB_RTC; - } - void OnEndpointDisconnect(ClientProxy* client, - const std::string& endpoint_id) final {} - - // BaseBwuHandler implementation: - std::string HandleInitializeUpgradedMediumForEndpoint( - ClientProxy* client, const std::string& upgrade_service_id, - const std::string& endpoint_id) final; - void HandleRevertInitiatorStateForService( - const std::string& upgrade_service_id) final; - - void OnIncomingWebrtcConnection( - ClientProxy* client, const std::string& upgrade_service_id, - std::shared_ptr socket); - - Mediums& mediums_; - mediums::WebRtc& webrtc_{mediums_.GetWebRtc()}; -}; - -} // namespace connections -} // namespace nearby - -#endif - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_BWU_HANDLER_STUB_H_ diff --git a/connections/implementation/mediums/wifi_direct.cc b/connections/implementation/mediums/wifi_direct.cc index 75f7b35d..1d1559a8 100644 --- a/connections/implementation/mediums/wifi_direct.cc +++ b/connections/implementation/mediums/wifi_direct.cc @@ -14,12 +14,15 @@ #include "connections/implementation/mediums/wifi_direct.h" +#include #include #include #include #include #include "absl/strings/string_view.h" +#include "connections/implementation/bwu_handler.h" +#include "connections/implementation/mediums/wifi_direct_bwu_handler.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" #include "internal/platform/logging.h" @@ -307,5 +310,12 @@ bool WifiDirect::SetPreferredWifiDirectAuthType(WifiDirectAuthType auth_type) { return true; } +std::unique_ptr WifiDirect::CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback) { + MutexLock lock(&mutex_); + return std::make_unique( + this, std::move(incoming_connection_callback)); +} + } // namespace connections } // namespace nearby diff --git a/connections/implementation/mediums/wifi_direct.h b/connections/implementation/mediums/wifi_direct.h index e85d2e64..1ea6211d 100644 --- a/connections/implementation/mediums/wifi_direct.h +++ b/connections/implementation/mediums/wifi_direct.h @@ -19,6 +19,7 @@ #include #include "absl/base/thread_annotations.h" +#include "connections/implementation/bwu_handler.h" #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" @@ -110,6 +111,9 @@ class WifiDirect { // Sets the preferred WifiDirect auth type. bool SetPreferredWifiDirectAuthType(WifiDirectAuthType auth_type); + std::unique_ptr CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback); + private: mutable Mutex mutex_; static constexpr int kMaxConcurrentAcceptLoops = 5; diff --git a/connections/implementation/mediums/wifi_direct_bwu_handler.cc b/connections/implementation/mediums/wifi_direct_bwu_handler.cc index ad501815..5072e922 100644 --- a/connections/implementation/mediums/wifi_direct_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_direct_bwu_handler.cc @@ -23,7 +23,8 @@ #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" +#include "absl/base/nullability.h" +#include "connections/implementation/mediums/wifi_direct.h" #include "connections/implementation/mediums/wifi_direct_endpoint_channel.h" #include "connections/implementation/offline_frames.h" #include "connections/strategy.h" @@ -41,9 +42,10 @@ using ::location::nearby::connections::BandwidthUpgradeNegotiationFrame; using ::location::nearby::proto::connections::OperationResultCode; } // namespace WifiDirectBwuHandler::WifiDirectBwuHandler( - Mediums& mediums, IncomingConnectionCallback incoming_connection_callback) + WifiDirect* absl_nonnull wifi_direct_medium, + IncomingConnectionCallback incoming_connection_callback) : BaseBwuHandler(std::move(incoming_connection_callback)), - mediums_(mediums) {} + wifi_direct_medium_(*wifi_direct_medium) {} // Called by BWU initiator. Set up WifiDirect upgraded medium for this // endpoint, and returns an upgrade path info (ServiceName, Pin for Wifi WPS, diff --git a/connections/implementation/mediums/wifi_direct_bwu_handler.h b/connections/implementation/mediums/wifi_direct_bwu_handler.h index 2f6b86b9..6fec11d3 100644 --- a/connections/implementation/mediums/wifi_direct_bwu_handler.h +++ b/connections/implementation/mediums/wifi_direct_bwu_handler.h @@ -18,11 +18,11 @@ #include #include +#include "absl/base/nullability.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/wifi_direct.h" #include "internal/platform/expected.h" #include "internal/platform/wifi_direct.h" @@ -34,8 +34,8 @@ namespace connections { // per-Medium-specific operations needed to upgrade an EndpointChannel. class WifiDirectBwuHandler : public BaseBwuHandler { public: - explicit WifiDirectBwuHandler( - Mediums& mediums, + WifiDirectBwuHandler( + WifiDirect* absl_nonnull wifi_direct_medium, IncomingConnectionCallback incoming_connection_callback); private: @@ -85,8 +85,7 @@ class WifiDirectBwuHandler : public BaseBwuHandler { const std::string& upgrade_service_id, WifiDirectSocket socket); - Mediums& mediums_; - WifiDirect& wifi_direct_medium_ = mediums_.GetWifiDirect(); + WifiDirect& wifi_direct_medium_; }; } // namespace connections diff --git a/connections/implementation/mediums/wifi_direct_bwu_handler_test.cc b/connections/implementation/mediums/wifi_direct_bwu_handler_test.cc index 00689ac9..fd3dccec 100644 --- a/connections/implementation/mediums/wifi_direct_bwu_handler_test.cc +++ b/connections/implementation/mediums/wifi_direct_bwu_handler_test.cc @@ -68,7 +68,8 @@ TEST_F(WifiDirectTest, CanCreateBwuHandler) { ClientProxy client; Mediums mediums; - auto handler = std::make_unique(mediums, nullptr); + auto handler = + std::make_unique(&mediums.GetWifiDirect(), nullptr); handler->InitializeUpgradedMediumForEndpoint(&client, std::string(kServiceID), std::string(kEndpointID)); @@ -87,7 +88,7 @@ TEST_F(WifiDirectTest, WFDGOBWUInit_GCCreateEndpointChannel) { ExceptionOr upgrade_frame; auto wfd_go_bwu_handler = std::make_unique( - mediums_wfd_go, [&](ClientProxy* client, + &mediums_wfd_go.GetWifiDirect(), [&](ClientProxy* client, std::unique_ptr mutable_connection) { LOG(INFO) << "Server socket connection accept call back, Socket name: " @@ -113,7 +114,8 @@ TEST_F(WifiDirectTest, WFDGOBWUInit_GCCreateEndpointChannel) { EXPECT_TRUE(start_latch.Await(kWaitDuration).result()); EXPECT_FALSE(mediums_wfd_gc.GetWifiDirect().IsConnectedToGO()); std::unique_ptr wfd_gc_bwu_handler = - std::make_unique(mediums_wfd_gc, nullptr); + std::make_unique(&mediums_wfd_gc.GetWifiDirect(), + nullptr); wfd_gc_executor.Execute([&]() { UpgradePathInfo upgrade_path_info; diff --git a/connections/implementation/mediums/wifi_hotspot.cc b/connections/implementation/mediums/wifi_hotspot.cc index 6d91e27e..4701a176 100644 --- a/connections/implementation/mediums/wifi_hotspot.cc +++ b/connections/implementation/mediums/wifi_hotspot.cc @@ -15,6 +15,7 @@ #include "connections/implementation/mediums/wifi_hotspot.h" #include +#include #include #include #include @@ -22,12 +23,15 @@ #include "absl/strings/string_view.h" #include "absl/time/clock.h" #include "absl/time/time.h" +#include "connections/implementation/bwu_handler.h" +#include "connections/implementation/mediums/wifi_hotspot_bwu_handler.h" #include "internal/flags/nearby_flags.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" #include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" +#include "internal/platform/service_address.h" #include "internal/platform/wifi_credential.h" #include "internal/platform/wifi_hotspot.h" @@ -325,5 +329,12 @@ ErrorOr WifiHotspot::Connect( return socket; } +std::unique_ptr WifiHotspot::CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback) { + MutexLock lock(&mutex_); + return std::make_unique( + this, std::move(incoming_connection_callback)); +} + } // namespace connections } // namespace nearby diff --git a/connections/implementation/mediums/wifi_hotspot.h b/connections/implementation/mediums/wifi_hotspot.h index 11b0bd3e..06e622c9 100644 --- a/connections/implementation/mediums/wifi_hotspot.h +++ b/connections/implementation/mediums/wifi_hotspot.h @@ -21,6 +21,7 @@ #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" +#include "connections/implementation/bwu_handler.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" #include "internal/platform/multi_thread_executor.h" @@ -86,6 +87,9 @@ class WifiHotspot { HotspotCredentials* GetCredentials(absl::string_view service_id) ABSL_LOCKS_EXCLUDED(mutex_); + std::unique_ptr CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback); + private: mutable Mutex mutex_; static constexpr int kMaxConcurrentAcceptLoops = 5; diff --git a/connections/implementation/mediums/wifi_hotspot_bwu_handler.cc b/connections/implementation/mediums/wifi_hotspot_bwu_handler.cc index 95b457a7..77d14c0d 100644 --- a/connections/implementation/mediums/wifi_hotspot_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_hotspot_bwu_handler.cc @@ -27,11 +27,12 @@ #include #include +#include "absl/base/nullability.h" #include "absl/functional/bind_front.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/mediums/wifi_hotspot.h" #include "connections/implementation/mediums/wifi_hotspot_endpoint_channel.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" @@ -66,9 +67,10 @@ std::vector GatewayToAddressBytes(const std::string& gateway) { } // namespace WifiHotspotBwuHandler::WifiHotspotBwuHandler( - Mediums& mediums, IncomingConnectionCallback incoming_connection_callback) + WifiHotspot* absl_nonnull wifi_hotspot_medium, + IncomingConnectionCallback incoming_connection_callback) : BaseBwuHandler(std::move(incoming_connection_callback)), - mediums_(mediums) {} + wifi_hotspot_medium_(*wifi_hotspot_medium) {} // Called by BWU initiator. Set up WifiHotspot upgraded medium for this // endpoint, and returns a upgrade path info (SSID, Password, Gateway used as diff --git a/connections/implementation/mediums/wifi_hotspot_bwu_handler.h b/connections/implementation/mediums/wifi_hotspot_bwu_handler.h index 134c5cc2..1c3c8f83 100644 --- a/connections/implementation/mediums/wifi_hotspot_bwu_handler.h +++ b/connections/implementation/mediums/wifi_hotspot_bwu_handler.h @@ -18,11 +18,11 @@ #include #include +#include "absl/base/nullability.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/wifi_hotspot.h" #include "internal/platform/expected.h" #include "internal/platform/wifi_hotspot.h" @@ -34,8 +34,8 @@ namespace connections { // per-Medium-specific operations needed to upgrade an EndpointChannel. class WifiHotspotBwuHandler : public BaseBwuHandler { public: - explicit WifiHotspotBwuHandler( - Mediums& mediums, + WifiHotspotBwuHandler( + WifiHotspot* absl_nonnull wifi_hotspot_medium, IncomingConnectionCallback incoming_connection_callback); // BwuHandler implementation: @@ -77,8 +77,7 @@ class WifiHotspotBwuHandler : public BaseBwuHandler { const std::string& upgrade_service_id, WifiHotspotSocket socket); - Mediums& mediums_; - WifiHotspot& wifi_hotspot_medium_{mediums_.GetWifiHotspot()}; + WifiHotspot& wifi_hotspot_medium_; }; } // namespace connections diff --git a/connections/implementation/mediums/wifi_hotspot_bwu_handler_test.cc b/connections/implementation/mediums/wifi_hotspot_bwu_handler_test.cc index 03978050..fcd42428 100644 --- a/connections/implementation/mediums/wifi_hotspot_bwu_handler_test.cc +++ b/connections/implementation/mediums/wifi_hotspot_bwu_handler_test.cc @@ -69,7 +69,8 @@ TEST_F(WifiHotspotTest, CanCreateBwuHandler) { ClientProxy client; Mediums mediums; - auto handler = std::make_unique(mediums, nullptr); + auto handler = std::make_unique( + &mediums.GetWifiHotspot(), nullptr); handler->InitializeUpgradedMediumForEndpoint(&client, std::string(kServiceID), std::string(kEndpointID)); @@ -88,7 +89,7 @@ TEST_F(WifiHotspotTest, SoftAPBWUInit_STACreateEndpointChannel) { ExceptionOr upgrade_frame; auto handler_1 = std::make_unique( - mediums_HS_ap, [&](ClientProxy* client, + &mediums_HS_ap.GetWifiHotspot(), [&](ClientProxy* client, std::unique_ptr mutable_connection) { LOG(INFO) << "Server socket connection accept call back, Socket name: " @@ -117,7 +118,8 @@ TEST_F(WifiHotspotTest, SoftAPBWUInit_STACreateEndpointChannel) { // Wait till client_hotspot_ap started as hotspot and then connect to it EXPECT_TRUE(start_latch.Await(kWaitDuration).result()); std::unique_ptr handler_2 = - std::make_unique(mediums_HS_sta, nullptr); + std::make_unique(&mediums_HS_sta.GetWifiHotspot(), + nullptr); client_executor.Execute([&]() { UpgradePathInfo upgrade_path_info; diff --git a/connections/implementation/mediums/wifi_lan.cc b/connections/implementation/mediums/wifi_lan.cc index 51ae771a..d789590b 100644 --- a/connections/implementation/mediums/wifi_lan.cc +++ b/connections/implementation/mediums/wifi_lan.cc @@ -15,13 +15,16 @@ #include "connections/implementation/mediums/wifi_lan.h" #include +#include #include #include #include #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "connections/implementation/bwu_handler.h" #include "connections/implementation/mediums/utils.h" +#include "connections/implementation/mediums/wifi_lan_bwu_handler.h" #include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" @@ -517,5 +520,12 @@ int WifiLan::GeneratePort(const std::string& service_id, (uint_of_service_id_hash % (port_range.second - port_range.first)); } +std::unique_ptr WifiLan::CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback) { + MutexLock lock(&mutex_); + return std::make_unique( + this, std::move(incoming_connection_callback)); +} + } // namespace connections } // namespace nearby diff --git a/connections/implementation/mediums/wifi_lan.h b/connections/implementation/mediums/wifi_lan.h index 39a5cc6a..7d6e6cb1 100644 --- a/connections/implementation/mediums/wifi_lan.h +++ b/connections/implementation/mediums/wifi_lan.h @@ -16,6 +16,7 @@ #define CORE_INTERNAL_MEDIUMS_WIFI_LAN_H_ #include +#include #include #include @@ -23,6 +24,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/functional/any_invocable.h" +#include "connections/implementation/bwu_handler.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" #include "internal/platform/expected.h" @@ -114,6 +116,9 @@ class WifiLan { api::UpgradeAddressInfo GetUpgradeAddressCandidates( const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); + std::unique_ptr CreateBwuHandler( + BwuHandler::IncomingConnectionCallback incoming_connection_callback); + private: struct AdvertisingInfo { bool Empty() const { return nsd_service_infos.empty(); } diff --git a/connections/implementation/mediums/wifi_lan_bwu_handler.cc b/connections/implementation/mediums/wifi_lan_bwu_handler.cc index 7b6e5604..e29e2f99 100644 --- a/connections/implementation/mediums/wifi_lan_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_lan_bwu_handler.cc @@ -24,7 +24,8 @@ #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" +#include "absl/base/nullability.h" +#include "connections/implementation/mediums/wifi_lan.h" #include "connections/implementation/mediums/wifi_lan_endpoint_channel.h" #include "connections/implementation/offline_frames.h" #include "internal/platform/expected.h" @@ -42,9 +43,10 @@ using ::location::nearby::proto::connections::OperationResultCode; } // namespace WifiLanBwuHandler::WifiLanBwuHandler( - Mediums& mediums, IncomingConnectionCallback incoming_connection_callback) + WifiLan* absl_nonnull wifi_lan_medium, + IncomingConnectionCallback incoming_connection_callback) : BaseBwuHandler(std::move(incoming_connection_callback)), - mediums_(mediums) {} + wifi_lan_medium_(*wifi_lan_medium) {} // Called by BWU target. Retrieves a new medium info from incoming message, // and establishes connection over WifiLan using this info. diff --git a/connections/implementation/mediums/wifi_lan_bwu_handler.h b/connections/implementation/mediums/wifi_lan_bwu_handler.h index a94a0554..46c4c0a0 100644 --- a/connections/implementation/mediums/wifi_lan_bwu_handler.h +++ b/connections/implementation/mediums/wifi_lan_bwu_handler.h @@ -18,11 +18,11 @@ #include #include +#include "absl/base/nullability.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/wifi_lan.h" #include "internal/platform/expected.h" #include "internal/platform/wifi_lan.h" @@ -34,8 +34,8 @@ namespace connections { // per-Medium-specific operations needed to upgrade an EndpointChannel. class WifiLanBwuHandler : public BaseBwuHandler { public: - explicit WifiLanBwuHandler( - Mediums& mediums, + WifiLanBwuHandler( + WifiLan* absl_nonnull wifi_lan_medium, IncomingConnectionCallback incoming_connection_callback); // BwuHandler implementation: @@ -77,8 +77,7 @@ class WifiLanBwuHandler : public BaseBwuHandler { const std::string& upgrade_service_id, WifiLanSocket socket); - Mediums& mediums_; - WifiLan& wifi_lan_medium_{mediums_.GetWifiLan()}; + WifiLan& wifi_lan_medium_; }; } // namespace connections diff --git a/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc b/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc index ad03cd54..24074701 100644 --- a/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc +++ b/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc @@ -72,7 +72,8 @@ constexpr absl::string_view kEndpointId{"endpoint_id"}; class WifiLanBwuHandlerTest : public ::testing::Test { protected: WifiLanBwuHandlerTest() - : handler_(mediums_, incoming_connection_callback_.AsStdFunction()) {} + : handler_(&mediums_.GetWifiLan(), + incoming_connection_callback_.AsStdFunction()) {} Mediums mediums_; MockFunction Date: Thu, 21 May 2026 14:31:18 -0700 Subject: [PATCH 107/151] Create separate WebRtc Platform. PiperOrigin-RevId: 919258148 --- internal/platform/implementation/BUILD | 20 ++++++++++++ .../platform/implementation/webrtc_platform.h | 31 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 internal/platform/implementation/webrtc_platform.h diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index c122ef11..d6188d88 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -87,6 +87,26 @@ cc_library( ], ) +cc_library( + name = "webrtc_platform", + hdrs = [ + "webrtc_platform.h", + ], + compatible_with = ["//buildenv/target:non_prod"], + visibility = [ + "//:__subpackages__", + ], + deps = [ + ":comm", + "//connections/implementation/proto:offline_wire_formats_cc_proto", + "//internal/platform:base", + # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/strings:string_view", + ], +) + cc_library( name = "comm", hdrs = [ diff --git a/internal/platform/implementation/webrtc_platform.h b/internal/platform/implementation/webrtc_platform.h new file mode 100644 index 00000000..6fdc3bbe --- /dev/null +++ b/internal/platform/implementation/webrtc_platform.h @@ -0,0 +1,31 @@ +// Copyright 2026 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 PLATFORM_API_WEBRTC_PLATFORM_H_ +#define PLATFORM_API_WEBRTC_PLATFORM_H_ + +#include + +#include "internal/platform/implementation/webrtc.h" + +namespace nearby::api { + +class WebRtcImplementationPlatform { + public: + static std::unique_ptr CreateWebRtcMedium(); +}; + +} // namespace nearby::api + +#endif // PLATFORM_API_WEBRTC_PLATFORM_H_ From 765bd555e4ae66665c282df351746e3317a23ee7 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 21 May 2026 15:05:31 -0700 Subject: [PATCH 108/151] Create separate WebRtc Platform. PiperOrigin-RevId: 919274513 --- Package.swift | 1 + internal/platform/implementation/apple/BUILD | 12 +++++++ .../platform/implementation/apple/Tests/BUILD | 2 ++ .../apple/Tests/GNCPlatformTest.mm | 3 +- .../platform/implementation/apple/platform.mm | 10 ------ .../implementation/apple/webrtc_platform.mm | 31 +++++++++++++++++++ 6 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 internal/platform/implementation/apple/webrtc_platform.mm diff --git a/Package.swift b/Package.swift index 973d26c5..09c96c3e 100644 --- a/Package.swift +++ b/Package.swift @@ -476,6 +476,7 @@ let package = Package( "internal/platform/implementation/apple/mutex_test.cc", "internal/platform/implementation/apple/atomic_boolean_test.cc", "internal/platform/implementation/apple/atomic_uint32_test.cc", + "internal/platform/implementation/apple/webrtc_platform.mm", "internal/platform/implementation/shared/file_test.cc", "internal/platform/implementation/wifi_utils_test.cc", "internal/platform/atomic_boolean_test.cc", diff --git a/internal/platform/implementation/apple/BUILD b/internal/platform/implementation/apple/BUILD index 55875c7b..6e4b01d9 100644 --- a/internal/platform/implementation/apple/BUILD +++ b/internal/platform/implementation/apple/BUILD @@ -51,6 +51,17 @@ objc_library( ], ) +objc_library( + name = "apple_webrtc", + srcs = [ + "webrtc_platform.mm", + ], + deps = [ + ":apple", + "//internal/platform/implementation:webrtc_platform", + ], +) + objc_library( name = "apple", srcs = [ @@ -102,6 +113,7 @@ objc_library( "//internal/base:file_path", "//internal/base:files", "//internal/base:masker", + "//internal/platform/implementation/apple/Flags", "//internal/platform/implementation/apple/Mediums/Hotspot", "//internal/account", "//internal/crypto_cros", diff --git a/internal/platform/implementation/apple/Tests/BUILD b/internal/platform/implementation/apple/Tests/BUILD index b27b3c4b..32369963 100644 --- a/internal/platform/implementation/apple/Tests/BUILD +++ b/internal/platform/implementation/apple/Tests/BUILD @@ -56,8 +56,10 @@ objc_library( "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", "//internal/platform/implementation:types", + "//internal/platform/implementation:webrtc_platform", "//internal/platform/implementation/apple", # buildcleaner: keep "//internal/platform/implementation/apple:Shared", + "//internal/platform/implementation/apple:apple_webrtc", # buildcleaner: keep "//internal/platform/implementation/apple:ble_v2", "//internal/platform/implementation/apple:network_utils", "//internal/platform/implementation/apple/Flags", diff --git a/internal/platform/implementation/apple/Tests/GNCPlatformTest.mm b/internal/platform/implementation/apple/Tests/GNCPlatformTest.mm index cfaaebac..22afb8c1 100644 --- a/internal/platform/implementation/apple/Tests/GNCPlatformTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCPlatformTest.mm @@ -13,6 +13,7 @@ // limitations under the License. #include "internal/platform/implementation/platform.h" +#include "internal/platform/implementation/webrtc_platform.h" #import #import @@ -320,7 +321,7 @@ void GNCEnsureFileAtPath(std::string path) { } - (void)testCreateWebRtcMedium { - auto webrtc_medium = nearby::api::ImplementationPlatform::CreateWebRtcMedium(); + auto webrtc_medium = nearby::api::WebRtcImplementationPlatform::CreateWebRtcMedium(); XCTAssertNotEqual(webrtc_medium.get(), nullptr); } diff --git a/internal/platform/implementation/apple/platform.mm b/internal/platform/implementation/apple/platform.mm index 5f95d4d6..e11b524b 100644 --- a/internal/platform/implementation/apple/platform.mm +++ b/internal/platform/implementation/apple/platform.mm @@ -45,10 +45,6 @@ #include "internal/platform/implementation/shared/file.h" #include "internal/platform/payload_id.h" -#ifndef NO_WEBRTC -#import "internal/platform/implementation/apple/webrtc.h" -#endif - namespace nearby { namespace api { @@ -205,12 +201,6 @@ std::unique_ptr ImplementationPlatform::CreateWifiDirectMedium return nullptr; } -#ifndef NO_WEBRTC -std::unique_ptr ImplementationPlatform::CreateWebRtcMedium() { - return std::make_unique(); -} -#endif - std::unique_ptr ImplementationPlatform::CreateAppLifecycleMonitor( std::function state_updated_callback) { #if TARGET_OS_IPHONE diff --git a/internal/platform/implementation/apple/webrtc_platform.mm b/internal/platform/implementation/apple/webrtc_platform.mm new file mode 100644 index 00000000..7cec489b --- /dev/null +++ b/internal/platform/implementation/apple/webrtc_platform.mm @@ -0,0 +1,31 @@ +// Copyright 2026 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. + +#include "internal/platform/implementation/webrtc_platform.h" + +#import + +#include + +#import "internal/platform/implementation/apple/webrtc.h" + +namespace nearby { +namespace api { + +std::unique_ptr WebRtcImplementationPlatform::CreateWebRtcMedium() { + return std::make_unique(); +} + +} // namespace api +} // namespace nearby From 5df1af7c613a202953cc4ed37f319728ae838ff9 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 21 May 2026 15:25:31 -0700 Subject: [PATCH 109/151] Create separate WebRtc Platform. PiperOrigin-RevId: 919283950 --- .../implementation/mediums/webrtc/BUILD | 3 +- .../implementation/mediums/webrtc/webrtc.h | 12 +++---- internal/platform/BUILD | 3 +- internal/platform/implementation/BUILD | 6 +--- internal/platform/implementation/apple/BUILD | 21 ++++++++---- internal/platform/implementation/g3/BUILD | 6 +++- .../platform/implementation/g3/platform.cc | 18 +--------- .../implementation/g3/webrtc_platform.cc | 34 +++++++++++++++++++ internal/platform/implementation/platform.h | 6 ---- internal/platform/implementation/webrtc.h | 5 +-- .../platform/implementation/windows/BUILD | 3 ++ .../implementation/windows/platform.cc | 4 --- internal/platform/medium_environment.cc | 5 +-- internal/platform/medium_environment.h | 8 ----- 14 files changed, 69 insertions(+), 65 deletions(-) create mode 100644 internal/platform/implementation/g3/webrtc_platform.cc diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index c1d34862..916d5de8 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -93,8 +93,7 @@ cc_library( hdrs = ["webrtc.h"], deps = [ "//internal/platform:base", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:platform", + "//internal/platform/implementation:webrtc_platform", # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", "@com_google_absl//absl/strings:string_view", diff --git a/connections/implementation/mediums/webrtc/webrtc.h b/connections/implementation/mediums/webrtc/webrtc.h index adccaa55..27055b4d 100644 --- a/connections/implementation/mediums/webrtc/webrtc.h +++ b/connections/implementation/mediums/webrtc/webrtc.h @@ -23,8 +23,8 @@ #include "absl/strings/string_view.h" #include "internal/platform/byte_array.h" #include "internal/platform/feature_flags.h" -#include "internal/platform/implementation/platform.h" #include "internal/platform/implementation/webrtc.h" +#include "internal/platform/implementation/webrtc_platform.h" #include "webrtc/api/peer_connection_interface.h" #include "webrtc/rtc_base/network_constants.h" @@ -66,7 +66,8 @@ class WebRtcSignalingMessenger { class WebRtcMedium { public: - WebRtcMedium() : impl_(api::ImplementationPlatform::CreateWebRtcMedium()) {} + WebRtcMedium() + : impl_(api::WebRtcImplementationPlatform::CreateWebRtcMedium()) {} virtual ~WebRtcMedium() = default; WebRtcMedium(WebRtcMedium&&) = default; WebRtcMedium& operator=(WebRtcMedium&&) = delete; @@ -75,9 +76,7 @@ class WebRtcMedium { // For example, en_US locale resolves to "US". std::string GetDefaultCountryCode() { return impl_->GetDefaultCountryCode(); } - void SetNonCellular(bool non_cellular) { - non_cellular_ = non_cellular; - } + void SetNonCellular(bool non_cellular) { non_cellular_ = non_cellular; } // Creates and returns a new webrtc::PeerConnectionInterface object via // |callback|. @@ -86,7 +85,8 @@ class WebRtcMedium { api::WebRtcMedium::PeerConnectionCallback callback) { if (FeatureFlags::GetInstance() .GetFlags() - .support_web_rtc_non_cellular_medium && non_cellular_) { + .support_web_rtc_non_cellular_medium && + non_cellular_) { std::optional options; options->network_ignore_mask |= webrtc::ADAPTER_TYPE_CELLULAR; impl_->CreatePeerConnection(options, observer, std::move(callback)); diff --git a/internal/platform/BUILD b/internal/platform/BUILD index e293cc42..76beadde 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -299,7 +299,7 @@ cc_library( ":logging", ":types", "//internal/account", - "//internal/platform/implementation:comm", + "//internal/platform/implementation:webrtc_platform", "//internal/proto:messaging_cc_grpc_proto", "//internal/proto:tachyon_cc_proto", "//internal/rpc:utils", @@ -411,6 +411,7 @@ cc_library( ":uuid", "//internal/base", "//internal/platform/implementation:comm", + "//internal/platform/implementation:webrtc_platform", "//internal/platform/implementation:wifi_utils", "//internal/test", "@com_google_absl//absl/base:core_headers", diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index d6188d88..65ed9747 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -90,6 +90,7 @@ cc_library( cc_library( name = "webrtc_platform", hdrs = [ + "webrtc.h", "webrtc_platform.h", ], compatible_with = ["//buildenv/target:non_prod"], @@ -97,7 +98,6 @@ cc_library( "//:__subpackages__", ], deps = [ - ":comm", "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/platform:base", # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", @@ -120,7 +120,6 @@ cc_library( "http_loader.h", "psk_info.h", "upgrade_address_info.h", - "webrtc.h", "wifi.h", "wifi_direct.h", "wifi_hotspot.h", @@ -136,15 +135,12 @@ cc_library( "//third_party/nearby/presence/implementation:__subpackages__", ], deps = [ - "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/platform:base", "//internal/platform:cancellation_flag", "//internal/platform:mac_address", "//internal/platform:uuid", "//internal/proto:credential_cc_proto", "//internal/proto:local_credential_cc_proto", - # "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep - # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/functional:any_invocable", diff --git a/internal/platform/implementation/apple/BUILD b/internal/platform/implementation/apple/BUILD index 6e4b01d9..7c48f36b 100644 --- a/internal/platform/implementation/apple/BUILD +++ b/internal/platform/implementation/apple/BUILD @@ -54,11 +54,24 @@ objc_library( objc_library( name = "apple_webrtc", srcs = [ + "webrtc.mm", "webrtc_platform.mm", ], + hdrs = [ + "webrtc.h", + ], deps = [ - ":apple", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", + "//third_party/apple_frameworks:Foundation", + "//internal/platform:logging", + "//internal/platform:tachyon_express_signaling_messenger", + "//internal/platform:types", "//internal/platform/implementation:webrtc_platform", + "//internal/proto:tachyon_cc_proto", + # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", + # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + "//third_party/webrtc/files/stable/webrtc/api/task_queue:default_task_queue_factory", ], ) @@ -72,7 +85,6 @@ objc_library( "preferences_manager.mm", "scheduled_executor.mm", "timer.mm", - "webrtc.mm", "wifi_hotspot.mm", "wifi_lan.mm", ], @@ -81,7 +93,6 @@ objc_library( "device_info.h", "preferences_manager.h", "timer.h", - "webrtc.h", "wifi.h", "wifi_hotspot.h", "wifi_lan.h", @@ -122,10 +133,6 @@ objc_library( "//internal/platform:tachyon_express_signaling_messenger", "//internal/platform:types", "//internal/proto:tachyon_cc_proto", - "//third_party/webrtc/files/stable/webrtc/api/task_queue:default_task_queue_factory", - # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", - "//third_party/webrtc/files/stable/webrtc/rtc_base:checks", "//internal/platform:base", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index 4fee0569..b50a8ea8 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -112,6 +112,7 @@ cc_library( "//internal/platform:types", "//internal/platform:uuid", "//internal/platform/implementation:comm", + "//internal/platform/implementation:webrtc_platform", "//internal/platform/implementation:wifi_utils", "//internal/proto:credential_cc_proto", # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", @@ -177,6 +178,7 @@ cc_library( testonly = True, srcs = [ "platform.cc", + "webrtc_platform.cc", ], defines = ["NO_WEBRTC"], visibility = [ @@ -208,14 +210,16 @@ cc_library( "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", "//internal/platform/implementation:types", + "//internal/platform/implementation:webrtc_platform", "//internal/platform/implementation/shared:count_down_latch", "//internal/platform/implementation/shared:file", + "//third_party/gloop/thread", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", - "@com_google_nisaba//nisaba/port:thread_pool", ], + alwayslink = 1, ) cc_library( diff --git a/internal/platform/implementation/g3/platform.cc b/internal/platform/implementation/g3/platform.cc index 02c5afda..dfa62fae 100644 --- a/internal/platform/implementation/g3/platform.cc +++ b/internal/platform/implementation/g3/platform.cc @@ -14,7 +14,6 @@ #include "internal/platform/implementation/platform.h" -#include #include #include #include @@ -25,6 +24,7 @@ #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" +#include "third_party/gloop/thread/thread.h" #include "internal/base/file_path.h" #include "internal/base/files.h" #include "internal/platform/implementation/app_lifecycle_monitor.h" @@ -55,11 +55,6 @@ #include "internal/platform/logging.h" #include "internal/platform/os_name.h" #include "internal/platform/payload_id.h" -#include "thread/thread.h" -#ifndef NO_WEBRTC -#include "internal/platform/implementation/g3/webrtc.h" -#include "internal/platform/implementation/webrtc.h" -#endif #include "internal/platform/implementation/g3/atomic_boolean.h" #include "internal/platform/implementation/g3/atomic_reference.h" #include "internal/platform/implementation/g3/ble.h" @@ -80,7 +75,6 @@ #include "internal/platform/implementation/g3/wifi_lan.h" #include "internal/platform/implementation/shared/file.h" #include "internal/platform/implementation/wifi.h" -#include "internal/platform/medium_environment.h" namespace nearby { namespace api { @@ -219,16 +213,6 @@ ImplementationPlatform::CreateWifiDirectMedium() { return std::make_unique(); } -#ifndef NO_WEBRTC -std::unique_ptr ImplementationPlatform::CreateWebRtcMedium() { - if (MediumEnvironment::Instance().GetEnvironmentConfig().webrtc_enabled) { - return std::make_unique(); - } else { - return nullptr; - } -} -#endif - std::unique_ptr ImplementationPlatform::CreateAppLifecycleMonitor( std::function diff --git a/internal/platform/implementation/g3/webrtc_platform.cc b/internal/platform/implementation/g3/webrtc_platform.cc new file mode 100644 index 00000000..5c42f5ee --- /dev/null +++ b/internal/platform/implementation/g3/webrtc_platform.cc @@ -0,0 +1,34 @@ +// Copyright 2026 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. + +#include "internal/platform/implementation/webrtc_platform.h" + +#include + +#include "internal/platform/implementation/g3/webrtc.h" +#include "internal/platform/implementation/webrtc.h" +#include "internal/platform/medium_environment.h" + +namespace nearby::api { + +std::unique_ptr +WebRtcImplementationPlatform::CreateWebRtcMedium() { + if (MediumEnvironment::Instance().GetEnvironmentConfig().webrtc_enabled) { + return std::make_unique(); + } else { + return nullptr; + } +} + +} // namespace nearby::api diff --git a/internal/platform/implementation/platform.h b/internal/platform/implementation/platform.h index 8cce972e..44ee1851 100644 --- a/internal/platform/implementation/platform.h +++ b/internal/platform/implementation/platform.h @@ -43,9 +43,6 @@ #include "internal/platform/implementation/scheduled_executor.h" #include "internal/platform/implementation/submittable_executor.h" #include "internal/platform/implementation/timer.h" -#ifndef NO_WEBRTC -#include "internal/platform/implementation/webrtc.h" -#endif #include "internal/platform/implementation/wifi.h" #include "internal/platform/implementation/wifi_direct.h" #include "internal/platform/implementation/wifi_hotspot.h" @@ -134,9 +131,6 @@ class ImplementationPlatform { static std::unique_ptr CreateWifiHotspotMedium(); static std::unique_ptr CreateWifiDirectMedium(); static std::unique_ptr CreateTimer(); -#ifndef NO_WEBRTC - static std::unique_ptr CreateWebRtcMedium(); -#endif #if defined(NEARBY_CHROMIUM) static std::unique_ptr CreateAppLifecycleMonitor( diff --git a/internal/platform/implementation/webrtc.h b/internal/platform/implementation/webrtc.h index 57bd14d7..c9022e28 100644 --- a/internal/platform/implementation/webrtc.h +++ b/internal/platform/implementation/webrtc.h @@ -15,8 +15,6 @@ #ifndef PLATFORM_API_WEBRTC_H_ #define PLATFORM_API_WEBRTC_H_ -#ifndef NO_WEBRTC - #include #include #include @@ -26,6 +24,7 @@ #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "internal/platform/byte_array.h" #include "webrtc/api/peer_connection_interface.h" +#include "webrtc/api/scoped_refptr.h" namespace nearby { namespace api { @@ -78,6 +77,4 @@ class WebRtcMedium { } // namespace api } // namespace nearby -#endif - #endif // PLATFORM_API_WEBRTC_H_ diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 077a83b7..7cc639f6 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -321,6 +321,9 @@ cc_library( "-DNO_INTEL_PIE", "-D_WIN32_WINNT=_WIN32_WINNT_WIN10 -DWINVER=_WIN32_WINNT_WIN10", ], + linkopts = [ + "iphlpapi.lib", + ], tags = ["windows"], visibility = [ "//chrome/chromeos/assistant/data_migration/lib:__pkg__", diff --git a/internal/platform/implementation/windows/platform.cc b/internal/platform/implementation/windows/platform.cc index 4d896be9..20004c26 100644 --- a/internal/platform/implementation/windows/platform.cc +++ b/internal/platform/implementation/windows/platform.cc @@ -259,10 +259,6 @@ ImplementationPlatform::CreateWifiDirectMedium() { return std::make_unique(); } -std::unique_ptr ImplementationPlatform::CreateWebRtcMedium() { - return nullptr; -} - std::unique_ptr ImplementationPlatform::CreateAppLifecycleMonitor( std::function diff --git a/internal/platform/medium_environment.cc b/internal/platform/medium_environment.cc index 3f1617b0..b0e9b98c 100644 --- a/internal/platform/medium_environment.cc +++ b/internal/platform/medium_environment.cc @@ -103,10 +103,8 @@ void MediumEnvironment::Reset() { bluetooth_adapters_.clear(); bluetooth_mediums_.clear(); ble_mediums_.clear(); -#ifndef NO_WEBRTC webrtc_signaling_message_callback_.clear(); webrtc_signaling_complete_callback_.clear(); -#endif wifi_lan_mediums_.clear(); awdl_mediums_.clear(); { @@ -675,7 +673,6 @@ MediumEnvironment::GetBleMediumStatus(const api::ble::BleMedium& medium) { return result; } -#ifndef NO_WEBRTC void MediumEnvironment::RegisterWebRtcSignalingMessenger( absl::string_view self_id, OnSignalingMessageCallback message_callback, OnSignalingCompleteCallback complete_callback) { @@ -733,7 +730,7 @@ void MediumEnvironment::SendWebRtcSignalingComplete(absl::string_view peer_id, item->second(success); }); } -#endif + void MediumEnvironment::SetUseValidPeerConnection( bool use_valid_peer_connection) { use_valid_peer_connection_ = use_valid_peer_connection; diff --git a/internal/platform/medium_environment.h b/internal/platform/medium_environment.h index 3a345a5a..8a4d7e14 100644 --- a/internal/platform/medium_environment.h +++ b/internal/platform/medium_environment.h @@ -37,9 +37,7 @@ #include "internal/platform/runnable.h" #include "internal/platform/uuid.h" #include "internal/test/fake_clock.h" -#ifndef NO_WEBRTC #include "internal/platform/implementation/webrtc.h" -#endif #include "internal/platform/byte_array.h" #include "internal/platform/feature_flags.h" #include "internal/platform/implementation/wifi_direct.h" @@ -80,12 +78,10 @@ class MediumEnvironment { using BluetoothDiscoveryCallback = api::BluetoothClassicMedium::DiscoveryCallback; using BleScanCallback = api::ble::BleMedium::ScanningCallback; -#ifndef NO_WEBRTC using OnSignalingMessageCallback = api::WebRtcSignalingMessenger::OnSignalingMessageCallback; using OnSignalingCompleteCallback = api::WebRtcSignalingMessenger::OnSignalingCompleteCallback; -#endif using WifiLanDiscoveredServiceCallback = api::WifiLanMedium::DiscoveredServiceCallback; using AwdlDiscoveredServiceCallback = @@ -164,7 +160,6 @@ class MediumEnvironment { api::BluetoothDevice* FindBluetoothDevice(MacAddress mac_address); EnvironmentConfig GetEnvironmentConfig(); -#ifndef NO_WEBRTC // Registers |message_callback| to receive messages sent to device with id // |self_id|, and |complete_callback| to notify when signaling is complete. void RegisterWebRtcSignalingMessenger( @@ -181,7 +176,6 @@ class MediumEnvironment { // Simulates sending an "signaling complete" signal to the WebRTC medium. void SendWebRtcSignalingComplete(absl::string_view peer_id, bool success); -#endif // Used to set if WebRtcMedium should use a valid peer connection or nullptr // in tests. void SetUseValidPeerConnection(bool use_valid_peer_connection); @@ -497,7 +491,6 @@ class MediumEnvironment { absl::flat_hash_map ble_mediums_; absl::flat_hash_map devices_pairing_contexts_; -#ifndef NO_WEBRTC // Maps peer id to callback for receiving signaling messages. absl::flat_hash_map webrtc_signaling_message_callback_; @@ -505,7 +498,6 @@ class MediumEnvironment { // Maps peer id to callback for signaling complete events. absl::flat_hash_map webrtc_signaling_complete_callback_; -#endif absl::flat_hash_map wifi_lan_mediums_; From 5ed4488cf51d5e9dee76c0e4202c48a052d17a36 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 21 May 2026 16:20:55 -0700 Subject: [PATCH 110/151] internal PiperOrigin-RevId: 919310819 --- connections/implementation/mediums/BUILD | 2 -- connections/implementation/mediums/webrtc/BUILD | 3 ++- .../implementation/mediums/webrtc/webrtc_bwu_handler.cc | 4 ++-- .../mediums/{ => webrtc}/webrtc_endpoint_channel.cc | 2 +- .../mediums/{ => webrtc}/webrtc_endpoint_channel.h | 6 +++--- 5 files changed, 8 insertions(+), 9 deletions(-) rename connections/implementation/mediums/{ => webrtc}/webrtc_endpoint_channel.cc (94%) rename connections/implementation/mediums/{ => webrtc}/webrtc_endpoint_channel.h (86%) diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index f0af9ba8..2bb183de 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -31,7 +31,6 @@ cc_library( "bluetooth_endpoint_channel.cc", "bluetooth_radio.cc", "mediums.cc", - "webrtc_endpoint_channel.cc", "wifi_direct.cc", "wifi_direct_bwu_handler.cc", "wifi_direct_endpoint_channel.cc", @@ -54,7 +53,6 @@ cc_library( "bluetooth_endpoint_channel.h", "bluetooth_radio.h", "mediums.h", - "webrtc_endpoint_channel.h", "wifi.h", "wifi_direct.h", "wifi_direct_bwu_handler.h", diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index 916d5de8..435ed413 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -104,10 +104,12 @@ cc_library( name = "webrtc_impl", srcs = [ "webrtc_bwu_handler.cc", + "webrtc_endpoint_channel.cc", "webrtc_impl.cc", ], hdrs = [ "webrtc_bwu_handler.h", + "webrtc_endpoint_channel.h", "webrtc_impl.h", ], visibility = [ @@ -123,7 +125,6 @@ cc_library( "//connections/implementation:client_proxy", "//connections/implementation:endpoint_channel", "//connections/implementation:offline_frames", - "//connections/implementation/mediums", "//connections/implementation/mediums:webrtc", "//connections/implementation/mediums:webrtc_peer_id", "//connections/implementation/mediums:webrtc_socket", diff --git a/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc index 8b041220..33d898ec 100644 --- a/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc +++ b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc @@ -18,13 +18,13 @@ #include #include +#include "absl/base/nullability.h" #include "absl/functional/bind_front.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "absl/base/nullability.h" #include "connections/implementation/mediums/webrtc.h" -#include "connections/implementation/mediums/webrtc_endpoint_channel.h" +#include "connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h" #include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/mediums/webrtc_socket.h" #include "connections/implementation/offline_frames.h" diff --git a/connections/implementation/mediums/webrtc_endpoint_channel.cc b/connections/implementation/mediums/webrtc/webrtc_endpoint_channel.cc similarity index 94% rename from connections/implementation/mediums/webrtc_endpoint_channel.cc rename to connections/implementation/mediums/webrtc/webrtc_endpoint_channel.cc index e054c416..bf939ea5 100644 --- a/connections/implementation/mediums/webrtc_endpoint_channel.cc +++ b/connections/implementation/mediums/webrtc/webrtc_endpoint_channel.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/mediums/webrtc_endpoint_channel.h" +#include "connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h" #include #include diff --git a/connections/implementation/mediums/webrtc_endpoint_channel.h b/connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h similarity index 86% rename from connections/implementation/mediums/webrtc_endpoint_channel.h rename to connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h index e7d396d5..6ceff1c6 100644 --- a/connections/implementation/mediums/webrtc_endpoint_channel.h +++ b/connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_ENDPOINT_CHANNEL_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_ENDPOINT_CHANNEL_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_ENDPOINT_CHANNEL_H_ +#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_ENDPOINT_CHANNEL_H_ #include #include @@ -41,4 +41,4 @@ class WebRtcEndpointChannel final : public BaseEndpointChannel { } // namespace connections } // namespace nearby -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_ENDPOINT_CHANNEL_H_ +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_ENDPOINT_CHANNEL_H_ From e4f25b54c69ae9945fdf3e252c7a7c4590e3fd82 Mon Sep 17 00:00:00 2001 From: Nick Bourdakos Date: Thu, 21 May 2026 18:00:08 -0700 Subject: [PATCH 111/151] Internal PiperOrigin-RevId: 919352057 --- connections/implementation/BUILD | 5 +--- connections/implementation/mediums/BUILD | 2 -- .../implementation/mediums/webrtc/BUILD | 29 +++++++++---------- internal/platform/BUILD | 5 +--- internal/platform/implementation/BUILD | 6 ++-- internal/platform/implementation/apple/BUILD | 10 +++---- internal/platform/implementation/g3/BUILD | 10 ++++--- .../platform/implementation/windows/BUILD | 16 +++++----- 8 files changed, 37 insertions(+), 46 deletions(-) diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 9f820647..b3bbee2d 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -219,10 +219,7 @@ cc_library( "service_controller_router.h", "wifi_lan_service_info.h", ], - copts = [ - "-DCORE_ADAPTER_DLL", - "-DNO_WEBRTC", - ], + copts = ["-DCORE_ADAPTER_DLL"], visibility = [ "//chrome/chromeos/assistant/data_migration/lib:__pkg__", "//connections:__pkg__", diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index 2bb183de..29007461 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -64,7 +64,6 @@ cc_library( "wifi_lan_bwu_handler.h", "wifi_lan_endpoint_channel.h", ], - copts = ["-DNO_WEBRTC"], local_defines = select({ "//:webrtc_enabled": [], "//conditions:default": ["NO_WEBRTC"], @@ -155,7 +154,6 @@ cc_library( name = "utils", srcs = ["utils.cc"], hdrs = ["utils.h"], - copts = ["-DNO_WEBRTC"], visibility = [ "//connections/implementation:__pkg__", "//connections/implementation/mediums/advertisements:__pkg__", diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index 435ed413..dfca3a94 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -23,11 +23,10 @@ cc_library( "local_ice_candidate_listener.h", "session_description_wrapper.h", ], - copts = ["-DNO_WEBRTC"], deps = [ "//connections/implementation/mediums:webrtc_socket", "//internal/platform:base", - # "//third_party/webrtc/files/stable/webrtc/api:jsep", + "//third_party/webrtc/files/stable/webrtc/api:jsep", "@com_google_absl//absl/functional:any_invocable", ], ) @@ -45,11 +44,11 @@ cc_library( "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:types", - # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", - # "//third_party/webrtc/files/stable/webrtc/api:jsep", - # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - # "//third_party/webrtc/files/stable/webrtc/api:rtc_error", - # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", + "//third_party/webrtc/files/stable/webrtc/api:jsep", + "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/files/stable/webrtc/api:rtc_error", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", "//third_party/webrtc/files/stable/webrtc/rtc_base:refcount", "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", @@ -68,7 +67,7 @@ cc_library( "//connections/implementation/mediums:webrtc_peer_id", "//internal/platform:base", "//proto/mediums:web_rtc_signaling_frames_cc_proto", - # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", ], ) @@ -81,8 +80,8 @@ cc_library( "//internal/platform:base", "//internal/platform:logging", "//internal/platform:types", - # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", - # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/strings:string_view", ], @@ -94,7 +93,7 @@ cc_library( deps = [ "//internal/platform:base", "//internal/platform/implementation:webrtc_platform", - # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", "@com_google_absl//absl/strings:string_view", ], @@ -134,7 +133,7 @@ cc_library( "//internal/platform:logging", "//internal/platform:types", "//proto/mediums:web_rtc_signaling_frames_cc_proto", - # "//third_party/webrtc/files/stable/webrtc/api:jsep", + "//third_party/webrtc/files/stable/webrtc/api:jsep", "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/base:nullability", @@ -186,9 +185,9 @@ cc_test( "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation:platform_impl", - # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", - # "//third_party/webrtc/files/stable/webrtc/api:jsep", - # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", + "//third_party/webrtc/files/stable/webrtc/api:jsep", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", "//third_party/webrtc/files/stable/webrtc/rtc_base:refcount", "@com_github_protobuf_matchers//protobuf-matchers", diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 76beadde..2e56b1d8 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -340,10 +340,7 @@ cc_library( "wifi_hotspot.h", "wifi_lan.h", ], - copts = [ - "-DCORE_ADAPTER_DLL", - "-DNO_WEBRTC", - ], + copts = ["-DCORE_ADAPTER_DLL"], visibility = [ "//connections:__subpackages__", "//internal/platform/implementation:__subpackages__", diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 65ed9747..22a42037 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -100,8 +100,8 @@ cc_library( deps = [ "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/platform:base", - # "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/strings:string_view", ], @@ -125,7 +125,6 @@ cc_library( "wifi_hotspot.h", "wifi_lan.h", ], - copts = ["-DNO_WEBRTC"], visibility = [ "//connections/implementation:__subpackages__", "//internal/network:__subpackages__", @@ -157,7 +156,6 @@ cc_library( hdrs = [ "platform.h", ], - defines = ["NO_WEBRTC"], visibility = [ "//connections/implementation:__subpackages__", "//internal:__subpackages__", diff --git a/internal/platform/implementation/apple/BUILD b/internal/platform/implementation/apple/BUILD index 7c48f36b..35b153f3 100644 --- a/internal/platform/implementation/apple/BUILD +++ b/internal/platform/implementation/apple/BUILD @@ -61,17 +61,17 @@ objc_library( "webrtc.h", ], deps = [ - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "//third_party/apple_frameworks:Foundation", "//internal/platform:logging", "//internal/platform:tachyon_express_signaling_messenger", "//internal/platform:types", "//internal/platform/implementation:webrtc_platform", "//internal/proto:tachyon_cc_proto", - # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + "//third_party/apple_frameworks:Foundation", + "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", + "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "//third_party/webrtc/files/stable/webrtc/api/task_queue:default_task_queue_factory", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", ], ) diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index b50a8ea8..935599c0 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -85,6 +85,7 @@ cc_library( "bluetooth_adapter.cc", "bluetooth_classic.cc", "credential_storage_impl.cc", + "webrtc.cc", "wifi_direct.cc", "wifi_hotspot.cc", "wifi_lan.cc", @@ -96,6 +97,7 @@ cc_library( "bluetooth_classic.h", "credential_storage_impl.h", "socket_base.h", + "webrtc.h", "wifi.h", "wifi_direct.h", "wifi_hotspot.h", @@ -115,9 +117,10 @@ cc_library( "//internal/platform/implementation:webrtc_platform", "//internal/platform/implementation:wifi_utils", "//internal/proto:credential_cc_proto", - # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", - # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", + "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/rtc_base:checks", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", @@ -180,7 +183,6 @@ cc_library( "platform.cc", "webrtc_platform.cc", ], - defines = ["NO_WEBRTC"], visibility = [ "//connections:__subpackages__", "//connections:partners", diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 7cc639f6..860165bb 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -241,10 +241,10 @@ cc_library( "//internal/platform:logging", "//internal/platform:tachyon_express_signaling_messenger", "//internal/platform/implementation:comm", - # "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", - # "//third_party/webrtc/files/stable/webrtc/api:rtc_error", - # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", + "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + "//third_party/webrtc/files/stable/webrtc/api:rtc_error", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", "@com_google_absl//absl/strings", ], @@ -444,10 +444,10 @@ cc_test( ":webrtc", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform_impl", - # "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", - # "//third_party/webrtc/files/stable/webrtc/api:jsep", - # "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", - # "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", + "//third_party/webrtc/files/stable/webrtc/api:jsep", + "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_googletest//:gtest_main", ], From 4c1b4490b755fb6e6d57ed94ed5b0201908a28de Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 21 May 2026 19:03:35 -0700 Subject: [PATCH 112/151] ...text exposed to open source public git repo... PiperOrigin-RevId: 919372916 --- proto/sharing_enums.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index 7adafdd3..88af80fc 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -845,6 +845,7 @@ enum SharingUseCase { USE_CASE_NEARBY_SHARE_WITH_QR_CODE = 7 [deprecated = true]; // The user was redirected from Bluetooth sharing UI to Nearby Share USE_CASE_REDIRECTED_FROM_BLUETOOTH_SHARE = 8; + USE_CASE_TAP_TO_SHARE = 9; } // Used only for Windows App now. From c9c7e6ee57f24ebb398570124939044481131288 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 22 May 2026 13:48:33 -0700 Subject: [PATCH 113/151] Delete contact management. PiperOrigin-RevId: 919842707 --- sharing/BUILD | 3 - sharing/contacts/BUILD | 84 ---------- .../fake_nearby_share_contact_manager.h | 36 ----- .../contacts/nearby_share_contact_manager.h | 46 ------ .../nearby_share_contact_manager_impl.cc | 150 ------------------ .../nearby_share_contact_manager_impl.h | 49 ------ .../nearby_share_contact_manager_impl_test.cc | 98 ------------ sharing/fake_nearby_sharing_service.cc | 4 - sharing/fake_nearby_sharing_service.h | 1 - sharing/nearby_sharing_service.h | 2 - sharing/nearby_sharing_service_factory.cc | 12 +- sharing/nearby_sharing_service_factory.h | 1 - sharing/nearby_sharing_service_impl.cc | 9 -- sharing/nearby_sharing_service_impl.h | 4 - sharing/nearby_sharing_service_impl_test.cc | 5 +- 15 files changed, 3 insertions(+), 501 deletions(-) delete mode 100644 sharing/contacts/BUILD delete mode 100644 sharing/contacts/fake_nearby_share_contact_manager.h delete mode 100644 sharing/contacts/nearby_share_contact_manager.h delete mode 100644 sharing/contacts/nearby_share_contact_manager_impl.cc delete mode 100644 sharing/contacts/nearby_share_contact_manager_impl.h delete mode 100644 sharing/contacts/nearby_share_contact_manager_impl_test.cc diff --git a/sharing/BUILD b/sharing/BUILD index 2533b34b..094d23a2 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -410,8 +410,6 @@ cc_library( "//sharing/certificates", "//sharing/common", "//sharing/common:enum", - "//sharing/contacts", - "//sharing/contacts:contacts_interface", "//sharing/fast_initiation:nearby_fast_initiation", "//sharing/flags/generated:generated_flags", "//sharing/internal/api:platform", @@ -668,7 +666,6 @@ cc_test( "//sharing/certificates:test_support", "//sharing/common", "//sharing/common:enum", - "//sharing/contacts:test_support", "//sharing/fast_initiation:nearby_fast_initiation", "//sharing/fast_initiation:test_support", "//sharing/flags/generated:generated_flags", diff --git a/sharing/contacts/BUILD b/sharing/contacts/BUILD deleted file mode 100644 index 0d489e88..00000000 --- a/sharing/contacts/BUILD +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2024 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. - -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -licenses(["notice"]) - -cc_library( - name = "contacts_interface", - hdrs = [ - "nearby_share_contact_manager.h", - ], - visibility = ["//visibility:public"], - deps = [ - "//sharing/proto:share_cc_proto", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status:statusor", - ], -) - -cc_library( - name = "contacts", - srcs = [ - "nearby_share_contact_manager_impl.cc", - ], - hdrs = [ - "nearby_share_contact_manager_impl.h", - ], - visibility = ["//visibility:public"], - deps = [ - ":contacts_interface", - "//internal/platform:types", - "//location/nearby/sharing/lib/account:account_manager", - "//location/nearby/sharing/lib/rpc:sharing_rpc_client", - "//sharing/internal/public:logging", - "//sharing/internal/public:types", - "//sharing/proto:share_cc_proto", - "@com_google_absl//absl/base:nullability", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/synchronization", - ], -) - -cc_library( - name = "test_support", - testonly = True, - hdrs = [ - "fake_nearby_share_contact_manager.h", - ], - visibility = ["//visibility:public"], - deps = [":contacts_interface"], -) - -cc_test( - name = "contacts_test", - srcs = [ - "nearby_share_contact_manager_impl_test.cc", - ], - deps = [ - ":contacts", - "//internal/platform/implementation:platform_impl", - "//location/nearby/sharing/lib/account:account_manager", - "//location/nearby/sharing/lib/account:fake_account_manager", - "//location/nearby/sharing/lib/rpc:fake_nearby_share_client", - "//sharing/internal/test:nearby_test", - "//sharing/local_device_data:test_support", - "//sharing/proto:share_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/sharing/contacts/fake_nearby_share_contact_manager.h b/sharing/contacts/fake_nearby_share_contact_manager.h deleted file mode 100644 index d52d0820..00000000 --- a/sharing/contacts/fake_nearby_share_contact_manager.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2021-2023 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_SHARING_CONTACTS_FAKE_NEARBY_SHARE_CONTACT_MANAGER_H_ -#define THIRD_PARTY_NEARBY_SHARING_CONTACTS_FAKE_NEARBY_SHARE_CONTACT_MANAGER_H_ - -#include "sharing/contacts/nearby_share_contact_manager.h" - -namespace nearby { -namespace sharing { - -// A fake implementation of NearbyShareContactManager. -class FakeNearbyShareContactManager : public NearbyShareContactManager { - public: - FakeNearbyShareContactManager() = default; - ~FakeNearbyShareContactManager() override = default; - - private: - void GetContacts(ContactsCallback callback) override {}; -}; - -} // namespace sharing -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_SHARING_CONTACTS_FAKE_NEARBY_SHARE_CONTACT_MANAGER_H_ diff --git a/sharing/contacts/nearby_share_contact_manager.h b/sharing/contacts/nearby_share_contact_manager.h deleted file mode 100644 index 81bf5f17..00000000 --- a/sharing/contacts/nearby_share_contact_manager.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2021-2023 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_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_H_ -#define THIRD_PARTY_NEARBY_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_H_ - -#include - -#include - -#include "absl/functional/any_invocable.h" -#include "absl/status/statusor.h" -#include "sharing/proto/rpc_resources.pb.h" - -namespace nearby { -namespace sharing { - -// The Nearby Share contacts manager retrieves the user's contact list from the -// server. -class NearbyShareContactManager { - public: - using ContactsCallback = absl::AnyInvocable< - void(absl::StatusOr>, - uint32_t num_unreachable_contacts_filtered_out) &&>; - - virtual ~NearbyShareContactManager() = default; - - // Retrieves the user's contact list from the server. - virtual void GetContacts(ContactsCallback callback) = 0; -}; - -} // namespace sharing -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_H_ diff --git a/sharing/contacts/nearby_share_contact_manager_impl.cc b/sharing/contacts/nearby_share_contact_manager_impl.cc deleted file mode 100644 index b0f7834e..00000000 --- a/sharing/contacts/nearby_share_contact_manager_impl.cc +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2023 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. - -#include "sharing/contacts/nearby_share_contact_manager_impl.h" - -#include - -#include -#include -#include -#include -#include -#include - -#include "location/nearby/sharing/lib/account/account_manager.h" -#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" -#include "absl/base/nullability.h" -#include "absl/status/statusor.h" -#include "absl/synchronization/notification.h" -#include "sharing/contacts/nearby_share_contact_manager.h" -#include "sharing/internal/public/context.h" -#include "sharing/internal/public/logging.h" -#include "sharing/proto/contact_rpc.pb.h" -#include "sharing/proto/rpc_resources.pb.h" - -namespace nearby::sharing { -namespace { - -using ::nearby::sharing::proto::ContactRecord; -using ::nearby::sharing::proto::ListContactPeopleRequest; -using ::nearby::sharing::proto::ListContactPeopleResponse; - -// Class for maintaining a single instance of contacts download request. It -// is responsible for downloading all available pages and making the results -// or error available. -class ContactDownloadContext { - public: - ContactDownloadContext( - nearby::sharing::api::SharingRpcClient* nearby_share_client, - NearbyShareContactManager::ContactsCallback download_callback) - : nearby_share_client_(nearby_share_client), - download_callback_(std::move(download_callback)) {} - - // Fetches the next page of contacts. - // If |next_page_token_| is empty, it fetches the first page. - // On successful download, if page token in the response is empty, the - // |download_callback_| is invoked with all downloaded contacts. - void FetchNextPage(); - - private: - nearby::sharing::api::SharingRpcClient* const nearby_share_client_; - std::optional next_page_token_; - int page_number_ = 1; - std::vector contacts_; - NearbyShareContactManager::ContactsCallback download_callback_; -}; - -void ContactDownloadContext::FetchNextPage() { - LOG(INFO) << "Downloading contacts page=" << page_number_++; - ListContactPeopleRequest request; - if (next_page_token_.has_value()) { - request.set_page_token(*next_page_token_); - } - nearby_share_client_->ListContactPeople( - std::move(request), - [this]( - const absl::StatusOr& response) mutable { - if (!response.ok()) { - LOG(WARNING) << "Failed to download contacts: " << response.status(); - std::move(download_callback_)( - response.status(), /*num_unreachable_contacts_filtered_out=*/0); - return; - } - - contacts_.insert(contacts_.end(), response->contact_records().begin(), - response->contact_records().end()); - - if (response->next_page_token().empty()) { - // We should filter here because we only care about contacts that we - // can share with. - uint32_t contacts_size = contacts_.size(); - // Filter out unreachable contacts. - contacts_.erase(std::remove_if(contacts_.begin(), contacts_.end(), - [](const ContactRecord& contact) { - return !contact.is_reachable(); - }), - contacts_.end()); - uint32_t num_unreachable_contacts_filtered_out = - contacts_size - contacts_.size(); - std::move(download_callback_)(std::move(contacts_), - num_unreachable_contacts_filtered_out); - return; - } - // Continue with next page. - next_page_token_ = response->next_page_token(); - FetchNextPage(); - }); -} - -} // namespace - -NearbyShareContactManagerImpl::NearbyShareContactManagerImpl( - Context* absl_nonnull context, AccountManager& account_manager, - nearby::sharing::api::SharingRpcClient* absl_nonnull nearby_client) - : account_manager_(account_manager), - nearby_share_client_(*nearby_client), - executor_(context->CreateSequencedTaskRunner()) {} - -void NearbyShareContactManagerImpl::GetContacts(ContactsCallback callback) { - executor_->PostTask([this, callback = std::move(callback)]() mutable { - LOG(INFO) << "Start downloading contacts"; - std::vector contacts; - if (!account_manager_.GetCurrentAccount().has_value()) { - LOG(WARNING) << "Ignore contacts download, no logged in account."; - std::move(callback)(contacts, - /*num_unreachable_contacts_filtered_out=*/0); - return; - } - - absl::Notification notification; - auto context = std::make_unique( - &nearby_share_client_, - [¬ification, callback = std::move(callback)]( - absl::StatusOr> - contacts, - uint32_t num_unreachable_contacts_filtered_out) mutable { - std::move(callback)(std::move(contacts), - num_unreachable_contacts_filtered_out); - notification.Notify(); - }); - context->FetchNextPage(); - // Wait for all pages of contacts to be downloaded. - // MUST not terminate early, otherwise notification will go out of scope, - // and the callback will call Notify on a destroyed object. - notification.WaitForNotification(); - }); -} - -} // namespace nearby::sharing diff --git a/sharing/contacts/nearby_share_contact_manager_impl.h b/sharing/contacts/nearby_share_contact_manager_impl.h deleted file mode 100644 index 16d38f87..00000000 --- a/sharing/contacts/nearby_share_contact_manager_impl.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2023 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_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_IMPL_H_ -#define THIRD_PARTY_NEARBY_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_IMPL_H_ - -#include - -#include "location/nearby/sharing/lib/account/account_manager.h" -#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" -#include "absl/base/nullability.h" -#include "internal/platform/task_runner.h" -#include "sharing/contacts/nearby_share_contact_manager.h" -#include "sharing/internal/public/context.h" - -namespace nearby::sharing { - -class NearbyShareContactManagerImpl : public NearbyShareContactManager { - public: - NearbyShareContactManagerImpl( - Context* absl_nonnull context, AccountManager& account_manager, - nearby::sharing::api::SharingRpcClient* absl_nonnull nearby_client); - - ~NearbyShareContactManagerImpl() override = default; - - private: - // NearbyShareContactsManager: - void GetContacts(ContactsCallback callback) override; - - AccountManager& account_manager_; - nearby::sharing::api::SharingRpcClient& nearby_share_client_; - - std::unique_ptr executor_ = nullptr; -}; - -} // namespace nearby::sharing - -#endif // THIRD_PARTY_NEARBY_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_IMPL_H_ diff --git a/sharing/contacts/nearby_share_contact_manager_impl_test.cc b/sharing/contacts/nearby_share_contact_manager_impl_test.cc deleted file mode 100644 index 837ceca3..00000000 --- a/sharing/contacts/nearby_share_contact_manager_impl_test.cc +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2023 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. - -#include "sharing/contacts/nearby_share_contact_manager_impl.h" - -#include -#include - -#include -#include -#include - -#include "location/nearby/sharing/lib/account/account_manager.h" -#include "location/nearby/sharing/lib/account/fake_account_manager.h" -#include "location/nearby/sharing/lib/rpc/fake_nearby_share_client.h" -#include "gtest/gtest.h" -#include "absl/time/time.h" -#include "sharing/internal/test/fake_context.h" -#include "sharing/local_device_data/fake_nearby_share_local_device_data_manager.h" -#include "sharing/proto/contact_rpc.pb.h" -#include "sharing/proto/rpc_resources.pb.h" - -namespace nearby::sharing { -namespace { - -using ::nearby::sharing::proto::ContactRecord; - -constexpr char kTestDefaultDeviceName[] = "Josh's Chromebook"; -constexpr char kTestProfileUserName[] = "test@google.com"; -constexpr char kTestAccountId[] = "test_account_id"; - -class NearbyShareContactManagerImplTest - : public ::testing::Test { - protected: - struct ContactsDownloadedNotification { - std::vector contacts; - uint32_t num_unreachable_contacts_filtered_out; - }; - struct ContactsUploadedNotification { - bool did_contacts_change_since_last_upload; - }; - - NearbyShareContactManagerImplTest() - : local_device_data_manager_(kTestDefaultDeviceName) {} - - ~NearbyShareContactManagerImplTest() override = default; - - void SetUp() override { - AccountManager::Account account; - account.id = kTestAccountId; - account.email = kTestProfileUserName; - fake_account_manager_.SetAccount(account); - - manager_ = std::make_unique( - &fake_context_, fake_account_manager_, &nearby_client_); - } - - void TearDown() override { - manager_.reset(); - } - - void Sync() { - EXPECT_TRUE(fake_context_.last_sequenced_task_runner()->SyncWithTimeout( - absl::Milliseconds(1000))); - } - - std::vector& - contacts_downloaded_notifications() { - return contacts_downloaded_notifications_; - } - - FakeContext& fake_context() { return fake_context_; } - - private: - FakeAccountManager fake_account_manager_; - FakeContext fake_context_; - std::vector - contacts_downloaded_notifications_; - std::vector contacts_uploaded_notifications_; - FakeNearbyShareClient nearby_client_; - FakeNearbyShareLocalDeviceDataManager local_device_data_manager_; - std::unique_ptr account_manager_; - std::unique_ptr manager_; -}; - -} // namespace -} // namespace nearby::sharing diff --git a/sharing/fake_nearby_sharing_service.cc b/sharing/fake_nearby_sharing_service.cc index c5975af4..416c4331 100644 --- a/sharing/fake_nearby_sharing_service.cc +++ b/sharing/fake_nearby_sharing_service.cc @@ -178,10 +178,6 @@ std::string FakeNearbySharingService::Dump() const { return ""; } NearbyShareSettings* FakeNearbySharingService::GetSettings() { return nullptr; } -NearbyShareContactManager* FakeNearbySharingService::GetContactManager() { - return nullptr; -} - NearbyShareCertificateManager* FakeNearbySharingService::GetCertificateManager() { return nullptr; diff --git a/sharing/fake_nearby_sharing_service.h b/sharing/fake_nearby_sharing_service.h index 4cd22969..57b0f05c 100644 --- a/sharing/fake_nearby_sharing_service.h +++ b/sharing/fake_nearby_sharing_service.h @@ -135,7 +135,6 @@ class FakeNearbySharingService : public NearbySharingService { void UpdateFilePathsInProgress(bool update_file_paths) override {} NearbyShareSettings* GetSettings() override; - NearbyShareContactManager* GetContactManager() override; NearbyShareCertificateManager* GetCertificateManager() override; AccountManager* GetAccountManager() override; Clock& GetClock() override; diff --git a/sharing/nearby_sharing_service.h b/sharing/nearby_sharing_service.h index da83f804..f657c968 100644 --- a/sharing/nearby_sharing_service.h +++ b/sharing/nearby_sharing_service.h @@ -36,7 +36,6 @@ namespace nearby::sharing { class AccountManager; class NearbyNotificationDelegate; -class NearbyShareContactManager; // This service implements Nearby Sharing on top of the Nearby Connections mojo. // Currently, only single profile will be allowed to be bound at a time and only @@ -222,7 +221,6 @@ class NearbySharingService { virtual void UpdateFilePathsInProgress(bool update_file_paths) = 0; virtual NearbyShareSettings* GetSettings() = 0; - virtual NearbyShareContactManager* GetContactManager() = 0; virtual NearbyShareCertificateManager* GetCertificateManager() = 0; virtual AccountManager* GetAccountManager() = 0; virtual Clock& GetClock() = 0; diff --git a/sharing/nearby_sharing_service_factory.cc b/sharing/nearby_sharing_service_factory.cc index 11e595ef..06ef08b3 100644 --- a/sharing/nearby_sharing_service_factory.cc +++ b/sharing/nearby_sharing_service_factory.cc @@ -21,7 +21,6 @@ #include "internal/analytics/event_logger.h" #include "internal/platform/task_runner.h" #include "sharing/analytics/analytics_recorder.h" -#include "sharing/contacts/nearby_share_contact_manager_impl.h" #include "sharing/internal/api/sharing_platform.h" #include "sharing/internal/public/context_impl.h" #include "sharing/nearby_connections_manager_factory.h" @@ -59,20 +58,13 @@ NearbySharingService* NearbySharingServiceFactory::CreateSharingService( std::make_unique( &sharing_platform.GetAccountManager(), context_->GetClock(), analytics_recorder); - nearby_share_client_ = nearby_share_client_factory_->CreateInstance(); nearby_identity_client_ = nearby_share_client_factory_->CreateIdentityInstance(); - auto nearby_share_contact_manager = - std::make_unique( - context_.get(), sharing_platform.GetAccountManager(), - nearby_share_client_.get()); nearby_sharing_service_ = std::make_unique( std::move(service_thread), context_.get(), sharing_platform, - nearby_identity_client_.get(), - std::move(nearby_connections_manager), - std::move(nearby_share_contact_manager), analytics_recorder, - supports_file_sync); + nearby_identity_client_.get(), std::move(nearby_connections_manager), + analytics_recorder, supports_file_sync); return nearby_sharing_service_.get(); } diff --git a/sharing/nearby_sharing_service_factory.h b/sharing/nearby_sharing_service_factory.h index 3fe117a9..6370de1d 100644 --- a/sharing/nearby_sharing_service_factory.h +++ b/sharing/nearby_sharing_service_factory.h @@ -45,7 +45,6 @@ class NearbySharingServiceFactory { std::unique_ptr nearby_sharing_service_; std::unique_ptr nearby_share_client_factory_; - std::unique_ptr nearby_share_client_; std::unique_ptr nearby_identity_client_; }; diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 0b22c96d..3f4e84f9 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -65,7 +65,6 @@ #include "sharing/common/nearby_share_enums.h" #include "sharing/common/nearby_share_prefs.h" #include "sharing/constants.h" -#include "sharing/contacts/nearby_share_contact_manager.h" #include "sharing/fast_initiation/nearby_fast_initiation.h" #include "sharing/fast_initiation/nearby_fast_initiation_impl.h" #include "sharing/file_attachment.h" @@ -260,7 +259,6 @@ NearbySharingServiceImpl::NearbySharingServiceImpl( nearby::sharing::api::IdentityRpcClient* absl_nonnull nearby_identity_client, std::unique_ptr nearby_connections_manager, - std::unique_ptr contact_manager, analytics::AnalyticsRecorder* analytics_recorder, bool supports_file_sync) : service_thread_(std::move(service_thread)), context_(context), @@ -274,7 +272,6 @@ NearbySharingServiceImpl::NearbySharingServiceImpl( local_device_data_manager_( NearbyShareLocalDeviceDataManagerImpl::Factory::Create( preference_manager_, account_manager_, device_info_)), - contact_manager_(std::move(contact_manager)), nearby_fast_initiation_( NearbyFastInitiationImpl::Factory::Create(context_)), settings_(std::make_unique( @@ -668,8 +665,6 @@ void NearbySharingServiceImpl::RegisterReceiveSurface( << background_receive_callbacks_map_.size(); if (IsVisibleInBackground(settings_->GetVisibility())) { - // The Identity API does not support contact manager which triggers - // Certificate refresh in DownloadContacts. Force upload explicitly. VLOG(1) << "[Call Identity API] ForceUploadPrivateCertificates."; certificate_manager_->ForceUploadPrivateCertificates(); } @@ -1028,10 +1023,6 @@ NearbyShareSettings* NearbySharingServiceImpl::GetSettings() { return settings_.get(); } -NearbyShareContactManager* NearbySharingServiceImpl::GetContactManager() { - return contact_manager_.get(); -} - NearbyShareCertificateManager* NearbySharingServiceImpl::GetCertificateManager() { return certificate_manager_.get(); diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index e0c04146..44841f00 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -79,7 +79,6 @@ #include "sharing/wrapped_share_target_discovered_callback.h" namespace nearby::sharing { -class NearbyShareContactManager; namespace NearbySharingServiceUnitTests { class NearbySharingServiceImplTest_CreateShareTarget_Test; @@ -108,7 +107,6 @@ class NearbySharingServiceImpl nearby::sharing::api::IdentityRpcClient* absl_nonnull nearby_identity_client, std::unique_ptr nearby_connections_manager, - std::unique_ptr contact_manager, analytics::AnalyticsRecorder* analytics_recorder, bool supports_file_sync); ~NearbySharingServiceImpl() override; @@ -164,7 +162,6 @@ class NearbySharingServiceImpl proto::DeviceVisibility visibility, absl::Duration expiration, absl::AnyInvocable callback) override; NearbyShareSettings* GetSettings() override; - NearbyShareContactManager* GetContactManager() override; NearbyShareCertificateManager* GetCertificateManager() override; AccountManager* GetAccountManager() override; Clock& GetClock() override { return *context_->GetClock(); } @@ -437,7 +434,6 @@ class NearbySharingServiceImpl nearby::sharing::api::IdentityRpcClient* absl_nonnull const nearby_identity_client_; std::unique_ptr local_device_data_manager_; - std::unique_ptr contact_manager_; std::unique_ptr certificate_manager_; std::unique_ptr nearby_fast_initiation_; diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index 91ef7624..6c05d4d6 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -64,7 +64,6 @@ #include "sharing/common/nearby_share_enums.h" #include "sharing/common/nearby_share_prefs.h" #include "sharing/constants.h" -#include "sharing/contacts/fake_nearby_share_contact_manager.h" #include "sharing/fake_nearby_connections_manager.h" #include "sharing/fast_initiation/fake_nearby_fast_initiation.h" #include "sharing/fast_initiation/nearby_fast_initiation_impl.h" @@ -430,7 +429,6 @@ class NearbySharingServiceImplTest : public testing::Test { auto fake_task_runner = std::make_unique(fake_context_.fake_clock(), 1); sharing_service_task_runner_ = fake_task_runner.get(); - contact_manager_ = new FakeNearbyShareContactManager(); fake_nearby_connections_manager_ = new FakeNearbyConnectionsManager(); connection_ = std::make_unique(fake_device_info_); fake_nearby_connections_manager_->set_send_payload_callback( @@ -487,7 +485,7 @@ class NearbySharingServiceImplTest : public testing::Test { std::move(task_runner), &fake_context_, mock_sharing_platform_, &nearby_identity_client_, absl::WrapUnique(fake_nearby_connections_manager_), - absl::WrapUnique(contact_manager_), analytics_recorder_.get(), + analytics_recorder_.get(), /*supports_file_sync=*/false); } @@ -1266,7 +1264,6 @@ class NearbySharingServiceImplTest : public testing::Test { FakeNearbyConnectionsManager* fake_nearby_connections_manager_ = nullptr; FakeNearbyShareLocalDeviceDataManager::Factory local_device_data_manager_factory_; - FakeNearbyShareContactManager* contact_manager_ = nullptr; FakeNearbyShareCertificateManager::Factory certificate_manager_factory_; std::unique_ptr nearby_fast_initiation_factory_; From b536c8da3ad69ae2dfe0d07f7c151daf8f77be64 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 22 May 2026 15:18:00 -0700 Subject: [PATCH 114/151] Move TachyonExpressSignallingMessenger into mediums/webrtc. PiperOrigin-RevId: 919882997 --- Package.swift | 4 +-- .../implementation/mediums/webrtc/BUILD | 31 ++++++++++++++++++ .../tachyon_express_signaling_messenger.cc | 11 ++----- .../tachyon_express_signaling_messenger.h | 16 +++------- internal/platform/BUILD | 32 ------------------- internal/platform/implementation/apple/BUILD | 3 +- .../platform/implementation/apple/webrtc.mm | 5 +-- .../platform/implementation/windows/BUILD | 4 +-- .../platform/implementation/windows/webrtc.cc | 4 ++- 9 files changed, 50 insertions(+), 60 deletions(-) rename {internal/platform => connections/implementation/mediums/webrtc}/tachyon_express_signaling_messenger.cc (98%) rename {internal/platform => connections/implementation/mediums/webrtc}/tachyon_express_signaling_messenger.h (91%) diff --git a/Package.swift b/Package.swift index 09c96c3e..27d9b761 100644 --- a/Package.swift +++ b/Package.swift @@ -525,8 +525,8 @@ let package = Package( "connections/implementation/webrtc_endpoint_channel.cc", "connections/implementation/mediums/webrtc.cc", "connections/implementation/mediums/webrtc", - "internal/platform/tachyon_express_signaling_messenger.cc", - "internal/platform/tachyon_express_signaling_messenger.h", + "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.cc", + "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h", "internal/platform/implementation/apple/webrtc.h", "internal/platform/implementation/apple/webrtc.mm", // This breaks the build, but seems to work fine without it? diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index dfca3a94..a1fae7a8 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -144,6 +144,37 @@ cc_library( ], ) +cc_library( + name = "tachyon_express_signaling_messenger", + srcs = ["tachyon_express_signaling_messenger.cc"], + hdrs = ["tachyon_express_signaling_messenger.h"], + visibility = [ + "//connections:__subpackages__", + "//internal/platform/implementation:__subpackages__", + "//internal/test:__subpackages__", + ], + deps = [ + "//internal/account", + "//internal/platform:base", + "//internal/platform:logging", + "//internal/platform:types", + "//internal/platform/implementation:webrtc_platform", + "//internal/proto:messaging_cc_grpc_proto", + "//internal/proto:tachyon_cc_proto", + "//internal/rpc:utils", + "//location/nearby/sharing/lib/account:account_manager", + "//third_party/gloop/util/random:mt_random", + "//third_party/grpc:gpr", + "//third_party/grpc:grpc++", + "//util/random:util", + "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/time", + ], +) + cc_library( name = "fake_webrtc", testonly = True, diff --git a/internal/platform/tachyon_express_signaling_messenger.cc b/connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.cc similarity index 98% rename from internal/platform/tachyon_express_signaling_messenger.cc rename to connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.cc index e430f7ff..9e6efa79 100644 --- a/internal/platform/tachyon_express_signaling_messenger.cc +++ b/connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.cc @@ -12,9 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef NO_WEBRTC - -#include "internal/platform/tachyon_express_signaling_messenger.h" +#include "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h" #include #include @@ -36,7 +34,6 @@ #include "internal/account/account_manager_impl.h" #include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" -#include "internal/platform/implementation/webrtc.h" #include "internal/platform/logging.h" #include "internal/proto/messaging.grpc.pb.h" #include "internal/proto/tachyon.proto.h" @@ -45,7 +42,7 @@ #include "internal/rpc/utils.h" #include "util/random/util.h" -namespace nearby { +namespace nearby::connections::mediums { namespace { using ::google::internal::communications::instantmessaging::v1::ClientInfo; @@ -340,6 +337,4 @@ bool TachyonExpressSignalingMessenger::SendMessage(absl::string_view peer_id, return success; } -} // namespace nearby - -#endif // #ifndef NO_WEBRTC +} // namespace nearby::connections::mediums diff --git a/internal/platform/tachyon_express_signaling_messenger.h b/connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h similarity index 91% rename from internal/platform/tachyon_express_signaling_messenger.h rename to connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h index 8f01bddd..47c6f59c 100644 --- a/internal/platform/tachyon_express_signaling_messenger.h +++ b/connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h @@ -12,12 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_TACHYON_MESSAGING_CLIENT_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_TACHYON_MESSAGING_CLIENT_H_ - -#ifndef NO_WEBRTC - -#include +#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_TACHYON_MESSAGING_CLIENT_H_ +#define CORE_INTERNAL_MEDIUMS_WEBRTC_TACHYON_MESSAGING_CLIENT_H_ #include #include @@ -34,7 +30,7 @@ #include "internal/platform/implementation/webrtc.h" #include "internal/proto/messaging.grpc.pb.h" -namespace nearby { +namespace nearby::connections::mediums { // Interface for the messaging Tachyon service. See // third_party/nearby/internal/proto/messaging.proto @@ -98,8 +94,6 @@ class TachyonExpressSignalingMessenger : public api::WebRtcSignalingMessenger { std::shared_ptr reader_ = nullptr; }; -} // namespace nearby +} // namespace nearby::connections::mediums -#endif // #ifndef NO_WEBRTC - -#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_TACHYON_MESSAGING_CLIENT_H_ +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_TACHYON_MESSAGING_CLIENT_H_ diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 2e56b1d8..e9efd49e 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -284,38 +284,6 @@ cc_library( ], ) -cc_library( - name = "tachyon_express_signaling_messenger", - srcs = ["tachyon_express_signaling_messenger.cc"], - hdrs = ["tachyon_express_signaling_messenger.h"], - visibility = [ - "//connections:__subpackages__", - "//internal/platform/implementation:__subpackages__", - "//internal/test:__subpackages__", - "//third_party/nearby/presence:__subpackages__", - ], - deps = [ - ":base", - ":logging", - ":types", - "//internal/account", - "//internal/platform/implementation:webrtc_platform", - "//internal/proto:messaging_cc_grpc_proto", - "//internal/proto:tachyon_cc_proto", - "//internal/rpc:utils", - "//location/nearby/sharing/lib/account:account_manager", - "//third_party/gloop/util/random:mt_random", - "//third_party/grpc:gpr", - "//third_party/grpc:grpc++", - "//util/random:util", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/synchronization", - "@com_google_absl//absl/time", - ], -) - cc_library( name = "comm", srcs = [ diff --git a/internal/platform/implementation/apple/BUILD b/internal/platform/implementation/apple/BUILD index 35b153f3..eb9349fa 100644 --- a/internal/platform/implementation/apple/BUILD +++ b/internal/platform/implementation/apple/BUILD @@ -61,8 +61,8 @@ objc_library( "webrtc.h", ], deps = [ + "//connections/implementation/mediums/webrtc:tachyon_express_signaling_messenger", "//internal/platform:logging", - "//internal/platform:tachyon_express_signaling_messenger", "//internal/platform:types", "//internal/platform/implementation:webrtc_platform", "//internal/proto:tachyon_cc_proto", @@ -130,7 +130,6 @@ objc_library( "//internal/crypto_cros", "//internal/platform:comm", "//internal/platform:logging", - "//internal/platform:tachyon_express_signaling_messenger", "//internal/platform:types", "//internal/proto:tachyon_cc_proto", "//internal/platform:base", diff --git a/internal/platform/implementation/apple/webrtc.mm b/internal/platform/implementation/apple/webrtc.mm index a7a50f79..755f0cb5 100644 --- a/internal/platform/implementation/apple/webrtc.mm +++ b/internal/platform/implementation/apple/webrtc.mm @@ -25,10 +25,10 @@ #include "absl/status/status.h" #include "absl/strings/string_view.h" +#include "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/crypto.h" #include "internal/platform/logging.h" -#include "internal/platform/tachyon_express_signaling_messenger.h" #include "internal/proto/tachyon.pb.h" #include "internal/proto/tachyon_enums.proto.h" #include "webrtc/api/create_modular_peer_connection_factory.h" @@ -91,7 +91,8 @@ void WebRtcMedium::CreatePeerConnection( std::unique_ptr WebRtcMedium::GetSignalingMessenger( absl::string_view self_id, const location::nearby::connections::LocationHint& location_hint) { - return std::make_unique(self_id, location_hint); + return std::make_unique< + nearby::connections::mediums::TachyonExpressSignalingMessenger>(self_id, location_hint); } } // namespace nearby::apple diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 860165bb..c89f5328 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -238,9 +238,9 @@ cc_library( hdrs = ["webrtc.h"], tags = ["windows"], deps = [ + "//connections/implementation/mediums/webrtc:tachyon_express_signaling_messenger", "//internal/platform:logging", - "//internal/platform:tachyon_express_signaling_messenger", - "//internal/platform/implementation:comm", + "//internal/platform/implementation:webrtc_platform", "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "//third_party/webrtc/files/stable/webrtc/api:rtc_error", diff --git a/internal/platform/implementation/windows/webrtc.cc b/internal/platform/implementation/windows/webrtc.cc index 85fa989d..cd6e366c 100644 --- a/internal/platform/implementation/windows/webrtc.cc +++ b/internal/platform/implementation/windows/webrtc.cc @@ -22,9 +22,9 @@ #include #include "absl/strings/string_view.h" +#include "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h" #include "internal/platform/implementation/webrtc.h" #include "internal/platform/logging.h" -#include "internal/platform/tachyon_express_signaling_messenger.h" #include "webrtc/api/create_modular_peer_connection_factory.h" #include "webrtc/api/peer_connection_interface.h" #include "webrtc/api/rtc_error.h" @@ -33,6 +33,8 @@ namespace nearby::windows { +using ::nearby::connections::mediums::TachyonExpressSignalingMessenger; + std::string WebRtcMedium::GetDefaultCountryCode() { wchar_t systemGeoName[LOCALE_NAME_MAX_LENGTH]; From 4e387e7ea789766dce44826aef2b4fea566772aa Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 22 May 2026 15:31:52 -0700 Subject: [PATCH 115/151] Move platform dependent part of WebRtcMedium into WebRtcPlatform. PiperOrigin-RevId: 919888693 --- connections/implementation/mediums/webrtc.h | 4 ---- .../implementation/mediums/webrtc/BUILD | 1 + .../implementation/mediums/webrtc/webrtc.h | 5 ----- .../mediums/webrtc/webrtc_bwu_handler.cc | 5 +++-- .../mediums/webrtc/webrtc_impl.cc | 4 ---- .../mediums/webrtc/webrtc_impl.h | 1 - .../platform/implementation/apple/webrtc.h | 6 ------ .../platform/implementation/apple/webrtc.mm | 9 --------- .../implementation/apple/webrtc_platform.mm | 8 ++++++++ internal/platform/implementation/g3/BUILD | 1 + internal/platform/implementation/g3/webrtc.cc | 3 +-- internal/platform/implementation/g3/webrtc.h | 2 -- .../implementation/g3/webrtc_platform.cc | 5 +++++ internal/platform/implementation/webrtc.h | 5 ----- .../platform/implementation/webrtc_platform.h | 6 ++++++ .../platform/implementation/windows/webrtc.cc | 18 ------------------ .../platform/implementation/windows/webrtc.h | 6 ------ .../implementation/windows/webrtc_test.cc | 6 ------ 18 files changed, 25 insertions(+), 70 deletions(-) diff --git a/connections/implementation/mediums/webrtc.h b/connections/implementation/mediums/webrtc.h index 4e401036..93203d98 100644 --- a/connections/implementation/mediums/webrtc.h +++ b/connections/implementation/mediums/webrtc.h @@ -40,10 +40,6 @@ class WebRtc { virtual ~WebRtc() = default; - // Gets the default two-letter country code associated with current locale. - // For example, en_US locale resolves to "US". - virtual std::string GetDefaultCountryCode() { return ""; } - // Returns if WebRtc is available as a medium for nearby to transport data. // Runs on @MainThread. virtual bool IsAvailable() { return false; } diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index a1fae7a8..72ddc3b8 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -132,6 +132,7 @@ cc_library( "//internal/platform:cancellation_flag", "//internal/platform:logging", "//internal/platform:types", + "//internal/platform/implementation:webrtc_platform", "//proto/mediums:web_rtc_signaling_frames_cc_proto", "//third_party/webrtc/files/stable/webrtc/api:jsep", "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", diff --git a/connections/implementation/mediums/webrtc/webrtc.h b/connections/implementation/mediums/webrtc/webrtc.h index 27055b4d..6490f5de 100644 --- a/connections/implementation/mediums/webrtc/webrtc.h +++ b/connections/implementation/mediums/webrtc/webrtc.h @@ -17,7 +17,6 @@ #include #include -#include #include #include "absl/strings/string_view.h" @@ -72,10 +71,6 @@ class WebRtcMedium { WebRtcMedium(WebRtcMedium&&) = default; WebRtcMedium& operator=(WebRtcMedium&&) = delete; - // Gets the default two-letter country code associated with current locale. - // For example, en_US locale resolves to "US". - std::string GetDefaultCountryCode() { return impl_->GetDefaultCountryCode(); } - void SetNonCellular(bool non_cellular) { non_cellular_ = non_cellular; } // Creates and returns a new webrtc::PeerConnectionInterface object via diff --git a/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc index 33d898ec..6c6c1dc0 100644 --- a/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc +++ b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc @@ -30,6 +30,7 @@ #include "connections/implementation/offline_frames.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "internal/platform/expected.h" +#include "internal/platform/implementation/webrtc_platform.h" #include "internal/platform/logging.h" namespace nearby { @@ -135,8 +136,8 @@ void WebrtcBwuHandler::HandleRevertInitiatorStateForService( std::string WebrtcBwuHandler::HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) { - LocationHint location_hint = - BuildLocationHint(webrtc_.GetDefaultCountryCode()); + LocationHint location_hint = BuildLocationHint( + api::WebRtcImplementationPlatform::GetDefaultCountryCode()); mediums::WebrtcPeerId self_id{mediums::WebrtcPeerId::FromRandom()}; if (!webrtc_.IsAcceptingConnections(upgrade_service_id)) { diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.cc b/connections/implementation/mediums/webrtc/webrtc_impl.cc index 4da2c2dd..9732aac9 100644 --- a/connections/implementation/mediums/webrtc/webrtc_impl.cc +++ b/connections/implementation/mediums/webrtc/webrtc_impl.cc @@ -81,10 +81,6 @@ WebRtcImpl::~WebRtcImpl() { } } -std::string WebRtcImpl::GetDefaultCountryCode() { - return medium_->GetDefaultCountryCode(); -} - bool WebRtcImpl::IsAvailable() { return medium_->IsValid(); } bool WebRtcImpl::IsAcceptingConnections(const std::string& service_id) { diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.h b/connections/implementation/mediums/webrtc/webrtc_impl.h index 979ebb48..92d9d5b4 100644 --- a/connections/implementation/mediums/webrtc/webrtc_impl.h +++ b/connections/implementation/mediums/webrtc/webrtc_impl.h @@ -52,7 +52,6 @@ class WebRtcImpl : public WebRtc { ~WebRtcImpl() override; // Overrides for WebRtc: - std::string GetDefaultCountryCode() override; bool IsAvailable() override; bool IsAcceptingConnections(const std::string& service_id) override ABSL_LOCKS_EXCLUDED(mutex_); diff --git a/internal/platform/implementation/apple/webrtc.h b/internal/platform/implementation/apple/webrtc.h index eb3af040..7fa67a98 100644 --- a/internal/platform/implementation/apple/webrtc.h +++ b/internal/platform/implementation/apple/webrtc.h @@ -19,7 +19,6 @@ #include #include -#include #include "absl/strings/string_view.h" #include "internal/platform/implementation/webrtc.h" @@ -31,11 +30,6 @@ class WebRtcMedium : public api::WebRtcMedium { public: ~WebRtcMedium() override = default; - // Gets the default two-letter country code associated with current locale. - // For example, en_US locale resolves to "US". - // This follows the ISO 3166-1 Alpha-2 standard. - std::string GetDefaultCountryCode() override; - // Creates and returns a new webrtc::PeerConnectionInterface object via // |callback|. void CreatePeerConnection(webrtc::PeerConnectionObserver* observer, diff --git a/internal/platform/implementation/apple/webrtc.mm b/internal/platform/implementation/apple/webrtc.mm index 755f0cb5..2479dc42 100644 --- a/internal/platform/implementation/apple/webrtc.mm +++ b/internal/platform/implementation/apple/webrtc.mm @@ -20,7 +20,6 @@ #include #include -#include #include #include "absl/status/status.h" @@ -36,14 +35,6 @@ namespace nearby::apple { -std::string WebRtcMedium::GetDefaultCountryCode() { - NSString* countryCode = [NSLocale.currentLocale objectForKey:NSLocaleCountryCode]; - if (countryCode) { - return std::string([countryCode UTF8String]); - } - return "US"; -} - void WebRtcMedium::CreatePeerConnection(webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) { CreatePeerConnection(std::nullopt, observer, std::move(callback)); diff --git a/internal/platform/implementation/apple/webrtc_platform.mm b/internal/platform/implementation/apple/webrtc_platform.mm index 7cec489b..5ed01d91 100644 --- a/internal/platform/implementation/apple/webrtc_platform.mm +++ b/internal/platform/implementation/apple/webrtc_platform.mm @@ -27,5 +27,13 @@ std::unique_ptr WebRtcImplementationPlatform::CreateWebRtcMedium() return std::make_unique(); } +std::string WebRtcImplementationPlatform::GetDefaultCountryCode() { + NSString* countryCode = [NSLocale.currentLocale objectForKey:NSLocaleCountryCode]; + if (countryCode) { + return std::string([countryCode UTF8String]); + } + return "US"; +} + } // namespace api } // namespace nearby diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index 935599c0..ef0c9b3f 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -121,6 +121,7 @@ cc_library( "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "//third_party/webrtc/files/stable/webrtc/rtc_base:checks", + "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", diff --git a/internal/platform/implementation/g3/webrtc.cc b/internal/platform/implementation/g3/webrtc.cc index c8385c0c..9659c50d 100644 --- a/internal/platform/implementation/g3/webrtc.cc +++ b/internal/platform/implementation/g3/webrtc.cc @@ -28,6 +28,7 @@ #include "webrtc/api/peer_connection_interface.h" #include "webrtc/api/scoped_refptr.h" #include "webrtc/rtc_base/checks.h" +#include "webrtc/rtc_base/thread.h" namespace nearby { namespace g3 { @@ -60,8 +61,6 @@ void WebRtcSignalingMessenger::StopReceivingMessages() { WebRtcMedium::~WebRtcMedium() { single_thread_executor_.Shutdown(); } -std::string WebRtcMedium::GetDefaultCountryCode() { return "US"; } - void WebRtcMedium::CreatePeerConnection( webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) { CreatePeerConnection(std::nullopt, observer, std::move(callback)); diff --git a/internal/platform/implementation/g3/webrtc.h b/internal/platform/implementation/g3/webrtc.h index 048dabf2..435fa57e 100644 --- a/internal/platform/implementation/g3/webrtc.h +++ b/internal/platform/implementation/g3/webrtc.h @@ -59,8 +59,6 @@ class WebRtcMedium : public api::WebRtcMedium { WebRtcMedium() = default; ~WebRtcMedium() override; - std::string GetDefaultCountryCode() override; - // Creates and returns a new webrtc::PeerConnectionInterface object via // |callback|. void CreatePeerConnection(webrtc::PeerConnectionObserver* observer, diff --git a/internal/platform/implementation/g3/webrtc_platform.cc b/internal/platform/implementation/g3/webrtc_platform.cc index 5c42f5ee..227f2e69 100644 --- a/internal/platform/implementation/g3/webrtc_platform.cc +++ b/internal/platform/implementation/g3/webrtc_platform.cc @@ -15,6 +15,7 @@ #include "internal/platform/implementation/webrtc_platform.h" #include +#include #include "internal/platform/implementation/g3/webrtc.h" #include "internal/platform/implementation/webrtc.h" @@ -31,4 +32,8 @@ WebRtcImplementationPlatform::CreateWebRtcMedium() { } } +std::string WebRtcImplementationPlatform::GetDefaultCountryCode() { + return "US"; +} + } // namespace nearby::api diff --git a/internal/platform/implementation/webrtc.h b/internal/platform/implementation/webrtc.h index c9022e28..5b64dd50 100644 --- a/internal/platform/implementation/webrtc.h +++ b/internal/platform/implementation/webrtc.h @@ -17,7 +17,6 @@ #include #include -#include #include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" @@ -52,10 +51,6 @@ class WebRtcMedium { virtual ~WebRtcMedium() = default; - // Gets the default two-letter country code associated with current locale. - // For example, en_US locale resolves to "US". - virtual std::string GetDefaultCountryCode() = 0; - // Creates and returns a new webrtc::PeerConnectionInterface object via // |callback|. virtual void CreatePeerConnection(webrtc::PeerConnectionObserver* observer, diff --git a/internal/platform/implementation/webrtc_platform.h b/internal/platform/implementation/webrtc_platform.h index 6fdc3bbe..a765179f 100644 --- a/internal/platform/implementation/webrtc_platform.h +++ b/internal/platform/implementation/webrtc_platform.h @@ -16,6 +16,7 @@ #define PLATFORM_API_WEBRTC_PLATFORM_H_ #include +#include #include "internal/platform/implementation/webrtc.h" @@ -24,6 +25,11 @@ namespace nearby::api { class WebRtcImplementationPlatform { public: static std::unique_ptr CreateWebRtcMedium(); + + // Gets the default two-letter country code associated with current locale. + // For example, en_US locale resolves to "US". + // This follows the ISO 3166-1 Alpha-2 standard. + static std::string GetDefaultCountryCode(); }; } // namespace nearby::api diff --git a/internal/platform/implementation/windows/webrtc.cc b/internal/platform/implementation/windows/webrtc.cc index cd6e366c..6a61051a 100644 --- a/internal/platform/implementation/windows/webrtc.cc +++ b/internal/platform/implementation/windows/webrtc.cc @@ -14,17 +14,13 @@ #include "internal/platform/implementation/windows/webrtc.h" -#include - #include #include -#include #include #include "absl/strings/string_view.h" #include "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h" #include "internal/platform/implementation/webrtc.h" -#include "internal/platform/logging.h" #include "webrtc/api/create_modular_peer_connection_factory.h" #include "webrtc/api/peer_connection_interface.h" #include "webrtc/api/rtc_error.h" @@ -35,20 +31,6 @@ namespace nearby::windows { using ::nearby::connections::mediums::TachyonExpressSignalingMessenger; -std::string WebRtcMedium::GetDefaultCountryCode() { - wchar_t systemGeoName[LOCALE_NAME_MAX_LENGTH]; - - if (!GetUserDefaultGeoName(systemGeoName, LOCALE_NAME_MAX_LENGTH)) { - LOG(ERROR) << __func__ - << ": Failed to GetUserDefaultGeoName: " << ". Fall back to US."; - return "US"; - } - std::wstring wideGeo(systemGeoName); - std::string systemGeoNameString(wideGeo.begin(), wideGeo.end()); - VLOG(1) << "GetUserDefaultGeoName() returns: " << systemGeoNameString; - return systemGeoNameString; -} - void WebRtcMedium::CreatePeerConnection( webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) { CreatePeerConnection(std::nullopt, observer, std::move(callback)); diff --git a/internal/platform/implementation/windows/webrtc.h b/internal/platform/implementation/windows/webrtc.h index 2c5b3fb3..15ff745c 100644 --- a/internal/platform/implementation/windows/webrtc.h +++ b/internal/platform/implementation/windows/webrtc.h @@ -17,7 +17,6 @@ #include #include -#include #include "absl/strings/string_view.h" #include "internal/platform/implementation/webrtc.h" @@ -29,11 +28,6 @@ class WebRtcMedium : public api::WebRtcMedium { public: ~WebRtcMedium() override = default; - // Gets the default two-letter country code associated with current locale. - // For example, en_US locale resolves to "US". - // This follows the ISO 3166-1 Alpha-2 standard. - std::string GetDefaultCountryCode() override; - // Creates and returns a new webrtc::PeerConnectionInterface object via // |callback|. void CreatePeerConnection(webrtc::PeerConnectionObserver* observer, diff --git a/internal/platform/implementation/windows/webrtc_test.cc b/internal/platform/implementation/windows/webrtc_test.cc index 708e0efc..0ccc4d1a 100644 --- a/internal/platform/implementation/windows/webrtc_test.cc +++ b/internal/platform/implementation/windows/webrtc_test.cc @@ -51,12 +51,6 @@ location::nearby::connections::LocationHint GetCountryCodeLocationHint( return location_hint; } -TEST(WebrtcTest, CountryCodeDefault) { - WebRtcMedium medium; - std::string result = medium.GetDefaultCountryCode(); - EXPECT_EQ(result, "US"); -} - TEST(WebrtcTest, CreatePeerConnectionSucceeds) { auto observer = std::make_unique(); WebRtcMedium medium; From 4181803eb65c6416096de8d9563c736778f83830 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 22 May 2026 15:43:41 -0700 Subject: [PATCH 116/151] Create platform independent WebRtcMedium impl. PiperOrigin-RevId: 919894367 --- .../implementation/mediums/webrtc/BUILD | 41 ++++++++- .../implementation/mediums/webrtc/README.md | 17 ++++ .../mediums/webrtc/webrtc_medium_impl.cc | 14 ++- .../mediums/webrtc/webrtc_medium_impl.h | 14 +-- .../mediums/webrtc/webrtc_medium_impl_test.cc | 16 ++-- internal/platform/implementation/apple/BUILD | 14 +-- .../platform/implementation/apple/webrtc.h | 56 ------------ .../platform/implementation/apple/webrtc.mm | 91 ------------------- .../implementation/apple/webrtc_platform.mm | 4 +- .../platform/implementation/windows/BUILD | 31 +------ .../implementation/windows/webrtc_platform.cc | 47 ++++++++++ 11 files changed, 127 insertions(+), 218 deletions(-) create mode 100644 connections/implementation/mediums/webrtc/README.md rename internal/platform/implementation/windows/webrtc.cc => connections/implementation/mediums/webrtc/webrtc_medium_impl.cc (91%) rename internal/platform/implementation/windows/webrtc.h => connections/implementation/mediums/webrtc/webrtc_medium_impl.h (81%) rename internal/platform/implementation/windows/webrtc_test.cc => connections/implementation/mediums/webrtc/webrtc_medium_impl_test.cc (87%) delete mode 100644 internal/platform/implementation/apple/webrtc.h delete mode 100644 internal/platform/implementation/apple/webrtc.mm create mode 100644 internal/platform/implementation/windows/webrtc_platform.cc diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index 72ddc3b8..c4305093 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -99,6 +99,25 @@ cc_library( ], ) +cc_library( + name = "webrtc_medium_impl", + srcs = ["webrtc_medium_impl.cc"], + hdrs = ["webrtc_medium_impl.h"], + visibility = [ + "//internal/platform/implementation:__subpackages__", + ], + deps = [ + ":tachyon_express_signaling_messenger", + "//internal/platform/implementation:webrtc_platform", + "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", + "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/files/stable/webrtc/api:rtc_error", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", + "@com_google_absl//absl/strings:string_view", + ], +) + cc_library( name = "webrtc_impl", srcs = [ @@ -149,11 +168,6 @@ cc_library( name = "tachyon_express_signaling_messenger", srcs = ["tachyon_express_signaling_messenger.cc"], hdrs = ["tachyon_express_signaling_messenger.h"], - visibility = [ - "//connections:__subpackages__", - "//internal/platform/implementation:__subpackages__", - "//internal/test:__subpackages__", - ], deps = [ "//internal/account", "//internal/platform:base", @@ -229,3 +243,20 @@ cc_test( "@com_google_protobuf//:protobuf", ], ) + +cc_test( + name = "webrtc_medium_impl_test", + size = "small", + srcs = ["webrtc_medium_impl_test.cc"], + deps = [ + ":webrtc_medium_impl", + "//internal/platform/implementation:platform_impl", + "//internal/platform/implementation:webrtc_platform", + "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", + "//third_party/webrtc/files/stable/webrtc/api:jsep", + "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", + "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/connections/implementation/mediums/webrtc/README.md b/connections/implementation/mediums/webrtc/README.md new file mode 100644 index 00000000..27ad4b1b --- /dev/null +++ b/connections/implementation/mediums/webrtc/README.md @@ -0,0 +1,17 @@ +# WebRtc support for Nearby Connections + +This directory contains the implementation to support WebRtc in the Nearby +Connection library. + +All dependencies on webrtc MUST be limited to targets in this directory. + +## To Enable WebRtc support + +To enabled WebRtc support undefine the ```NO_WEBRTC``` preprocessor symbol in +the file **connections/implementation/mediums/mediums.cc**. + +When building using bazel, pass the build flag +```--//:enable_webrtc=true``` to set the correct symbol. + +Make sure the binary is linked with an implementation of the +```WebRtcImplementationPlatform```. \ No newline at end of file diff --git a/internal/platform/implementation/windows/webrtc.cc b/connections/implementation/mediums/webrtc/webrtc_medium_impl.cc similarity index 91% rename from internal/platform/implementation/windows/webrtc.cc rename to connections/implementation/mediums/webrtc/webrtc_medium_impl.cc index 6a61051a..8c5a2237 100644 --- a/internal/platform/implementation/windows/webrtc.cc +++ b/connections/implementation/mediums/webrtc/webrtc_medium_impl.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "internal/platform/implementation/windows/webrtc.h" +#include "connections/implementation/mediums/webrtc/webrtc_medium_impl.h" #include #include @@ -27,16 +27,14 @@ #include "webrtc/api/scoped_refptr.h" #include "webrtc/rtc_base/thread.h" -namespace nearby::windows { +namespace nearby::connections::mediums { -using ::nearby::connections::mediums::TachyonExpressSignalingMessenger; - -void WebRtcMedium::CreatePeerConnection( +void WebRtcMediumImpl::CreatePeerConnection( webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) { CreatePeerConnection(std::nullopt, observer, std::move(callback)); } -void WebRtcMedium::CreatePeerConnection( +void WebRtcMediumImpl::CreatePeerConnection( std::optional options, webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) { webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; @@ -79,11 +77,11 @@ void WebRtcMedium::CreatePeerConnection( } std::unique_ptr -WebRtcMedium::GetSignalingMessenger( +WebRtcMediumImpl::GetSignalingMessenger( absl::string_view self_id, const location::nearby::connections::LocationHint& location_hint) { return std::make_unique(self_id, location_hint); } -} // namespace nearby::windows +} // namespace nearby::connections::mediums diff --git a/internal/platform/implementation/windows/webrtc.h b/connections/implementation/mediums/webrtc/webrtc_medium_impl.h similarity index 81% rename from internal/platform/implementation/windows/webrtc.h rename to connections/implementation/mediums/webrtc/webrtc_medium_impl.h index 15ff745c..7eb5ff1b 100644 --- a/internal/platform/implementation/windows/webrtc.h +++ b/connections/implementation/mediums/webrtc/webrtc_medium_impl.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef PLATFORM_IMPL_WINDOWS_WEBRTC_H_ -#define PLATFORM_IMPL_WINDOWS_WEBRTC_H_ +#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_MEDIUM_IMPL_H_ +#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_MEDIUM_IMPL_H_ #include #include @@ -22,11 +22,11 @@ #include "internal/platform/implementation/webrtc.h" #include "webrtc/api/peer_connection_interface.h" -namespace nearby::windows { +namespace nearby::connections::mediums { -class WebRtcMedium : public api::WebRtcMedium { +class WebRtcMediumImpl : public api::WebRtcMedium { public: - ~WebRtcMedium() override = default; + ~WebRtcMediumImpl() override = default; // Creates and returns a new webrtc::PeerConnectionInterface object via // |callback|. @@ -47,6 +47,6 @@ class WebRtcMedium : public api::WebRtcMedium { override; }; -} // namespace nearby::windows +} // namespace nearby::connections::mediums -#endif // PLATFORM_IMPL_WINDOWS_WEBRTC_H_ +#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_MEDIUM_IMPL_H_ diff --git a/internal/platform/implementation/windows/webrtc_test.cc b/connections/implementation/mediums/webrtc/webrtc_medium_impl_test.cc similarity index 87% rename from internal/platform/implementation/windows/webrtc_test.cc rename to connections/implementation/mediums/webrtc/webrtc_medium_impl_test.cc index 0ccc4d1a..c52cee0a 100644 --- a/internal/platform/implementation/windows/webrtc_test.cc +++ b/connections/implementation/mediums/webrtc/webrtc_medium_impl_test.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "internal/platform/implementation/windows/webrtc.h" +#include "connections/implementation/mediums/webrtc/webrtc_medium_impl.h" #include #include @@ -25,8 +25,7 @@ #include "webrtc/api/peer_connection_interface.h" #include "webrtc/api/scoped_refptr.h" -namespace nearby { -namespace windows { +namespace nearby::connections::mediums { class MockPeerConnectionObserver : public webrtc::PeerConnectionObserver { public: @@ -51,9 +50,9 @@ location::nearby::connections::LocationHint GetCountryCodeLocationHint( return location_hint; } -TEST(WebrtcTest, CreatePeerConnectionSucceeds) { +TEST(WebrtcMediumImplTest, CreatePeerConnectionSucceeds) { auto observer = std::make_unique(); - WebRtcMedium medium; + WebRtcMediumImpl medium; medium.CreatePeerConnection( std::nullopt, observer.get(), [](webrtc::scoped_refptr @@ -65,12 +64,11 @@ TEST(WebrtcTest, CreatePeerConnectionSucceeds) { }); } -TEST(WebrtcTest, GetSignalingMessengerSucceeds) { - WebRtcMedium medium; +TEST(WebrtcMediumImplTest, GetSignalingMessengerSucceeds) { + WebRtcMediumImpl medium; std::unique_ptr messenger = medium.GetSignalingMessenger("US", GetCountryCodeLocationHint("US")); EXPECT_TRUE(messenger); } -} // namespace windows -} // namespace nearby +} // namespace nearby::connections::mediums diff --git a/internal/platform/implementation/apple/BUILD b/internal/platform/implementation/apple/BUILD index eb9349fa..f850bd13 100644 --- a/internal/platform/implementation/apple/BUILD +++ b/internal/platform/implementation/apple/BUILD @@ -54,24 +54,12 @@ objc_library( objc_library( name = "apple_webrtc", srcs = [ - "webrtc.mm", "webrtc_platform.mm", ], - hdrs = [ - "webrtc.h", - ], deps = [ - "//connections/implementation/mediums/webrtc:tachyon_express_signaling_messenger", - "//internal/platform:logging", - "//internal/platform:types", + "//connections/implementation/mediums/webrtc:webrtc_medium_impl", "//internal/platform/implementation:webrtc_platform", - "//internal/proto:tachyon_cc_proto", "//third_party/apple_frameworks:Foundation", - "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", - "//third_party/webrtc/files/stable/webrtc/api/task_queue:default_task_queue_factory", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", ], ) diff --git a/internal/platform/implementation/apple/webrtc.h b/internal/platform/implementation/apple/webrtc.h deleted file mode 100644 index 7fa67a98..00000000 --- a/internal/platform/implementation/apple/webrtc.h +++ /dev/null @@ -1,56 +0,0 @@ -// 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 PLATFORM_IMPL_APPLE_WEBRTC_H_ -#define PLATFORM_IMPL_APPLE_WEBRTC_H_ - -#ifndef NO_WEBRTC - -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/webrtc.h" -#include "webrtc/api/peer_connection_interface.h" - -namespace nearby::apple { - -class WebRtcMedium : public api::WebRtcMedium { - public: - ~WebRtcMedium() override = default; - - // Creates and returns a new webrtc::PeerConnectionInterface object via - // |callback|. - void CreatePeerConnection(webrtc::PeerConnectionObserver* observer, - PeerConnectionCallback callback) override; - - // Creates and returns a new webrtc::PeerConnectionInterface object via - // |callback| with |PeerConnectionFactoryInterface::Options|. - void CreatePeerConnection( - std::optional options, - webrtc::PeerConnectionObserver* observer, - PeerConnectionCallback callback) override; - - // Returns a signaling messenger for sending WebRTC signaling messages. - std::unique_ptr GetSignalingMessenger( - absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint) - override; -}; - -} // namespace nearby::apple - -#endif // #ifndef NO_WEBRTC - -#endif // PLATFORM_IMPL_APPLE_WEBRTC_H_ diff --git a/internal/platform/implementation/apple/webrtc.mm b/internal/platform/implementation/apple/webrtc.mm deleted file mode 100644 index 2479dc42..00000000 --- a/internal/platform/implementation/apple/webrtc.mm +++ /dev/null @@ -1,91 +0,0 @@ -// 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 NO_WEBRTC - -#include "internal/platform/implementation/apple/webrtc.h" - -#import - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/crypto.h" -#include "internal/platform/logging.h" -#include "internal/proto/tachyon.pb.h" -#include "internal/proto/tachyon_enums.proto.h" -#include "webrtc/api/create_modular_peer_connection_factory.h" -#include "webrtc/api/task_queue/default_task_queue_factory.h" - -namespace nearby::apple { - -void WebRtcMedium::CreatePeerConnection(webrtc::PeerConnectionObserver* observer, - PeerConnectionCallback callback) { - CreatePeerConnection(std::nullopt, observer, std::move(callback)); -} - -void WebRtcMedium::CreatePeerConnection( - std::optional options, - webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) { - webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; - rtc_config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; - // TODO: b/261663238 - Add the TURN servers and go beyond the default servers. - webrtc::PeerConnectionInterface::IceServer ice_server; - ice_server.urls.emplace_back("stun:stun.l.google.com:19302"); - ice_server.urls.emplace_back("stun:stun1.l.google.com:19302"); - ice_server.urls.emplace_back("stun:stun2.l.google.com:19302"); - ice_server.urls.emplace_back("stun:stun3.l.google.com:19302"); - ice_server.urls.emplace_back("stun:stun4.l.google.com:19302"); - rtc_config.servers.push_back(ice_server); - - std::unique_ptr signaling_thread = webrtc::Thread::Create(); - signaling_thread->SetName("signaling_thread", nullptr); - if (!signaling_thread->Start()) { - callback(/*peer_connection=*/nullptr); - return; - } - - webrtc::PeerConnectionDependencies dependencies(observer); - webrtc::PeerConnectionFactoryDependencies factory_dependencies; - factory_dependencies.signaling_thread = signaling_thread.release(); - - webrtc::scoped_refptr peer_connection_factory = - webrtc::CreateModularPeerConnectionFactory(std::move(factory_dependencies)); - if (options.has_value()) { - peer_connection_factory->SetOptions(options.value()); - } - webrtc::RTCErrorOr> - peer_connection_or_error = - peer_connection_factory->CreatePeerConnectionOrError(rtc_config, std::move(dependencies)); - if (peer_connection_or_error.ok()) { - callback(peer_connection_or_error.MoveValue()); - } else { - callback(/*peer_connection=*/nullptr); - } -} - -std::unique_ptr WebRtcMedium::GetSignalingMessenger( - absl::string_view self_id, const location::nearby::connections::LocationHint& location_hint) { - return std::make_unique< - nearby::connections::mediums::TachyonExpressSignalingMessenger>(self_id, location_hint); -} - -} // namespace nearby::apple - -#endif // #ifndef NO_WEBRTC diff --git a/internal/platform/implementation/apple/webrtc_platform.mm b/internal/platform/implementation/apple/webrtc_platform.mm index 5ed01d91..8cc97a86 100644 --- a/internal/platform/implementation/apple/webrtc_platform.mm +++ b/internal/platform/implementation/apple/webrtc_platform.mm @@ -18,13 +18,13 @@ #include -#import "internal/platform/implementation/apple/webrtc.h" +#include "connections/implementation/mediums/webrtc/webrtc_medium_impl.h" namespace nearby { namespace api { std::unique_ptr WebRtcImplementationPlatform::CreateWebRtcMedium() { - return std::make_unique(); + return std::make_unique(); } std::string WebRtcImplementationPlatform::GetDefaultCountryCode() { diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index c89f5328..94698475 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -233,21 +233,15 @@ cc_library( ) cc_library( - name = "webrtc", - srcs = ["webrtc.cc"], - hdrs = ["webrtc.h"], + name = "webrtc_platform", + srcs = ["webrtc_platform.cc"], tags = ["windows"], deps = [ - "//connections/implementation/mediums/webrtc:tachyon_express_signaling_messenger", + "//connections/implementation/mediums/webrtc:webrtc_medium_impl", "//internal/platform:logging", "//internal/platform/implementation:webrtc_platform", - "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", - "//third_party/webrtc/files/stable/webrtc/api:rtc_error", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", - "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", - "@com_google_absl//absl/strings", ], + alwayslink = True, ) cc_library( @@ -436,23 +430,6 @@ cc_proto_library( deps = [":preferences_manager_test_proto"], ) -cc_test( - name = "webrtc_test", - size = "small", - srcs = ["webrtc_test.cc"], - deps = [ - ":webrtc", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:platform_impl", - "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", - "//third_party/webrtc/files/stable/webrtc/api:jsep", - "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - cc_test( name = "impl_test", size = "small", diff --git a/internal/platform/implementation/windows/webrtc_platform.cc b/internal/platform/implementation/windows/webrtc_platform.cc new file mode 100644 index 00000000..fe7bc8fa --- /dev/null +++ b/internal/platform/implementation/windows/webrtc_platform.cc @@ -0,0 +1,47 @@ +// Copyright 2026 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. + +#include "internal/platform/implementation/webrtc_platform.h" + +#include + +#include +#include + +#include "internal/platform/logging.h" +#include "internal/platform/implementation/webrtc.h" +#include "connections/implementation/mediums/webrtc/webrtc_medium_impl.h" + +namespace nearby::api { + +std::unique_ptr +WebRtcImplementationPlatform::CreateWebRtcMedium() { + return std::make_unique(); +} + +std::string WebRtcImplementationPlatform::GetDefaultCountryCode() { + wchar_t systemGeoName[LOCALE_NAME_MAX_LENGTH]; + + if (!GetUserDefaultGeoName(systemGeoName, LOCALE_NAME_MAX_LENGTH)) { + LOG(ERROR) << __func__ + << ": Failed to GetUserDefaultGeoName: " << ". Fall back to US."; + return "US"; + } + std::wstring wideGeo(systemGeoName); + std::string systemGeoNameString(wideGeo.begin(), wideGeo.end()); + VLOG(1) << "GetUserDefaultGeoName() returns: " << systemGeoNameString; + return systemGeoNameString; +} + +} // namespace nearby::api From 7f91b60661b6dac2958e58509da44834123e917e Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 22 May 2026 17:58:40 -0700 Subject: [PATCH 117/151] Add update save path and delete binding to dart adapter. PiperOrigin-RevId: 919945057 --- sharing/BUILD | 1 + sharing/fake_nearby_sharing_service.cc | 13 +++++++++++++ sharing/fake_nearby_sharing_service.h | 4 ++++ sharing/nearby_sharing_service.h | 5 +++++ sharing/nearby_sharing_service_impl.cc | 13 +++++++++++++ sharing/nearby_sharing_service_impl.h | 3 +++ 6 files changed, 39 insertions(+) diff --git a/sharing/BUILD b/sharing/BUILD index 094d23a2..caf97bf2 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -479,6 +479,7 @@ cc_library( "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", diff --git a/sharing/fake_nearby_sharing_service.cc b/sharing/fake_nearby_sharing_service.cc index 416c4331..e3c90021 100644 --- a/sharing/fake_nearby_sharing_service.cc +++ b/sharing/fake_nearby_sharing_service.cc @@ -22,6 +22,9 @@ #include "location/nearby/sharing/lib/sync/sync_manager.h" #include "absl/functional/any_invocable.h" +#include "absl/status/statusor.h" +#include "absl/strings/string_view.h" +#include "internal/base/file_path.h" #include "internal/base/observer_list.h" #include "internal/platform/clock.h" #include "sharing/advertisement.h" @@ -297,5 +300,15 @@ void FakeNearbySharingService::FireInitiatePairingResult( std::move(callback)(status); } +void FakeNearbySharingService::UpdateBackupSavePath( + absl::string_view binding_id, absl::string_view save_path, + absl::AnyInvocable + status_codes_callback) { + absl::StatusOr status = + sync_manager_->UpdateSyncBindingDestinationDirectory(binding_id, + FilePath(save_path)); + status_codes_callback(status.ok() ? StatusCodes::kOk : StatusCodes::kError); +} + } // namespace sharing } // namespace nearby diff --git a/sharing/fake_nearby_sharing_service.h b/sharing/fake_nearby_sharing_service.h index 57b0f05c..ca4c4a0f 100644 --- a/sharing/fake_nearby_sharing_service.h +++ b/sharing/fake_nearby_sharing_service.h @@ -142,6 +142,10 @@ class FakeNearbySharingService : public NearbySharingService { uint16_t alternate_service_uuid) override {} SyncManager& sync_manager() override; OutgoingTargetsManager& outgoing_targets_manager() override; + void UpdateBackupSavePath( + absl::string_view binding_id, absl::string_view save_path, + absl::AnyInvocable + status_codes_callback) override; nearby::sharing::api::IdentityRpcClient& fake_identity_rpc_client() { return identity_rpc_client_; diff --git a/sharing/nearby_sharing_service.h b/sharing/nearby_sharing_service.h index f657c968..317b5a02 100644 --- a/sharing/nearby_sharing_service.h +++ b/sharing/nearby_sharing_service.h @@ -22,6 +22,7 @@ #include "location/nearby/sharing/lib/sync/sync_manager.h" #include "absl/functional/any_invocable.h" +#include "absl/strings/string_view.h" #include "absl/time/time.h" #include "internal/platform/clock.h" #include "sharing/advertisement.h" @@ -228,6 +229,10 @@ class NearbySharingService { uint16_t alternate_service_uuid) = 0; virtual SyncManager& sync_manager() = 0; virtual OutgoingTargetsManager& outgoing_targets_manager() = 0; + virtual void UpdateBackupSavePath( + absl::string_view binding_id, absl::string_view save_path, + absl::AnyInvocable + status_codes_callback) = 0; }; } // namespace nearby::sharing diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 3f4e84f9..ef4f3f83 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -3299,4 +3299,17 @@ void NearbySharingServiceImpl::UpdateFilePathsInProgress( << ": Update file paths in progress: " << update_file_paths; } +void NearbySharingServiceImpl::UpdateBackupSavePath( + absl::string_view binding_id, absl::string_view save_path, + absl::AnyInvocable + status_codes_callback) { + absl::StatusOr original_path = + sync_manager_.UpdateSyncBindingDestinationDirectory(binding_id, + FilePath(save_path)); + // TODO: b/485307320 - If original destination directory exists, move + // contents to the new destination directory. + status_codes_callback( + original_path.ok() ? StatusCodes::kOk : StatusCodes::kError); +} + } // namespace nearby::sharing diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index 44841f00..b4d763be 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -173,6 +173,9 @@ class NearbySharingServiceImpl OutgoingTargetsManager& outgoing_targets_manager() override { return outgoing_targets_manager_; } + void UpdateBackupSavePath( + absl::string_view binding_id, absl::string_view save_path, + absl::AnyInvocable status_codes_callback) override; // NearbyConnectionsManager::IncomingConnectionListener: void OnIncomingConnection(absl::string_view endpoint_id, From 91c62dda3e67c80f75a8654d9eec90680d21154a Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 22 May 2026 21:26:06 -0700 Subject: [PATCH 118/151] Automated Code Change PiperOrigin-RevId: 920006627 --- internal/crypto_cros/aead.cc | 2 +- internal/crypto_cros/aead_unittest.cc | 2 +- internal/crypto_cros/encryptor.cc | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/crypto_cros/aead.cc b/internal/crypto_cros/aead.cc index f25699ee..451d9d5f 100644 --- a/internal/crypto_cros/aead.cc +++ b/internal/crypto_cros/aead.cc @@ -104,7 +104,7 @@ bool Aead::Seal(absl::string_view plaintext, absl::string_view nonce, return true; } -absl::optional> Aead::Open( +std::optional> Aead::Open( absl::Span ciphertext, absl::Span nonce, absl::Span additional_data) const { const size_t max_output_length = ciphertext.size(); diff --git a/internal/crypto_cros/aead_unittest.cc b/internal/crypto_cros/aead_unittest.cc index df1c4750..6699c47f 100644 --- a/internal/crypto_cros/aead_unittest.cc +++ b/internal/crypto_cros/aead_unittest.cc @@ -64,7 +64,7 @@ TEST_P(AeadTest, SealOpenSpan) { aead.Seal(kPlaintext, nonce, kAdditionalData); EXPECT_LT(sizeof(kPlaintext), ciphertext.size()); - absl::optional> decrypted = + std::optional> decrypted = aead.Open(ciphertext, nonce, kAdditionalData); ASSERT_TRUE(decrypted); ASSERT_EQ(decrypted->size(), sizeof(kPlaintext)); diff --git a/internal/crypto_cros/encryptor.cc b/internal/crypto_cros/encryptor.cc index 2eaede2c..2081091e 100644 --- a/internal/crypto_cros/encryptor.cc +++ b/internal/crypto_cros/encryptor.cc @@ -127,7 +127,7 @@ bool Encryptor::CryptString(bool do_encrypt, absl::string_view input, uint8_t* out_ptr = reinterpret_cast(nearbybase::WriteInto(&result, out_size + 1)); - absl::optional len = + std::optional len = (mode_ == CTR) ? CryptCTR(do_encrypt, nearbybase::as_bytes(absl::MakeSpan(input)), absl::MakeSpan(out_ptr, out_size)) @@ -143,7 +143,7 @@ bool Encryptor::CryptString(bool do_encrypt, absl::string_view input, bool Encryptor::CryptBytes(bool do_encrypt, absl::Span input, std::vector* output) { std::vector result(MaxOutput(do_encrypt, input.size())); - absl::optional len = + std::optional len = (mode_ == CTR) ? CryptCTR(do_encrypt, input, absl::MakeSpan(result)) : Crypt(do_encrypt, input, absl::MakeSpan(result)); if (!len) return false; @@ -159,9 +159,9 @@ size_t Encryptor::MaxOutput(bool do_encrypt, size_t length) { return result; } -absl::optional Encryptor::Crypt(bool do_encrypt, - absl::Span input, - absl::Span output) { +std::optional Encryptor::Crypt(bool do_encrypt, + absl::Span input, + absl::Span output) { DCHECK(key_); // Must call Init() before En/De-crypt. const EVP_CIPHER* cipher = GetCipherForKey(key_); @@ -197,9 +197,9 @@ absl::optional Encryptor::Crypt(bool do_encrypt, return out_len; } -absl::optional Encryptor::CryptCTR(bool do_encrypt, - absl::Span input, - absl::Span output) { +std::optional Encryptor::CryptCTR(bool do_encrypt, + absl::Span input, + absl::Span output) { if (iv_.size() != AES_BLOCK_SIZE) { LOG(ERROR) << "Counter value not set in CTR mode."; return absl::nullopt; From 55bccac92309918ea84667739562176a42199428 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 25 May 2026 08:51:01 -0700 Subject: [PATCH 119/151] internal PiperOrigin-RevId: 920994624 --- .../flags/nearby_connections_feature_flags.h | 12 ++-- .../flags/nearby_platform_feature_flags.h | 70 +++++++++---------- sharing/flags/generated/README.md | 17 ----- .../generated/nearby_sharing_feature_flags.h | 4 -- 4 files changed, 41 insertions(+), 62 deletions(-) mode change 100644 => 100755 connections/implementation/flags/nearby_connections_feature_flags.h delete mode 100644 sharing/flags/generated/README.md diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h old mode 100644 new mode 100755 index 9ac89ceb..9b322ee5 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -74,6 +74,9 @@ constexpr auto kEnableSafeToDisconnect = // servers. constexpr auto kEnableSharedPeripheralManager = flags::Flag(kConfigPackage, "45770787", false); +// Enable/Disable single copy read/write for input/output buffers. +constexpr auto kEnableSingleCopy = + flags::Flag(kConfigPackage, "45782646", true); // Stop BLE_V2 scanning when upgrading to WIFI Hotspot or WFD. constexpr auto kEnableStopBleScanningOnWifiUpgrade = flags::Flag(kConfigPackage, "45687902", false); @@ -83,6 +86,9 @@ constexpr auto kEnableWifiDirect = // by default, enable Wi-Fi Hotspot client. constexpr auto kEnableWifiHotspotClient = flags::Flag(kConfigPackage, "45648734", true); +// When true, fix the BleServerSocket deadlock/use-after-free (b/494335036). +constexpr auto kFixBleServerSocketDeadlock = + flags::Flag(kConfigPackage, "45782647", true); // Default max transmit packet size for medium. constexpr auto kMediumDefaultMaxTransmitPacketSize = flags::Flag(kConfigPackage, "45669529", 65536); @@ -98,12 +104,6 @@ constexpr auto kRefactorBleL2cap = // 4. auto-resume 5. non-distance-constraint-recovery 6. payload_ack constexpr auto kSafeToDisconnectVersion = flags::Flag(kConfigPackage, "45425841", 0); -// Enable/Disable single copy read/write for input/output buffers. -constexpr auto kEnableSingleCopy = - flags::Flag(kConfigPackage, "45782646", true); -// When true, fix the BleServerSocket deadlock/use-after-free (b/494335036). -constexpr auto kFixBleServerSocketDeadlock = - flags::Flag(kConfigPackage, "45782647", true); } // namespace nearby_connections_feature } // namespace config_package_nearby diff --git a/internal/platform/flags/nearby_platform_feature_flags.h b/internal/platform/flags/nearby_platform_feature_flags.h index 35c2ebcf..0deadf4b 100644 --- a/internal/platform/flags/nearby_platform_feature_flags.h +++ b/internal/platform/flags/nearby_platform_feature_flags.h @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Mendel flags, auto-generated. DO NOT EDIT. #ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_FLAGS_NEARBY_PLATFORM_FEATURE_FLAGS_H_ #define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_FLAGS_NEARBY_PLATFORM_FEATURE_FLAGS_H_ @@ -28,46 +29,45 @@ constexpr absl::string_view kConfigPackage = "nearby"; // The Nearby Platform features. namespace nearby_platform_feature { - -// The maximum scanning times for available hotspots. -constexpr auto kWifiHotspotScanMaxRetries = - flags::Flag(kConfigPackage, "45415883", 3); - -// The maximum IP check times during Wi-Fi hotspot connection. -constexpr auto kWifiHotspotCheckIpMaxRetries = - flags::Flag(kConfigPackage, "45415884", 20); - -// The interval between 2 IP check attempts. -constexpr auto kWifiHotspotCheckIpIntervalMillis = - flags::Flag(kConfigPackage, "45415885", 500); - -// The maximum connection times to remote Wi-Fi hotspot. -constexpr auto kWifiHotspotConnectionMaxRetries = - flags::Flag(kConfigPackage, "45415886", 3); - -// The interval between 2 connectin attempts. -constexpr auto kWifiHotspotConnectionIntervalMillis = - flags::Flag(kConfigPackage, "45415887", 2000); - -// The connection timeout to remote Wi-Fi hotspot. -constexpr auto kWifiHotspotConnectionTimeoutMillis = - flags::Flag(kConfigPackage, "45415888", 10000); - +// Disable/Enable GATT feature in BLE v2. +constexpr auto kEnableBleV2Gatt = + flags::Flag(kConfigPackage, "45415180", true); +// Disable/Enable GATT feature on devices without BLE extended feature. +constexpr auto kEnableBleV2GattOnNonExtendedDevice = + flags::Flag(kConfigPackage, "45415267", true); // Enable/Disable Intel PIe SDK to query/set WIFI feature. constexpr auto kEnableIntelPieSdk = flags::Flag(kConfigPackage, "45428547", false); - -// Enable/Disable new Bluetooth refactor -constexpr auto kEnableNewBluetoothRefactor = - flags::Flag(kConfigPackage, "45615156", false); - -// The send buffer size of blocking socket +// Replace std::async with platform thread +constexpr auto kEnablePlatformThreadToNetwork = + flags::Flag(kConfigPackage, "45412711", true); +// Enable/Disable task scheduler for ScheduledExecutor and timer. +constexpr auto kEnableTaskScheduler = + flags::Flag(kConfigPackage, "45643835", true); +// Enable/Disable Wi-Fi hotspot native. +constexpr auto kEnableWifiHotspotNative = + flags::Flag(kConfigPackage, "45667396", true); +// The send buffer size of blocking socket. constexpr auto kSocketSendBufferSize = flags::Flag(kConfigPackage, "45673785", 524288); - -// Run scheduled executor callback on executor thread. -constexpr auto kRunScheduledExecutorCallbackOnExecutorThread = - flags::Flag(kConfigPackage, "45686494", false); +// The interval between 2 IP check attempts. +constexpr auto kWifiHotspotCheckIpIntervalMillis = + flags::Flag(kConfigPackage, "45415885", 500); +// The maximum IP check times during Wi-Fi hotspot connection. +constexpr auto kWifiHotspotCheckIpMaxRetries = + flags::Flag(kConfigPackage, "45415884", 10); +// The interval between 2 connectin attempts. +constexpr auto kWifiHotspotConnectionIntervalMillis = + flags::Flag(kConfigPackage, "45415887", 2000); +// The maximum connection times to remote WiFi hotspot. +constexpr auto kWifiHotspotConnectionMaxRetries = + flags::Flag(kConfigPackage, "45415886", 3); +// The connection timeout to remote Wi-Fi hotspot. +constexpr auto kWifiHotspotConnectionTimeoutMillis = + flags::Flag(kConfigPackage, "45415888", 10000); +// The max retry times to scan WiFi hotspots. +constexpr auto kWifiHotspotScanMaxRetries = + flags::Flag(kConfigPackage, "45415883", 3); } // namespace nearby_platform_feature } // namespace config_package_nearby diff --git a/sharing/flags/generated/README.md b/sharing/flags/generated/README.md deleted file mode 100644 index a7682807..00000000 --- a/sharing/flags/generated/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Feature flags generation - -This directory contains the generated Nearby Share feature flags definition -file. - -## Adding flags - -New flags need to be added to google3/googledata/experiments/mobile/nearby/features/nearby_sharing_feature.gcl. - -To generate code for the new flags, run: - -``` -blaze build //third_party/nearby/sharing/flags:nearby_sharing_feature_flags_cpp_consts -``` - -The creates the generated file in *blaze-genfiles/third_party/nearby/sharing/flags/nearby_sharing_feature_flags.h*. Copy this file to google3/third_party/nearby/sharing/flags/generated/nearby_sharing_feature_flags.h -and include in your CL for submission. diff --git a/sharing/flags/generated/nearby_sharing_feature_flags.h b/sharing/flags/generated/nearby_sharing_feature_flags.h index ec0900d3..25beaeb5 100755 --- a/sharing/flags/generated/nearby_sharing_feature_flags.h +++ b/sharing/flags/generated/nearby_sharing_feature_flags.h @@ -47,9 +47,6 @@ constexpr auto kEnableMediumWifiLan = // Enable/disable retry/resume transfer for partial files. constexpr auto kEnableRetryResumeTransfer = flags::Flag(kConfigPackage, "45411589", false); -// Enable/disable self share UI in Nearby Share -constexpr auto kEnableSelfShareUi = - flags::Flag(kConfigPackage, "45418908", false); // Enable/disable sending desktop events constexpr auto kEnableSendingDesktopEvents = flags::Flag(kConfigPackage, "45459748", false); @@ -112,7 +109,6 @@ inline absl::btree_map&> GetBoolFlags() { {45418905, kEnableMediumWebRtc}, {45418906, kEnableMediumWifiLan}, {45411589, kEnableRetryResumeTransfer}, - {45418908, kEnableSelfShareUi}, {45459748, kEnableSendingDesktopEvents}, {45409033, kShowAutoUpdateSetting}, {45762616, kEnableFileSync}, From 83b35985a86669b055613ebeb8e0f945db19eb97 Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 26 May 2026 03:27:39 -0700 Subject: [PATCH 120/151] ...text exposed to open source public git repo... PiperOrigin-RevId: 921357852 --- proto/sharing_enums.proto | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index 88af80fc..e0891933 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -848,6 +848,14 @@ enum SharingUseCase { USE_CASE_TAP_TO_SHARE = 9; } +enum SharingSurface { + SURFACE_UNKNOWN = 0; + + SURFACE_QUICK_SHARE = 1; + SURFACE_APP = 2; + SURFACE_SYSTEM_SHARE_SHEET = 3; +} + // Used only for Windows App now. enum AppCrashReason { APP_CRASH_REASON_UNKNOWN = 0; From 173da323914d79c852313cddcfeeda6a8079bab5 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 26 May 2026 18:11:55 -0700 Subject: [PATCH 121/151] Refactor AnalyticsRecorder into a pure abstract interface PiperOrigin-RevId: 921794969 --- internal/analytics/BUILD | 1 + sharing/BUILD | 15 +- sharing/analytics/BUILD | 30 - sharing/analytics/analytics_recorder.cc | 838 ----------------- sharing/analytics/analytics_recorder.h | 192 ++-- sharing/analytics/analytics_recorder_test.cc | 901 ------------------- sharing/fake_nearby_sharing_service.h | 21 +- sharing/incoming_share_session_test.cc | 6 +- sharing/nearby_sharing_service_impl_test.cc | 12 +- sharing/outgoing_share_session_test.cc | 6 +- sharing/outgoing_targets_manager_test.cc | 4 +- sharing/share_session_test.cc | 6 +- 12 files changed, 126 insertions(+), 1906 deletions(-) delete mode 100644 sharing/analytics/analytics_recorder.cc delete mode 100644 sharing/analytics/analytics_recorder_test.cc diff --git a/internal/analytics/BUILD b/internal/analytics/BUILD index 39427317..9b22ebf8 100644 --- a/internal/analytics/BUILD +++ b/internal/analytics/BUILD @@ -24,6 +24,7 @@ cc_library( "//connections:__subpackages__", "//location/nearby/analytics/cpp:__subpackages__", "//location/nearby/cpp/experiments:__subpackages__", + "//location/nearby/sharing/lib:__subpackages__", "//sharing:__subpackages__", ], deps = [ diff --git a/sharing/BUILD b/sharing/BUILD index caf97bf2..063a477a 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -464,10 +464,10 @@ cc_library( "//internal/base:file_path", "//internal/platform:types", "//internal/test", + "//location/nearby/sharing/lib/analytics", "//location/nearby/sharing/lib/rpc:fake_nearby_share_client", "//location/nearby/sharing/lib/rpc:sharing_rpc_client", "//location/nearby/sharing/lib/sync:sync_manager", - "//sharing/analytics", "//sharing/certificates", "//sharing/common:enum", "//sharing/internal/api:platform", @@ -661,8 +661,8 @@ cc_test( "//location/nearby/sharing/lib/account:fake_account_manager", "//location/nearby/sharing/lib/account:mock_account_manager", "//location/nearby/sharing/lib/account:signin_attempt", + "//location/nearby/sharing/lib/analytics", "//location/nearby/sharing/lib/rpc:fake_nearby_share_client", - "//sharing/analytics", "//sharing/certificates", "//sharing/certificates:test_support", "//sharing/common", @@ -868,16 +868,14 @@ cc_test( ":nearby_connection_impl", ":paired_key_verification_runner", ":share_session", - ":share_session_usage", ":test_support", ":transfer_metadata", ":transfer_metadata_matchers", ":types", "//internal/analytics:mock_event_logger", - "//internal/base:file_path", "//internal/platform/implementation:platform_impl", "//internal/test", - "//sharing/analytics", + "//location/nearby/sharing/lib/analytics", "//sharing/certificates:test_support", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", @@ -931,8 +929,8 @@ cc_test( "//internal/network:url", "//internal/platform/implementation:platform_impl", "//internal/test", + "//location/nearby/sharing/lib/analytics", "//net/proto2/contrib/parse_proto:parse_text_proto", - "//sharing/analytics", "//sharing/certificates:test_support", "//sharing/common:enum", "//sharing/proto:wire_format_cc_proto", @@ -952,7 +950,6 @@ cc_test( ":attachments", ":connection_types", ":nearby_connection_impl", - ":paired_key_verification_runner", ":share_session", ":share_session_usage", ":test_support", @@ -963,8 +960,8 @@ cc_test( "//internal/base:file_path", "//internal/platform/implementation:platform_impl", "//internal/test", + "//location/nearby/sharing/lib/analytics", "//proto:sharing_enums_cc_proto", - "//sharing/analytics", "//sharing/internal/public:logging", "//sharing/proto:wire_format_cc_proto", "//sharing/proto/analytics:sharing_log_cc_proto", @@ -1033,7 +1030,7 @@ cc_test( ":types", "//internal/platform/implementation:platform_impl", "//internal/test", - "//sharing/analytics", + "//location/nearby/sharing/lib/analytics", "//sharing/certificates", "//sharing/certificates:test_support", "@com_github_protobuf_matchers//protobuf-matchers", diff --git a/sharing/analytics/BUILD b/sharing/analytics/BUILD index b1ff308b..8294c9f9 100644 --- a/sharing/analytics/BUILD +++ b/sharing/analytics/BUILD @@ -13,15 +13,11 @@ # limitations under the License. load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") licenses(["notice"]) cc_library( name = "analytics", - srcs = [ - "analytics_recorder.cc", - ], hdrs = [ "analytics_device_settings.h", "analytics_information.h", @@ -29,38 +25,12 @@ cc_library( ], visibility = ["//visibility:public"], deps = [ - "//internal/analytics:event_logger", "//proto:sharing_enums_cc_proto", "//sharing:attachments", "//sharing:types", "//sharing/common:enum", "//sharing/proto:enums_cc_proto", - "//sharing/proto/analytics:sharing_log_cc_proto", - "@com_google_absl//absl/random", "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/time", - "@com_google_protobuf//:protobuf", - ], -) - -cc_test( - name = "analytics_test", - srcs = ["analytics_recorder_test.cc"], - deps = [ - ":analytics", - "//internal/analytics:mock_event_logger", - "//internal/platform/implementation:platform_impl", - "//proto:sharing_enums_cc_proto", - "//sharing:attachments", - "//sharing:types", - "//sharing/common:enum", - "//sharing/proto:enums_cc_proto", - "//sharing/proto:wire_format_cc_proto", - "//sharing/proto/analytics:sharing_log_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - "@com_google_protobuf//:protobuf", ], ) diff --git a/sharing/analytics/analytics_recorder.cc b/sharing/analytics/analytics_recorder.cc deleted file mode 100644 index 3a37df92..00000000 --- a/sharing/analytics/analytics_recorder.cc +++ /dev/null @@ -1,838 +0,0 @@ -// Copyright 2022-2023 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. - -#include "sharing/analytics/analytics_recorder.h" - -#include -#include -#include -#include - -#include "google/protobuf/duration.pb.h" -#include "absl/random/random.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "proto/sharing_enums.pb.h" -#include "sharing/analytics/analytics_device_settings.h" -#include "sharing/analytics/analytics_information.h" -#include "sharing/attachment_container.h" -#include "sharing/common/nearby_share_enums.h" -#include "sharing/file_attachment.h" -#include "sharing/proto/analytics/nearby_sharing_log.pb.h" -#include "sharing/proto/enums.pb.h" -#include "sharing/share_target.h" -#include "sharing/wifi_credentials_attachment.h" - -namespace nearby { -namespace sharing { -namespace analytics { -namespace { - -using ::location::nearby::proto::sharing::DeviceRelationship; -using ::location::nearby::proto::sharing::DeviceType; -using ::location::nearby::proto::sharing::EstablishConnectionStatus; -using ::location::nearby::proto::sharing::EventCategory; -using ::location::nearby::proto::sharing::EventType; -using ::location::nearby::proto::sharing::OSType; -using ::location::nearby::proto::sharing::ProcessReceivedAttachmentsStatus; -using ::location::nearby::proto::sharing::ShowNotificationStatus; -using ::location::nearby::proto::sharing::Visibility; - -using ::nearby::sharing::analytics::proto::SharingLog; -using ::nearby::sharing::proto::DataUsage; -using ::nearby::sharing::proto::DeviceVisibility; - -DeviceRelationship GetLoggerDeviceRelationship( - const ShareTarget& share_target) { - if (share_target.for_self_share) { - return DeviceRelationship::IS_SELF; - } else if (share_target.is_known) { - return DeviceRelationship::IS_CONTACT; - } else { - return DeviceRelationship::IS_STRANGER; - } -} - -DeviceType GetLoggerDeviceType(ShareTargetType type) { - switch (type) { - case ShareTargetType::kLaptop: - return DeviceType::LAPTOP; - case ShareTargetType::kPhone: - return DeviceType::PHONE; - case ShareTargetType::kTablet: - return DeviceType::TABLET; - default: - return DeviceType::UNKNOWN_DEVICE_TYPE; - } -} - -Visibility GetLoggerVisibility(DeviceVisibility visibility) { - switch (visibility) { - case DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS: - return Visibility::CONTACTS_ONLY; - case DeviceVisibility::DEVICE_VISIBILITY_SELECTED_CONTACTS: - return Visibility::SELECTED_CONTACTS_ONLY; - case DeviceVisibility::DEVICE_VISIBILITY_EVERYONE: - return Visibility::EVERYONE; - case DeviceVisibility::DEVICE_VISIBILITY_SELF_SHARE: - return Visibility::SELF_SHARE; - case DeviceVisibility::DEVICE_VISIBILITY_HIDDEN: - return Visibility::HIDDEN; - case DeviceVisibility::DEVICE_VISIBILITY_UNSPECIFIED: - default: - return Visibility::UNKNOWN_VISIBILITY; - } -} - -location::nearby::proto::sharing::DataUsage GetLoggerDataUsage( - DataUsage data_usage) { - switch (data_usage) { - case DataUsage::OFFLINE_DATA_USAGE: - return location::nearby::proto::sharing::DataUsage::OFFLINE; - case DataUsage::ONLINE_DATA_USAGE: - return location::nearby::proto::sharing::DataUsage::ONLINE; - case DataUsage::WIFI_ONLY_DATA_USAGE: - return location::nearby::proto::sharing::DataUsage::WIFI_ONLY; - default: - return location::nearby::proto::sharing::DataUsage::UNKNOWN_DATA_USAGE; - } -} - -void SetShareTargetInfo(SharingLog::ShareTargetInfo* share_target_info, - ShareTargetType device_type, - DeviceRelationship relationship, - OSType os_type = OSType::UNKNOWN_OS_TYPE) { - share_target_info->set_device_relationship(relationship); - share_target_info->set_device_type(GetLoggerDeviceType(device_type)); - if (os_type == OSType::UNKNOWN_OS_TYPE && - device_type == ShareTargetType::kPhone) { - // If the device type is phone, just set the OS type to android because - // no other phone OS for now. - share_target_info->set_os_type(OSType::ANDROID); - } else { - share_target_info->set_os_type(os_type); - } -} - -void SetShareTargetInfo(SharingLog::ShareTargetInfo* share_target_info, - const ShareTarget& share_target, - OSType os_type = OSType::UNKNOWN_OS_TYPE) { - share_target_info->set_device_relationship( - GetLoggerDeviceRelationship(share_target)); - share_target_info->set_device_type(GetLoggerDeviceType(share_target.type)); - if (os_type == OSType::UNKNOWN_OS_TYPE && - share_target.type == ShareTargetType::kPhone) { - // If the device type is phone, just set the OS type to android because - // no other phone OS for now. - share_target_info->set_os_type(OSType::ANDROID); - } else { - share_target_info->set_os_type(os_type); - } -} - -void SetAttachmentInfo(SharingLog::AttachmentsInfo* attachments_info, - const AttachmentContainer& attachments) { - for (const auto& attachment : attachments.GetTextAttachments()) { - SharingLog::TextAttachment::Type type = - SharingLog::TextAttachment::UNKNOWN_TEXT_TYPE; - switch (attachment.GetShareType()) { - case ShareType::kPhone: - type = SharingLog::TextAttachment::PHONE_NUMBER; - break; - case ShareType::kUrl: - type = SharingLog::TextAttachment::URL; - break; - case ShareType::kAddress: - type = SharingLog::TextAttachment::ADDRESS; - break; - case ShareType::kText: - // Apply UNKNOWN_TEXT_TYPE for it based on analytics design. - break; - default: - break; - } - SharingLog::TextAttachment* text_attachment = - attachments_info->mutable_text_attachment()->Add(); - text_attachment->set_type(type); - text_attachment->set_size_bytes(attachment.size()); - text_attachment->set_source_type(attachment.source_type()); - text_attachment->set_batch_id(attachment.batch_id()); - } - - for (const auto& attachment : attachments.GetFileAttachments()) { - SharingLog::FileAttachment::Type type = - SharingLog::FileAttachment::UNKNOWN_FILE_TYPE; - switch (attachment.GetShareType()) { - case ShareType::kImageFile: - type = SharingLog::FileAttachment::IMAGE; - break; - case ShareType::kVideoFile: - type = SharingLog::FileAttachment::VIDEO; - break; - case ShareType::kAudioFile: - type = SharingLog::FileAttachment::AUDIO; - break; - case ShareType::kPdfFile: - case ShareType::kTextFile: - case ShareType::kGoogleDocsFile: - case ShareType::kGoogleSheetsFile: - case ShareType::kGoogleSlidesFile: - type = SharingLog::FileAttachment::DOCUMENT; - break; - case ShareType::kUnknownFile: - // The default type is set to type. - break; - default: - break; - } - SharingLog::FileAttachment* file_attachment = - attachments_info->mutable_file_attachment()->Add(); - file_attachment->set_type(type); - file_attachment->set_size_bytes(attachment.size()); - file_attachment->set_offset_bytes(0); - file_attachment->set_source_type(attachment.source_type()); - file_attachment->set_batch_id(attachment.batch_id()); - } - - for (const auto& attachment : attachments.GetWifiCredentialsAttachments()) { - SharingLog::WifiCredentialsAttachment* wifi_credentials_attachment = - attachments_info->mutable_wifi_credentials_attachment()->Add(); - wifi_credentials_attachment->set_source_type(attachment.source_type()); - wifi_credentials_attachment->set_batch_id(attachment.batch_id()); - } -} - -} // namespace - -void AnalyticsRecorder::NewEstablishConnection( - int64_t session_id, EstablishConnectionStatus connection_status, - const ShareTarget& share_target, int transfer_position, - int concurrent_connections, int64_t duration_millis, - std::optional referrer_package) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SENDING_EVENT, EventType::ESTABLISH_CONNECTION); - - auto* establish_connection = sharing_log->mutable_establish_connection(); - - establish_connection->set_session_id(session_id); - establish_connection->set_status(connection_status); - SetShareTargetInfo(establish_connection->mutable_share_target_info(), - share_target); - establish_connection->set_transfer_position(transfer_position); - establish_connection->set_concurrent_connections(concurrent_connections); - establish_connection->set_duration_millis(duration_millis); - if (referrer_package.has_value()) { - establish_connection->set_referrer_name(*referrer_package); - } - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewAcceptAgreements() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::ACCEPT_AGREEMENTS); - - sharing_log->mutable_accept_agreements(); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewDeclineAgreements() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::DECLINE_AGREEMENTS); - - sharing_log->mutable_decline_agreements(); - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewAddContact() { - std::unique_ptr sharing_log = - CreateSharingLog(EventCategory::SETTINGS_EVENT, EventType::ADD_CONTACT); - - sharing_log->mutable_add_contact(); - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewRemoveContact() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::REMOVE_CONTACT); - - sharing_log->mutable_remove_contact(); - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewTapFeedback() { - std::unique_ptr sharing_log = - CreateSharingLog(EventCategory::SETTINGS_EVENT, EventType::TAP_FEEDBACK); - - sharing_log->mutable_tap_feedback(); - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewTapHelp() { - std::unique_ptr sharing_log = - CreateSharingLog(EventCategory::SETTINGS_EVENT, EventType::TAP_HELP); - - sharing_log->mutable_tap_help(); - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewLaunchDeviceContactConsent( - ::location::nearby::proto::sharing::ConsentAcceptanceStatus status) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::LAUNCH_CONSENT); - - auto* launch_consent = sharing_log->mutable_launch_consent(); - launch_consent->set_status(status); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewAdvertiseDevicePresenceEnd(int64_t session_id) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::ADVERTISE_DEVICE_PRESENCE_END); - - auto* advertise_device_presence_end = - sharing_log->mutable_advertise_device_presence_end(); - advertise_device_presence_end->set_session_id(session_id); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewAdvertiseDevicePresenceStart( - int64_t session_id, DeviceVisibility visibility, - ::location::nearby::proto::sharing::SessionStatus status, - DataUsage data_usage, std::optional referrer_package) { - std::unique_ptr sharing_log = - CreateSharingLog(EventCategory::RECEIVING_EVENT, - EventType::ADVERTISE_DEVICE_PRESENCE_START); - - auto* advertise_device_presence_start = - sharing_log->mutable_advertise_device_presence_start(); - advertise_device_presence_start->set_session_id(session_id); - advertise_device_presence_start->set_visibility( - GetLoggerVisibility(visibility)); - advertise_device_presence_start->set_status(status); - advertise_device_presence_start->set_data_usage( - GetLoggerDataUsage(data_usage)); - if (referrer_package.has_value()) { - advertise_device_presence_start->set_referrer_name(*referrer_package); - } - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewDescribeAttachments( - const AttachmentContainer& attachments) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SENDING_EVENT, EventType::DESCRIBE_ATTACHMENTS); - - auto* describe_attachments = sharing_log->mutable_describe_attachments(); - SetAttachmentInfo(describe_attachments->mutable_attachments_info(), - attachments); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewDiscoverShareTarget( - const ShareTarget& share_target, int64_t session_id, - int64_t latency_since_scanning_start_millis, int64_t flow_id, - std::optional referrer_package, - int64_t latency_since_send_surface_registered_millis) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SENDING_EVENT, EventType::DISCOVER_SHARE_TARGET); - - auto* discover_share_target = sharing_log->mutable_discover_share_target(); - discover_share_target->set_session_id(session_id); - auto* duration = discover_share_target->mutable_duration_since_scanning(); - duration->set_seconds(latency_since_scanning_start_millis / 1000); - duration->set_nanos((latency_since_scanning_start_millis % 1000) * 1000000); - SetShareTargetInfo(discover_share_target->mutable_share_target_info(), - share_target); - discover_share_target->set_session_id(session_id); - discover_share_target->set_flow_id(flow_id); - - discover_share_target->set_latency_since_activity_start_millis( - latency_since_send_surface_registered_millis > 0 - ? latency_since_send_surface_registered_millis - : -1); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewEnableNearbySharing( - ::location::nearby::proto::sharing::NearbySharingStatus status) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::ENABLE_NEARBY_SHARING); - - auto* enable_nearby_sharing = sharing_log->mutable_enable_nearby_sharing(); - enable_nearby_sharing->set_status(status); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewOpenReceivedAttachments( - const AttachmentContainer& attachments, int64_t session_id) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::OPEN_RECEIVED_ATTACHMENTS); - - auto* open_received_attachments = - sharing_log->mutable_open_received_attachments(); - SetAttachmentInfo(open_received_attachments->mutable_attachments_info(), - attachments); - open_received_attachments->set_session_id(session_id); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewProcessReceivedAttachmentsEnd( - int64_t session_id, ProcessReceivedAttachmentsStatus status) { - std::unique_ptr sharing_log = - CreateSharingLog(EventCategory::RECEIVING_EVENT, - EventType::PROCESS_RECEIVED_ATTACHMENTS_END); - - auto* process_received_attachments_end = - sharing_log->mutable_process_received_attachments_end(); - process_received_attachments_end->set_status(status); - process_received_attachments_end->set_session_id(session_id); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewReceiveAttachmentsEnd( - int64_t session_id, int64_t received_bytes, - ::location::nearby::proto::sharing::AttachmentTransmissionStatus status, - std::optional referrer_package) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::RECEIVE_ATTACHMENTS_END); - - auto* receive_attachments_end = - sharing_log->mutable_receive_attachments_end(); - receive_attachments_end->set_session_id(session_id); - receive_attachments_end->set_received_bytes(received_bytes); - receive_attachments_end->set_status(status); - if (referrer_package.has_value()) { - receive_attachments_end->set_referrer_name(*referrer_package); - } - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewReceiveAttachmentsStart( - int64_t session_id, const AttachmentContainer& attachments) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::RECEIVE_ATTACHMENTS_START); - - auto* receive_attachments_start = - sharing_log->mutable_receive_attachments_start(); - SetAttachmentInfo(receive_attachments_start->mutable_attachments_info(), - attachments); - receive_attachments_start->set_session_id(session_id); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewReceiveFastInitialization( - int64_t timeElapseSinceScreenUnlockMillis) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::RECEIVE_FAST_INITIALIZATION); - - auto* receive_fast_initialization = - sharing_log->mutable_receive_initialization(); - - receive_fast_initialization->set_time_elapse_since_screen_unlock_millis( - timeElapseSinceScreenUnlockMillis); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewAcceptFastInitialization() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::ACCEPT_FAST_INITIALIZATION); - - sharing_log->mutable_accept_fast_initialization(); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewDismissFastInitialization() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::DISMISS_FAST_INITIALIZATION); - - sharing_log->mutable_dismiss_fast_initialization(); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewReceiveIntroduction( - int64_t session_id, const ShareTarget& share_target, - std::optional referrer_package, - ::location::nearby::proto::sharing::OSType share_target_os_type) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::RECEIVE_INTRODUCTION); - - auto* receive_introduction = sharing_log->mutable_receive_introduction(); - receive_introduction->set_session_id(session_id); - SetShareTargetInfo(receive_introduction->mutable_share_target_info(), - share_target, share_target_os_type); - if (referrer_package.has_value()) { - receive_introduction->set_referrer_name(*referrer_package); - } - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewRespondToIntroduction( - ::location::nearby::proto::sharing::ResponseToIntroduction action, - int64_t session_id) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::RESPOND_TO_INTRODUCTION); - - auto* respond_to_introduction = sharing_log->mutable_respond_introduction(); - respond_to_introduction->set_session_id(session_id); - respond_to_introduction->set_action(action); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewTapPrivacyNotification() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::TAP_PRIVACY_NOTIFICATION); - - sharing_log->mutable_tap_privacy_notification(); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewDismissPrivacyNotification() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::RECEIVING_EVENT, EventType::DISMISS_PRIVACY_NOTIFICATION); - - sharing_log->mutable_dismiss_privacy_notification(); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewScanForShareTargetsEnd(int64_t session_id) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SENDING_EVENT, EventType::SCAN_FOR_SHARE_TARGETS_END); - - auto* scan_for_share_targets_end = - sharing_log->mutable_scan_for_share_targets_end(); - scan_for_share_targets_end->set_session_id(session_id); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewScanForShareTargetsStart( - int64_t session_id, - ::location::nearby::proto::sharing::SessionStatus status, - AnalyticsInformation analytics_information, int64_t flow_id, - std::optional referrer_package) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SENDING_EVENT, EventType::SCAN_FOR_SHARE_TARGETS_START); - - auto* scan_for_share_targets_start = - sharing_log->mutable_scan_for_share_targets_start(); - scan_for_share_targets_start->set_session_id(session_id); - scan_for_share_targets_start->set_status(status); - scan_for_share_targets_start->set_scan_type( - static_cast<::location::nearby::proto::sharing::ScanType>( - analytics_information.send_surface_state)); - scan_for_share_targets_start->set_flow_id(flow_id); - if (referrer_package.has_value()) { - scan_for_share_targets_start->set_referrer_name(*referrer_package); - } - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewSendAttachmentsEnd( - int64_t session_id, int64_t sent_bytes, const ShareTarget& share_target, - ::location::nearby::proto::sharing::AttachmentTransmissionStatus status, - int transfer_position, int concurrent_connections, int64_t duration_millis, - std::optional referrer_package, - ::location::nearby::proto::sharing::ConnectionLayerStatus - connection_layer_status, - ::location::nearby::proto::sharing::OSType share_target_os_type) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SENDING_EVENT, EventType::SEND_ATTACHMENTS_END); - - auto* send_attachments_end = sharing_log->mutable_send_attachments_end(); - send_attachments_end->set_session_id(session_id); - send_attachments_end->set_sent_bytes(sent_bytes); - SetShareTargetInfo(send_attachments_end->mutable_share_target_info(), - share_target, share_target_os_type); - send_attachments_end->set_status(status); - send_attachments_end->set_transfer_position(transfer_position); - send_attachments_end->set_concurrent_connections(concurrent_connections); - send_attachments_end->set_duration_millis(duration_millis); - if (referrer_package.has_value()) { - send_attachments_end->set_referrer_name(*referrer_package); - } - send_attachments_end->set_connection_layer_status(connection_layer_status); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewSendAttachmentsStart( - int64_t session_id, const AttachmentContainer& attachments, - int transfer_position, int concurrent_connections, - bool advanced_protection_enabled, bool advanced_protection_mismatch) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SENDING_EVENT, EventType::SEND_ATTACHMENTS_START); - - auto* send_attachments_start = sharing_log->mutable_send_attachments_start(); - send_attachments_start->set_session_id(session_id); - SetAttachmentInfo(send_attachments_start->mutable_attachments_info(), - attachments); - send_attachments_start->set_transfer_position(transfer_position); - send_attachments_start->set_concurrent_connections(concurrent_connections); - send_attachments_start->set_advanced_protection_enabled( - advanced_protection_enabled); - send_attachments_start->set_advanced_protection_mismatch( - advanced_protection_mismatch); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewSendFastInitialization() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SENDING_EVENT, EventType::SEND_FAST_INITIALIZATION); - - sharing_log->mutable_send_initialization(); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewSendStart(int64_t session_id, int transfer_position, - int concurrent_connections, - const ShareTarget& share_target) { - std::unique_ptr sharing_log = - CreateSharingLog(EventCategory::SENDING_EVENT, EventType::SEND_START); - - auto* send_start = sharing_log->mutable_send_start(); - send_start->set_session_id(session_id); - send_start->set_transfer_position(transfer_position); - send_start->set_concurrent_connections(concurrent_connections); - SetShareTargetInfo(send_start->mutable_share_target_info(), share_target); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewSendIntroduction( - ShareTargetType target_type, int64_t session_id, - DeviceRelationship relationship, - ::location::nearby::proto::sharing::OSType share_target_os_type) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SENDING_EVENT, EventType::SEND_INTRODUCTION); - auto* send_introduction = sharing_log->mutable_send_introduction(); - SetShareTargetInfo(send_introduction->mutable_share_target_info(), - target_type, relationship, share_target_os_type); - send_introduction->set_session_id(session_id); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewSendIntroduction( - int64_t session_id, const ShareTarget& share_target, int transfer_position, - int concurrent_connections, - ::location::nearby::proto::sharing::OSType share_target_os_type) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SENDING_EVENT, EventType::SEND_INTRODUCTION); - - auto* send_introduction = sharing_log->mutable_send_introduction(); - SetShareTargetInfo(send_introduction->mutable_share_target_info(), - share_target, share_target_os_type); - send_introduction->set_session_id(session_id); - send_introduction->set_transfer_position(transfer_position); - send_introduction->set_concurrent_connections(concurrent_connections); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewSetVisibility(DeviceVisibility src_visibility, - DeviceVisibility dst_visibility, - int64_t duration_millis) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::SET_VISIBILITY); - - auto* set_visibility = sharing_log->mutable_set_visibility(); - set_visibility->set_visibility(GetLoggerVisibility(dst_visibility)); - set_visibility->set_source_visibility(GetLoggerVisibility(src_visibility)); - set_visibility->set_duration_millis(duration_millis); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewDeviceSettings(AnalyticsDeviceSettings settings) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::DEVICE_SETTINGS); - - auto* device_settings = sharing_log->mutable_device_settings(); - device_settings->set_data_usage(GetLoggerDataUsage(settings.data_usage)); - device_settings->set_device_name_size(settings.device_name_size); - device_settings->set_is_show_notification_enabled( - settings.is_fast_init_notification_enabled); - device_settings->set_visibility(GetLoggerVisibility(settings.visibility)); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewSetDataUsage(DataUsage original_preference, - DataUsage preference) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::SET_DATA_USAGE); - - auto* set_data_usage = sharing_log->mutable_set_data_usage(); - set_data_usage->set_original_preference( - GetLoggerDataUsage(original_preference)); - set_data_usage->set_preference(GetLoggerDataUsage(preference)); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewAddQuickSettingsTile() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::ADD_QUICK_SETTINGS_TILE); - - sharing_log->mutable_add_quick_settings_tile(); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewRemoveQuickSettingsTile() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::REMOVE_QUICK_SETTINGS_TILE); - - sharing_log->mutable_remove_quick_settings_tile(); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewTapQuickSettingsTile() { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::TAP_QUICK_SETTINGS_TILE); - - sharing_log->mutable_tap_quick_settings_tile(); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewToggleShowNotification( - ShowNotificationStatus prev_status, ShowNotificationStatus current_status) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::TOGGLE_SHOW_NOTIFICATION); - - auto* toggle_show_notification = - sharing_log->mutable_toggle_show_notification(); - toggle_show_notification->set_current_status(current_status); - toggle_show_notification->set_previous_status(prev_status); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewSetDeviceName(int device_name_size) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::SET_DEVICE_NAME); - - auto* set_device_name = sharing_log->mutable_set_device_name(); - set_device_name->set_device_name_size(device_name_size); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewRequestSettingPermissions( - ::location::nearby::proto::sharing::PermissionRequestType type, - ::location::nearby::proto::sharing::PermissionRequestResult result) { - std::unique_ptr sharing_log = CreateSharingLog( - EventCategory::SETTINGS_EVENT, EventType::REQUEST_SETTING_PERMISSIONS); - - auto* request_setting_permissions = - sharing_log->mutable_request_setting_permissions(); - request_setting_permissions->set_permission_type(type); - request_setting_permissions->set_permission_request_result(result); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewInstallAPKStatus( - ::location::nearby::proto::sharing::InstallAPKStatus status, - ::location::nearby::proto::sharing::ApkSource source) { - std::unique_ptr sharing_log = - CreateSharingLog(EventCategory::RECEIVING_EVENT, EventType::INSTALL_APK); - - auto* install_apk_status = sharing_log->mutable_install_apk_status(); - install_apk_status->add_status(status); - install_apk_status->add_source(source); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewVerifyAPKStatus( - ::location::nearby::proto::sharing::VerifyAPKStatus status, - ::location::nearby::proto::sharing::ApkSource source) { - std::unique_ptr sharing_log = - CreateSharingLog(EventCategory::RECEIVING_EVENT, EventType::VERIFY_APK); - - auto* verify_apk_status = sharing_log->mutable_verify_apk_status(); - verify_apk_status->add_status(status); - verify_apk_status->add_source(source); - - LogEvent(*sharing_log); -} - -void AnalyticsRecorder::NewRpcCallStatus( - absl::string_view rpc_name, - SharingLog::RpcCallStatus::RpcDirection direction, - int error_code, absl::Duration latency) { - std::unique_ptr sharing_log = - CreateSharingLog(EventCategory::RPC_EVENT, EventType::RPC_CALL_STATUS); - - auto* rpc_call_status = sharing_log->mutable_rpc_call_status(); - rpc_call_status->set_rpc_name(std::string(rpc_name)); - rpc_call_status->set_direction(direction); - rpc_call_status->set_error_code(error_code); - rpc_call_status->set_latency_millis(absl::ToInt64Milliseconds(latency)); - - LogEvent(*sharing_log); -} - -// Start private methods. - -std::unique_ptr AnalyticsRecorder::CreateSharingLog( - EventCategory event_category, EventType event_type) { - auto sharing_log = std::make_unique(); - sharing_log->set_event_category(event_category); - sharing_log->set_event_type(event_type); - sharing_log->mutable_event_metadata()->set_vendor_id(vendor_id_); - return sharing_log; -} - -void AnalyticsRecorder::LogEvent(const SharingLog& message) { - if (event_logger_ == nullptr) { - return; - } - - event_logger_->Log(message); -} - -int64_t AnalyticsRecorder::GenerateNextId() { - absl::BitGen bit_gen; - return absl::Uniform(bit_gen, 0, INT64_MAX - 1) + 1; -} - -} // namespace analytics -} // namespace sharing -} // namespace nearby diff --git a/sharing/analytics/analytics_recorder.h b/sharing/analytics/analytics_recorder.h index e3b776b9..d1bbba4e 100644 --- a/sharing/analytics/analytics_recorder.h +++ b/sharing/analytics/analytics_recorder.h @@ -16,205 +16,195 @@ #define THIRD_PARTY_NEARBY_SHARING_ANALYTICS_ANALYTICS_RECORDER_H_ #include -#include #include #include #include "absl/strings/string_view.h" #include "absl/time/time.h" -#include "internal/analytics/event_logger.h" #include "proto/sharing_enums.pb.h" #include "sharing/analytics/analytics_device_settings.h" #include "sharing/analytics/analytics_information.h" #include "sharing/attachment_container.h" #include "sharing/common/nearby_share_enums.h" -#include "sharing/proto/analytics/nearby_sharing_log.pb.h" #include "sharing/proto/enums.pb.h" #include "sharing/share_target.h" -namespace nearby { -namespace sharing { -namespace analytics { +namespace nearby::sharing::analytics { class AnalyticsRecorder { public: - explicit AnalyticsRecorder(int32_t vendor_id, - nearby::analytics::EventLogger* event_logger) - : vendor_id_(vendor_id), event_logger_(event_logger) {} - ~AnalyticsRecorder() = default; + enum class RpcDirection { + kUnknown = 0, + kIncoming = 1, + kOutgoing = 2, + }; - void NewEstablishConnection( + AnalyticsRecorder() = default; + virtual ~AnalyticsRecorder() = default; + + virtual void NewEstablishConnection( int64_t session_id, location::nearby::proto::sharing::EstablishConnectionStatus connection_status, const ShareTarget& share_target, int transfer_position, int concurrent_connections, int64_t duration_millis, - std::optional referrer_package); + std::optional referrer_package) = 0; - void NewAcceptAgreements(); + virtual void NewAcceptAgreements() = 0; - void NewDeclineAgreements(); + virtual void NewDeclineAgreements() = 0; - void NewAddContact(); + virtual void NewAddContact() = 0; - void NewRemoveContact(); + virtual void NewRemoveContact() = 0; - void NewTapFeedback(); + virtual void NewTapFeedback() = 0; - void NewTapHelp(); + virtual void NewTapHelp() = 0; - void NewLaunchDeviceContactConsent( - location::nearby::proto::sharing::ConsentAcceptanceStatus status); + virtual void NewLaunchDeviceContactConsent( + location::nearby::proto::sharing::ConsentAcceptanceStatus status) = 0; - void NewAdvertiseDevicePresenceEnd(int64_t session_id); + virtual void NewAdvertiseDevicePresenceEnd(int64_t session_id) = 0; - void NewAdvertiseDevicePresenceStart( + virtual void NewAdvertiseDevicePresenceStart( int64_t session_id, nearby::sharing::proto::DeviceVisibility visibility, location::nearby::proto::sharing::SessionStatus status, nearby::sharing::proto::DataUsage data_usage, - std::optional referrer_package); + std::optional referrer_package) = 0; - void NewDescribeAttachments(const AttachmentContainer& attachments); + virtual void NewDescribeAttachments( + const AttachmentContainer& attachments) = 0; - void NewDiscoverShareTarget( + virtual void NewDiscoverShareTarget( const ShareTarget& share_target, int64_t session_id, int64_t latency_since_scanning_start_millis, int64_t flow_id, std::optional referrer_package, - int64_t latency_since_send_surface_registered_millis); + int64_t latency_since_send_surface_registered_millis) = 0; - void NewEnableNearbySharing( - location::nearby::proto::sharing::NearbySharingStatus status); + virtual void NewEnableNearbySharing( + location::nearby::proto::sharing::NearbySharingStatus status) = 0; - void NewOpenReceivedAttachments(const AttachmentContainer& attachments, - int64_t session_id); + virtual void NewOpenReceivedAttachments( + const AttachmentContainer& attachments, int64_t session_id) = 0; - void NewProcessReceivedAttachmentsEnd( + virtual void NewProcessReceivedAttachmentsEnd( int64_t session_id, location::nearby::proto::sharing::ProcessReceivedAttachmentsStatus - status); + status) = 0; - void NewReceiveAttachmentsEnd( + virtual void NewReceiveAttachmentsEnd( int64_t session_id, int64_t received_bytes, location::nearby::proto::sharing::AttachmentTransmissionStatus status, - std::optional referrer_package); + std::optional referrer_package) = 0; - void NewReceiveAttachmentsStart(int64_t session_id, - const AttachmentContainer& attachments); + virtual void NewReceiveAttachmentsStart( + int64_t session_id, const AttachmentContainer& attachments) = 0; - void NewReceiveFastInitialization(int64_t timeElapseSinceScreenUnlockMillis); + virtual void NewReceiveFastInitialization( + int64_t timeElapseSinceScreenUnlockMillis) = 0; - void NewAcceptFastInitialization(); + virtual void NewAcceptFastInitialization() = 0; - void NewDismissFastInitialization(); + virtual void NewDismissFastInitialization() = 0; - void NewReceiveIntroduction( + virtual void NewReceiveIntroduction( int64_t session_id, const ShareTarget& share_target, std::optional referrer_package, - location::nearby::proto::sharing::OSType share_target_os_type); + location::nearby::proto::sharing::OSType share_target_os_type) = 0; - void NewRespondToIntroduction( + virtual void NewRespondToIntroduction( location::nearby::proto::sharing::ResponseToIntroduction action, - int64_t session_id); + int64_t session_id) = 0; - void NewTapPrivacyNotification(); + virtual void NewTapPrivacyNotification() = 0; - void NewDismissPrivacyNotification(); + virtual void NewDismissPrivacyNotification() = 0; - void NewScanForShareTargetsEnd(int64_t session_id); + virtual void NewScanForShareTargetsEnd(int64_t session_id) = 0; - void NewScanForShareTargetsStart( + virtual void NewScanForShareTargetsStart( int64_t session_id, location::nearby::proto::sharing::SessionStatus status, AnalyticsInformation analytics_information, int64_t flow_id, - std::optional referrer_package); + std::optional referrer_package) = 0; - void NewSendAttachmentsEnd( + virtual void NewSendAttachmentsEnd( int64_t session_id, int64_t sent_bytes, const ShareTarget& share_target, location::nearby::proto::sharing::AttachmentTransmissionStatus status, int transfer_position, int concurrent_connections, int64_t duration_millis, std::optional referrer_package, location::nearby::proto::sharing::ConnectionLayerStatus connection_layer_status, - location::nearby::proto::sharing::OSType share_target_os_type); + location::nearby::proto::sharing::OSType share_target_os_type) = 0; - void NewSendAttachmentsStart(int64_t session_id, - const AttachmentContainer& attachments, - int transfer_position, - int concurrent_connections, - bool advanced_protection_enabled, - bool advanced_protection_mismatch); + virtual void NewSendAttachmentsStart(int64_t session_id, + const AttachmentContainer& attachments, + int transfer_position, + int concurrent_connections, + bool advanced_protection_enabled, + bool advanced_protection_mismatch) = 0; - void NewSendFastInitialization(); + virtual void NewSendFastInitialization() = 0; - void NewSendStart(int64_t session_id, int transfer_position, - int concurrent_connections, - const ShareTarget& share_target); + virtual void NewSendStart(int64_t session_id, int transfer_position, + int concurrent_connections, + const ShareTarget& share_target) = 0; - void NewSendIntroduction( + virtual void NewSendIntroduction( ShareTargetType target_type, int64_t session_id, location::nearby::proto::sharing::DeviceRelationship relationship, - location::nearby::proto::sharing::OSType share_target_os_type); + location::nearby::proto::sharing::OSType share_target_os_type) = 0; - void NewSendIntroduction( + virtual void NewSendIntroduction( int64_t session_id, const ShareTarget& share_target, int transfer_position, int concurrent_connections, - location::nearby::proto::sharing::OSType share_target_os_type); + location::nearby::proto::sharing::OSType share_target_os_type) = 0; - void NewSetVisibility(nearby::sharing::proto::DeviceVisibility src_visibility, - nearby::sharing::proto::DeviceVisibility dst_visibility, - int64_t duration_millis); + virtual void NewSetVisibility( + nearby::sharing::proto::DeviceVisibility src_visibility, + nearby::sharing::proto::DeviceVisibility dst_visibility, + int64_t duration_millis) = 0; - void NewDeviceSettings(AnalyticsDeviceSettings settings); + virtual void NewDeviceSettings(AnalyticsDeviceSettings settings) = 0; - void NewSetDataUsage(nearby::sharing::proto::DataUsage original_preference, - nearby::sharing::proto::DataUsage preference); + virtual void NewSetDataUsage( + nearby::sharing::proto::DataUsage original_preference, + nearby::sharing::proto::DataUsage preference) = 0; - void NewAddQuickSettingsTile(); + virtual void NewAddQuickSettingsTile() = 0; - void NewRemoveQuickSettingsTile(); + virtual void NewRemoveQuickSettingsTile() = 0; - void NewTapQuickSettingsTile(); + virtual void NewTapQuickSettingsTile() = 0; - void NewToggleShowNotification( + virtual void NewToggleShowNotification( location::nearby::proto::sharing::ShowNotificationStatus prev_status, - location::nearby::proto::sharing::ShowNotificationStatus current_status); + location::nearby::proto::sharing::ShowNotificationStatus + current_status) = 0; - void NewSetDeviceName(int device_name_size); + virtual void NewSetDeviceName(int device_name_size) = 0; - void NewRequestSettingPermissions( + virtual void NewRequestSettingPermissions( location::nearby::proto::sharing::PermissionRequestType type, - location::nearby::proto::sharing::PermissionRequestResult result); + location::nearby::proto::sharing::PermissionRequestResult result) = 0; - void NewInstallAPKStatus( + virtual void NewInstallAPKStatus( location::nearby::proto::sharing::InstallAPKStatus status, - location::nearby::proto::sharing::ApkSource source); + location::nearby::proto::sharing::ApkSource source) = 0; - void NewVerifyAPKStatus( + virtual void NewVerifyAPKStatus( location::nearby::proto::sharing::VerifyAPKStatus status, - location::nearby::proto::sharing::ApkSource source); + location::nearby::proto::sharing::ApkSource source) = 0; - void NewRpcCallStatus( - absl::string_view rpc_name, - nearby::sharing::analytics::proto::SharingLog::RpcCallStatus::RpcDirection - direction, - int error_code, absl::Duration latency); + virtual void NewRpcCallStatus(absl::string_view rpc_name, + RpcDirection direction, int error_code, + absl::Duration latency) = 0; // Generates a random number for session ID or flow ID. - int64_t GenerateNextId(); - - private: - std::unique_ptr - CreateSharingLog( - location::nearby::proto::sharing::EventCategory event_category, - location::nearby::proto::sharing::EventType event_type); - void LogEvent(const nearby::sharing::analytics::proto::SharingLog& message); - - const int32_t vendor_id_; - nearby::analytics::EventLogger* event_logger_ = nullptr; + virtual int64_t GenerateNextId() = 0; }; -} // namespace analytics -} // namespace sharing -} // namespace nearby +} // namespace nearby::sharing::analytics #endif // THIRD_PARTY_NEARBY_SHARING_ANALYTICS_ANALYTICS_RECORDER_H_ diff --git a/sharing/analytics/analytics_recorder_test.cc b/sharing/analytics/analytics_recorder_test.cc deleted file mode 100644 index 1686947d..00000000 --- a/sharing/analytics/analytics_recorder_test.cc +++ /dev/null @@ -1,901 +0,0 @@ -// Copyright 2022-2023 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. - -#include "sharing/analytics/analytics_recorder.h" - -#include - -#include -#include -#include - -#include "google/protobuf/duration.pb.h" -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "internal/analytics/mock_event_logger.h" -#include "proto/sharing_enums.pb.h" -#include "sharing/analytics/analytics_device_settings.h" -#include "sharing/analytics/analytics_information.h" -#include "sharing/attachment_container.h" -#include "sharing/common/nearby_share_enums.h" -#include "sharing/file_attachment.h" -#include "sharing/proto/analytics/nearby_sharing_log.pb.h" -#include "sharing/proto/enums.pb.h" -#include "sharing/proto/wire_format.pb.h" -#include "sharing/share_target.h" -#include "sharing/text_attachment.h" - -namespace nearby::sharing::analytics { -namespace { - -using ::location::nearby::proto::sharing::EventCategory; -using ::location::nearby::proto::sharing::EventType; -using ::location::nearby::proto::sharing::OSType; -using ::nearby::analytics::MockEventLogger; -using ::nearby::sharing::analytics::proto::SharingLog; -using ::nearby::sharing::proto::DataUsage; -using ::nearby::sharing::proto::DeviceVisibility; -using ::testing::An; - -constexpr absl::string_view kFileName = "fileName"; -constexpr absl::string_view kTextBody = "textBody"; -constexpr absl::string_view kFileDocumentName = "abc.pdf"; -constexpr absl::string_view kFileMimeType = "application/pdf"; -constexpr absl::string_view kTextMimeType = "text/plain"; -constexpr absl::string_view kAppPackageName = "com.google.android.youtube"; - -class AnalyticsRecorderTest : public ::testing::Test { - public: - AnalyticsRecorderTest() = default; - ~AnalyticsRecorderTest() override = default; - - MockEventLogger& event_logger() { return event_logger_; } - - AnalyticsRecorder analytics_recoder() { return analytics_recorder_; } - - private: - MockEventLogger event_logger_; - AnalyticsRecorder analytics_recorder_{/*vendor_id=*/0, &event_logger_}; -}; - -TEST_F(AnalyticsRecorderTest, NewEstablishConnection) { - ShareTarget share_target; - share_target.device_name = "share_target"; - share_target.type = ShareTargetType::kPhone; - - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::ESTABLISH_CONNECTION); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.establish_connection().status(), - location::nearby::proto::sharing::EstablishConnectionStatus:: - CONNECTION_STATUS_SUCCESS); - EXPECT_EQ(log.establish_connection().session_id(), 1); - EXPECT_EQ(log.establish_connection().transfer_position(), 1); - EXPECT_EQ(log.establish_connection().concurrent_connections(), 1); - EXPECT_EQ(log.establish_connection().duration_millis(), 100); - EXPECT_EQ(log.establish_connection().share_target_info().os_type(), - location::nearby::proto::sharing::OSType::ANDROID); - EXPECT_EQ(log.establish_connection().referrer_name(), kAppPackageName); - }); - - analytics_recoder().NewEstablishConnection( - 1, - location::nearby::proto::sharing::EstablishConnectionStatus:: - CONNECTION_STATUS_SUCCESS, - share_target, 1, 1, 100, std::string(kAppPackageName)); -} - -TEST_F(AnalyticsRecorderTest, NewAcceptAgreements) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::ACCEPT_AGREEMENTS); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - }); - - analytics_recoder().NewAcceptAgreements(); -} - -TEST_F(AnalyticsRecorderTest, NewDeclineAgreements) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::DECLINE_AGREEMENTS); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - }); - - analytics_recoder().NewDeclineAgreements(); -} - -TEST_F(AnalyticsRecorderTest, NewAddContact) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::ADD_CONTACT); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - }); - - analytics_recoder().NewAddContact(); -} - -TEST_F(AnalyticsRecorderTest, NewRemoveContact) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::REMOVE_CONTACT); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - }); - - analytics_recoder().NewRemoveContact(); -} - -TEST_F(AnalyticsRecorderTest, NewTapFeedback) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::TAP_FEEDBACK); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - }); - - analytics_recoder().NewTapFeedback(); -} - -TEST_F(AnalyticsRecorderTest, NewTapHelp) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::TAP_HELP); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - }); - - analytics_recoder().NewTapHelp(); -} - -TEST_F(AnalyticsRecorderTest, NewLaunchDeviceContactConsent) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::LAUNCH_CONSENT); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - EXPECT_EQ(log.launch_consent().status(), - location::nearby::proto::sharing::ConsentAcceptanceStatus:: - CONSENT_ACCEPTED); - }); - - analytics_recoder().NewLaunchDeviceContactConsent( - ::location::nearby::proto::sharing::ConsentAcceptanceStatus:: - CONSENT_ACCEPTED); -} - -TEST_F(AnalyticsRecorderTest, NewAdvertiseDevicePresenceEnd) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::ADVERTISE_DEVICE_PRESENCE_END); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ(log.advertise_device_presence_end().session_id(), 100); - }); - - analytics_recoder().NewAdvertiseDevicePresenceEnd(100); -} - -TEST_F(AnalyticsRecorderTest, NewAdvertiseDevicePresenceStart) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::ADVERTISE_DEVICE_PRESENCE_START); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ(log.advertise_device_presence_start().visibility(), - location::nearby::proto::sharing::Visibility::CONTACTS_ONLY); - EXPECT_EQ(log.advertise_device_presence_start().status(), - location::nearby::proto::sharing::SessionStatus:: - SUCCEEDED_SESSION_STATUS); - EXPECT_EQ(log.advertise_device_presence_start().data_usage(), - location::nearby::proto::sharing::DataUsage::OFFLINE); - EXPECT_EQ(log.advertise_device_presence_start().referrer_name(), - kAppPackageName); - EXPECT_EQ(log.advertise_device_presence_start().session_id(), 100); - }); - - analytics_recoder().NewAdvertiseDevicePresenceStart( - 100, DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, - location::nearby::proto::sharing::SessionStatus::SUCCEEDED_SESSION_STATUS, - DataUsage::OFFLINE_DATA_USAGE, std::string(kAppPackageName)); -} - -TEST_F(AnalyticsRecorderTest, NewDescribeAttachments) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::DESCRIBE_ATTACHMENTS); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .text_attachment_size(), - 5); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .text_attachment(0) - .size_bytes(), - kTextBody.size()); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .text_attachment(0) - .type(), - SharingLog::TextAttachment::UNKNOWN_TEXT_TYPE); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .text_attachment(1) - .type(), - SharingLog::TextAttachment::PHONE_NUMBER); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .text_attachment(2) - .type(), - SharingLog::TextAttachment::URL); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .text_attachment(3) - .type(), - SharingLog::TextAttachment::ADDRESS); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .text_attachment(4) - .type(), - SharingLog::TextAttachment::UNKNOWN_TEXT_TYPE); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .file_attachment_size(), - 4); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .file_attachment(0) - .size_bytes(), - 2); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .file_attachment(0) - .type(), - SharingLog::FileAttachment::IMAGE); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .file_attachment(1) - .type(), - SharingLog::FileAttachment::DOCUMENT); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .file_attachment(2) - .type(), - SharingLog::FileAttachment::AUDIO); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .file_attachment(3) - .type(), - SharingLog::FileAttachment::DOCUMENT); - }); - - std::unique_ptr attachments = - AttachmentContainer::Builder( - {TextAttachment(5, service::proto::TextMetadata::TEXT, - std::string(kTextBody), kTextBody.size()), - TextAttachment(6, service::proto::TextMetadata::PHONE_NUMBER, - std::string(kTextBody), kTextBody.size()), - TextAttachment(7, service::proto::TextMetadata::URL, - std::string(kTextBody), kTextBody.size()), - TextAttachment(8, service::proto::TextMetadata::ADDRESS, - std::string(kTextBody), kTextBody.size()), - TextAttachment(9, service::proto::TextMetadata::UNKNOWN, - std::string(kTextBody), kTextBody.size())}, - {FileAttachment(1, 2, std::string(kFileName), "", - service::proto::FileMetadata::IMAGE), - FileAttachment(2, 3, std::string(kFileDocumentName), - std::string(kFileMimeType), - service::proto::FileMetadata::DOCUMENT), - FileAttachment(3, 4, std::string(kFileName), "", - service::proto::FileMetadata::AUDIO), - FileAttachment(4, 5, std::string(kFileName), - std::string(kTextMimeType), - service::proto::FileMetadata::DOCUMENT)}, - {}) - .Build(); - - analytics_recoder().NewDescribeAttachments(*attachments); -} - -TEST_F(AnalyticsRecorderTest, EmptyDescribeAttachments) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::DESCRIBE_ATTACHMENTS); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .text_attachment_size(), - 0); - EXPECT_EQ(log.describe_attachments() - .attachments_info() - .file_attachment_size(), - 0); - }); - - analytics_recoder().NewDescribeAttachments(AttachmentContainer()); -} - -TEST_F(AnalyticsRecorderTest, NewDiscoverShareTarget) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::DISCOVER_SHARE_TARGET); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.discover_share_target().duration_since_scanning().nanos(), - (2100 % 1000) * 1000000); - EXPECT_EQ( - log.discover_share_target().duration_since_scanning().seconds(), - 2100 / 1000); - EXPECT_EQ( - log.discover_share_target() - .share_target_info() - .device_relationship(), - ::location::nearby::proto::sharing::DeviceRelationship::IS_CONTACT); - EXPECT_EQ(log.discover_share_target().share_target_info().device_type(), - ::location::nearby::proto::sharing::DeviceType::LAPTOP); - EXPECT_EQ(log.discover_share_target().share_target_info().os_type(), - ::location::nearby::proto::sharing::OSType::UNKNOWN_OS_TYPE); - EXPECT_EQ(log.discover_share_target().session_id(), 1); - EXPECT_EQ(log.discover_share_target().flow_id(), 100); - EXPECT_FALSE(log.discover_share_target().has_referrer_name()); - EXPECT_EQ( - log.discover_share_target().latency_since_activity_start_millis(), - 2); - }); - - ShareTarget share_target; - share_target.device_name = "share_target"; - share_target.type = ShareTargetType::kLaptop; - share_target.is_incoming = true; - share_target.is_known = true; - - analytics_recoder().NewDiscoverShareTarget(share_target, 1, 2100, 100, - std::nullopt, 2); -} - -TEST_F(AnalyticsRecorderTest, NewEnableNearbySharing) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::ENABLE_NEARBY_SHARING); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - EXPECT_EQ(log.enable_nearby_sharing().status(), - location::nearby::proto::sharing::NearbySharingStatus::ON); - }); - - analytics_recoder().NewEnableNearbySharing( - ::location::nearby::proto::sharing::NearbySharingStatus::ON); -} - -TEST_F(AnalyticsRecorderTest, NewOpenReceivedAttachments) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::OPEN_RECEIVED_ATTACHMENTS); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ(log.open_received_attachments() - .attachments_info() - .text_attachment_size(), - 0); - EXPECT_EQ(log.open_received_attachments() - .attachments_info() - .file_attachment_size(), - 0); - EXPECT_EQ(log.open_received_attachments().session_id(), 1); - }); - - analytics_recoder().NewOpenReceivedAttachments(AttachmentContainer(), 1); -} - -TEST_F(AnalyticsRecorderTest, NewProcessReceivedAttachmentsEnd) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), - EventType::PROCESS_RECEIVED_ATTACHMENTS_END); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ(log.process_received_attachments_end().session_id(), 1); - EXPECT_EQ( - log.process_received_attachments_end().status(), - location::nearby::proto::sharing::ProcessReceivedAttachmentsStatus:: - PROCESSING_STATUS_COMPLETE_PROCESSING_ATTACHMENTS); - }); - - analytics_recoder().NewProcessReceivedAttachmentsEnd( - 1, location::nearby::proto::sharing::ProcessReceivedAttachmentsStatus:: - PROCESSING_STATUS_COMPLETE_PROCESSING_ATTACHMENTS); -} - -TEST_F(AnalyticsRecorderTest, NewReceiveAttachmentsEnd) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::RECEIVE_ATTACHMENTS_END); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ(log.receive_attachments_end().session_id(), 1); - EXPECT_EQ(log.receive_attachments_end().received_bytes(), 2); - EXPECT_EQ( - log.receive_attachments_end().status(), - ::location::nearby::proto::sharing::AttachmentTransmissionStatus:: - COMPLETE_ATTACHMENT_TRANSMISSION_STATUS); - EXPECT_EQ(log.receive_attachments_end().referrer_name(), - kAppPackageName); - }); - - analytics_recoder().NewReceiveAttachmentsEnd( - 1, 2, - ::location::nearby::proto::sharing::AttachmentTransmissionStatus:: - COMPLETE_ATTACHMENT_TRANSMISSION_STATUS, - std::string(kAppPackageName)); -} - -TEST_F(AnalyticsRecorderTest, NewReceiveAttachmentsStart) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::RECEIVE_ATTACHMENTS_START); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ(log.receive_attachments_start().session_id(), 1); - EXPECT_EQ(log.receive_attachments_start() - .attachments_info() - .file_attachment_size(), - 0); - }); - - analytics_recoder().NewReceiveAttachmentsStart(1, AttachmentContainer()); -} - -TEST_F(AnalyticsRecorderTest, NewReceiveFastInitialization) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::RECEIVE_FAST_INITIALIZATION); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ(log.receive_initialization() - .time_elapse_since_screen_unlock_millis(), - 1); - }); - - analytics_recoder().NewReceiveFastInitialization(1); -} - -TEST_F(AnalyticsRecorderTest, NewAcceptFastInitialization) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::ACCEPT_FAST_INITIALIZATION); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - }); - - analytics_recoder().NewAcceptFastInitialization(); -} - -TEST_F(AnalyticsRecorderTest, NewDismissFastInitialization) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::DISMISS_FAST_INITIALIZATION); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - }); - - analytics_recoder().NewDismissFastInitialization(); -} - -TEST_F(AnalyticsRecorderTest, NewReceiveIntroduction) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::RECEIVE_INTRODUCTION); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ(log.receive_introduction().session_id(), 1); - EXPECT_EQ(log.receive_introduction().share_target_info().os_type(), - ::location::nearby::proto::sharing::OSType::WINDOWS); - EXPECT_EQ(log.receive_introduction().share_target_info().device_type(), - ::location::nearby::proto::sharing::DeviceType::PHONE); - EXPECT_EQ(log.receive_introduction().referrer_name(), kAppPackageName); - }); - - ShareTarget share_target; - share_target.device_name = "share_target"; - share_target.type = ShareTargetType::kPhone; - analytics_recoder().NewReceiveIntroduction( - 1, share_target, std::string(kAppPackageName), OSType::WINDOWS); -} - -TEST_F(AnalyticsRecorderTest, NewRespondToIntroduction) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::RESPOND_TO_INTRODUCTION); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ(log.respond_introduction().session_id(), 1); - EXPECT_EQ(log.respond_introduction().action(), - ::location::nearby::proto::sharing::ResponseToIntroduction:: - ACCEPT_INTRODUCTION); - }); - - analytics_recoder().NewRespondToIntroduction( - ::location::nearby::proto::sharing::ResponseToIntroduction:: - ACCEPT_INTRODUCTION, - 1); -} - -TEST_F(AnalyticsRecorderTest, NewTapPrivacyNotification) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::TAP_PRIVACY_NOTIFICATION); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - }); - - analytics_recoder().NewTapPrivacyNotification(); -} - -TEST_F(AnalyticsRecorderTest, NewDismissPrivacyNotification) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::DISMISS_PRIVACY_NOTIFICATION); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - }); - - analytics_recoder().NewDismissPrivacyNotification(); -} - -TEST_F(AnalyticsRecorderTest, NewScanForShareTargetsEnd) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SCAN_FOR_SHARE_TARGETS_END); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.scan_for_share_targets_end().session_id(), 100); - }); - - analytics_recoder().NewScanForShareTargetsEnd(100); -} - -TEST_F(AnalyticsRecorderTest, NewScanForShareTargetsStart) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SCAN_FOR_SHARE_TARGETS_START); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.scan_for_share_targets_start().session_id(), 3); - EXPECT_EQ(log.scan_for_share_targets_start().status(), - ::location::nearby::proto::sharing::SessionStatus:: - FAILED_SESSION_STATUS); - EXPECT_EQ(log.scan_for_share_targets_start().flow_id(), 100); - EXPECT_EQ( - log.scan_for_share_targets_start().scan_type(), - ::location::nearby::proto::sharing::ScanType::FOREGROUND_SCAN); - EXPECT_FALSE(log.scan_for_share_targets_start().has_referrer_name()); - }); - - analytics_recoder().NewScanForShareTargetsStart( - 3, - ::location::nearby::proto::sharing::SessionStatus::FAILED_SESSION_STATUS, - AnalyticsInformation{SendSurfaceState::kForeground}, 100, std::nullopt); -} - -TEST_F(AnalyticsRecorderTest, NewSendAttachmentsEnd) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SEND_ATTACHMENTS_END); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.send_attachments_end().session_id(), 1); - EXPECT_EQ(log.send_attachments_end().sent_bytes(), 2); - EXPECT_EQ(log.send_attachments_end().share_target_info().os_type(), - ::location::nearby::proto::sharing::OSType::ANDROID); - EXPECT_EQ(log.send_attachments_end().share_target_info().device_type(), - ::location::nearby::proto::sharing::DeviceType::PHONE); - EXPECT_EQ(log.send_attachments_end().transfer_position(), 1); - EXPECT_EQ(log.send_attachments_end().concurrent_connections(), 2); - EXPECT_EQ(log.send_attachments_end().duration_millis(), 100); - EXPECT_EQ( - log.send_attachments_end().status(), - ::location::nearby::proto::sharing::AttachmentTransmissionStatus:: - COMPLETE_ATTACHMENT_TRANSMISSION_STATUS); - EXPECT_EQ(log.send_attachments_end().referrer_name(), kAppPackageName); - }); - - ShareTarget share_target; - share_target.device_name = "share_target"; - share_target.type = ShareTargetType::kPhone; - analytics_recoder().NewSendAttachmentsEnd( - 1, 2, share_target, - ::location::nearby::proto::sharing::AttachmentTransmissionStatus:: - COMPLETE_ATTACHMENT_TRANSMISSION_STATUS, - 1, 2, 100, std::string(kAppPackageName), - ::location::nearby::proto::sharing::ConnectionLayerStatus:: - CONNECTION_LAYER_STATUS_UNKNOWN, - OSType::UNKNOWN_OS_TYPE); -} - -TEST_F(AnalyticsRecorderTest, NewSendAttachmentsStart) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SEND_ATTACHMENTS_START); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.send_attachments_start().session_id(), 1); - EXPECT_EQ(log.send_attachments_start() - .attachments_info() - .file_attachment_size(), - 0); - EXPECT_EQ(log.send_attachments_start().transfer_position(), 100); - EXPECT_EQ(log.send_attachments_start().concurrent_connections(), 200); - EXPECT_EQ(log.send_attachments_start().advanced_protection_enabled(), - true); - EXPECT_EQ(log.send_attachments_start().advanced_protection_mismatch(), - true); - }); - - analytics_recoder().NewSendAttachmentsStart(1, AttachmentContainer(), 100, - 200, true, true); -} - -TEST_F(AnalyticsRecorderTest, NewSendFastInitialization) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SEND_FAST_INITIALIZATION); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - }); - - analytics_recoder().NewSendFastInitialization(); -} - -TEST_F(AnalyticsRecorderTest, NewSendStart) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SEND_START); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.send_start().session_id(), 123); - EXPECT_EQ(log.send_start().transfer_position(), 1); - EXPECT_EQ(log.send_start().concurrent_connections(), 2); - EXPECT_EQ(log.send_start().share_target_info().device_type(), - ::location::nearby::proto::sharing::DeviceType::LAPTOP); - EXPECT_EQ(log.send_start().share_target_info().os_type(), - ::location::nearby::proto::sharing::OSType::UNKNOWN_OS_TYPE); - }); - - ShareTarget share_target; - share_target.device_name = "share_target"; - share_target.type = ShareTargetType::kLaptop; - share_target.is_known = true; - share_target.is_incoming = true; - analytics_recoder().NewSendStart(123, 1, 2, share_target); -} - -TEST_F(AnalyticsRecorderTest, NewSendIntroductionWithRelationship) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SEND_INTRODUCTION); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.send_introduction().session_id(), 5); - EXPECT_EQ(log.send_introduction().share_target_info().device_type(), - ::location::nearby::proto::sharing::DeviceType::LAPTOP); - EXPECT_EQ(log.send_introduction().share_target_info().os_type(), - ::location::nearby::proto::sharing::OSType::MACOS); - EXPECT_EQ( - log.send_introduction().share_target_info().device_relationship(), - ::location::nearby::proto::sharing::DeviceRelationship::IS_CONTACT); - }); - - analytics_recoder().NewSendIntroduction( - ShareTargetType::kLaptop, 5, - ::location::nearby::proto::sharing::DeviceRelationship::IS_CONTACT, - OSType::MACOS); -} - -TEST_F(AnalyticsRecorderTest, NewSendIntroduction) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SEND_INTRODUCTION); - EXPECT_EQ(log.event_category(), EventCategory::SENDING_EVENT); - EXPECT_EQ(log.send_introduction().session_id(), 1); - EXPECT_EQ(log.send_introduction().transfer_position(), 2); - EXPECT_EQ(log.send_introduction().concurrent_connections(), 3); - EXPECT_EQ(log.send_introduction().share_target_info().device_type(), - ::location::nearby::proto::sharing::DeviceType::LAPTOP); - EXPECT_EQ(log.send_introduction().share_target_info().os_type(), - ::location::nearby::proto::sharing::OSType::UNKNOWN_OS_TYPE); - }); - - ShareTarget share_target; - share_target.device_name = "share_target"; - share_target.type = ShareTargetType::kLaptop; - analytics_recoder().NewSendIntroduction(1, share_target, 2, 3, - OSType::UNKNOWN_OS_TYPE); -} - -TEST_F(AnalyticsRecorderTest, NewSetVisibility) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SET_VISIBILITY); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - EXPECT_EQ(log.set_visibility().duration_millis(), 100); - EXPECT_EQ(log.set_visibility().source_visibility(), - ::location::nearby::proto::sharing::Visibility::EVERYONE); - EXPECT_EQ( - log.set_visibility().visibility(), - ::location::nearby::proto::sharing::Visibility::CONTACTS_ONLY); - }); - - analytics_recoder().NewSetVisibility( - DeviceVisibility::DEVICE_VISIBILITY_EVERYONE, - DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, 100); -} - -TEST_F(AnalyticsRecorderTest, NewDeviceSettings) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::DEVICE_SETTINGS); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - EXPECT_EQ(log.device_settings().device_name_size(), 10); - EXPECT_EQ(log.device_settings().visibility(), - ::location::nearby::proto::sharing::Visibility::EVERYONE); - EXPECT_EQ(log.device_settings().data_usage(), - ::location::nearby::proto::sharing::DataUsage::WIFI_ONLY); - EXPECT_EQ(log.device_settings().is_show_notification_enabled(), true); - }); - - AnalyticsDeviceSettings device_settings; - device_settings.device_name_size = 10; - device_settings.data_usage = DataUsage::WIFI_ONLY_DATA_USAGE; - device_settings.is_fast_init_notification_enabled = true; - device_settings.visibility = DeviceVisibility::DEVICE_VISIBILITY_EVERYONE; - analytics_recoder().NewDeviceSettings(device_settings); -} - -TEST_F(AnalyticsRecorderTest, NewSetDataUsage) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SET_DATA_USAGE); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - EXPECT_EQ(log.set_data_usage().preference(), - ::location::nearby::proto::sharing::DataUsage::OFFLINE); - EXPECT_EQ(log.set_data_usage().original_preference(), - ::location::nearby::proto::sharing::DataUsage::WIFI_ONLY); - }); - - analytics_recoder().NewSetDataUsage(DataUsage::WIFI_ONLY_DATA_USAGE, - DataUsage::OFFLINE_DATA_USAGE); -} - -TEST_F(AnalyticsRecorderTest, NewAddQuickSettingsTile) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::ADD_QUICK_SETTINGS_TILE); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - }); - - analytics_recoder().NewAddQuickSettingsTile(); -} - -TEST_F(AnalyticsRecorderTest, NewRemoveQuickSettingsTile) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::REMOVE_QUICK_SETTINGS_TILE); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - }); - - analytics_recoder().NewRemoveQuickSettingsTile(); -} - -TEST_F(AnalyticsRecorderTest, NewTapQuickSettingsTile) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::TAP_QUICK_SETTINGS_TILE); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - }); - - analytics_recoder().NewTapQuickSettingsTile(); -} - -TEST_F(AnalyticsRecorderTest, NewToggleShowNotification) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::TOGGLE_SHOW_NOTIFICATION); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - EXPECT_EQ( - log.toggle_show_notification().previous_status(), - ::location::nearby::proto::sharing::ShowNotificationStatus::SHOW); - EXPECT_EQ(log.toggle_show_notification().current_status(), - ::location::nearby::proto::sharing::ShowNotificationStatus:: - NOT_SHOW); - }); - - analytics_recoder().NewToggleShowNotification( - ::location::nearby::proto::sharing::ShowNotificationStatus::SHOW, - ::location::nearby::proto::sharing::ShowNotificationStatus::NOT_SHOW); -} - -TEST_F(AnalyticsRecorderTest, NewSetDeviceName) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::SET_DEVICE_NAME); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - EXPECT_EQ(log.set_device_name().device_name_size(), 16); - }); - - analytics_recoder().NewSetDeviceName(16); -} - -TEST_F(AnalyticsRecorderTest, NewRequestSettingPermissions) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::REQUEST_SETTING_PERMISSIONS); - EXPECT_EQ(log.event_category(), EventCategory::SETTINGS_EVENT); - EXPECT_EQ(log.request_setting_permissions().permission_type(), - ::location::nearby::proto::sharing::PermissionRequestType:: - PERMISSION_BLUETOOTH); - EXPECT_EQ( - log.request_setting_permissions().permission_request_result(), - ::location::nearby::proto::sharing::PermissionRequestResult:: - PERMISSION_GRANTED); - }); - - analytics_recoder().NewRequestSettingPermissions( - ::location::nearby::proto::sharing::PermissionRequestType:: - PERMISSION_BLUETOOTH, - ::location::nearby::proto::sharing::PermissionRequestResult:: - PERMISSION_GRANTED); -} - -TEST_F(AnalyticsRecorderTest, NewInstallAPKStatus) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::INSTALL_APK); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ(log.install_apk_status().status(0), - ::location::nearby::proto::sharing::InstallAPKStatus:: - SUCCESS_INSTALLATION); - EXPECT_EQ( - log.install_apk_status().source(0), - ::location::nearby::proto::sharing::ApkSource::APK_FROM_SD_CARD); - }); - - analytics_recoder().NewInstallAPKStatus( - ::location::nearby::proto::sharing::InstallAPKStatus:: - SUCCESS_INSTALLATION, - ::location::nearby::proto::sharing::ApkSource::APK_FROM_SD_CARD); -} - -TEST_F(AnalyticsRecorderTest, NewVerifyAPKStatus) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::VERIFY_APK); - EXPECT_EQ(log.event_category(), EventCategory::RECEIVING_EVENT); - EXPECT_EQ( - log.verify_apk_status().status(0), - ::location::nearby::proto::sharing::VerifyAPKStatus::INSTALLABLE); - EXPECT_EQ( - log.verify_apk_status().source(0), - ::location::nearby::proto::sharing::ApkSource::APK_FROM_SD_CARD); - }); - - analytics_recoder().NewVerifyAPKStatus( - ::location::nearby::proto::sharing::VerifyAPKStatus::INSTALLABLE, - ::location::nearby::proto::sharing::ApkSource::APK_FROM_SD_CARD); -} - -TEST_F(AnalyticsRecorderTest, NewRpcCallStatus) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([](const SharingLog& log) { - EXPECT_EQ(log.event_type(), EventType::RPC_CALL_STATUS); - EXPECT_EQ(log.event_category(), EventCategory::RPC_EVENT); - EXPECT_EQ(log.rpc_call_status().rpc_name(), "service.rpc_name"); - EXPECT_EQ(log.rpc_call_status().direction(), - SharingLog::RpcCallStatus::OUTGOING); - EXPECT_EQ(log.rpc_call_status().error_code(), 123); - EXPECT_EQ(log.rpc_call_status().latency_millis(), 456); - }); - - analytics_recoder().NewRpcCallStatus( - "service.rpc_name", SharingLog::RpcCallStatus::OUTGOING, 123, - absl::Milliseconds(456)); -} - -TEST_F(AnalyticsRecorderTest, GenerateID) { - int64_t id = analytics_recoder().GenerateNextId(); - EXPECT_GT(id, 0); - int64_t id2 = analytics_recoder().GenerateNextId(); - EXPECT_NE(id2, id); -} - -} // namespace -} // namespace nearby::sharing::analytics diff --git a/sharing/fake_nearby_sharing_service.h b/sharing/fake_nearby_sharing_service.h index ca4c4a0f..e68644af 100644 --- a/sharing/fake_nearby_sharing_service.h +++ b/sharing/fake_nearby_sharing_service.h @@ -20,31 +20,32 @@ #include #include +#include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" +#include "location/nearby/sharing/lib/rpc/fake_nearby_share_client.h" #include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" +#include "location/nearby/sharing/lib/sync/sync_manager.h" #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" +#include "absl/strings/string_view.h" #include "absl/time/time.h" #include "internal/base/observer_list.h" #include "internal/platform/clock.h" +#include "internal/test/fake_clock.h" +#include "internal/test/fake_task_runner.h" #include "sharing/advertisement.h" #include "sharing/attachment_container.h" #include "sharing/certificates/nearby_share_certificate_manager.h" +#include "sharing/fake_nearby_connections_manager.h" #include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/test/fake_preference_manager.h" #include "sharing/nearby_sharing_service.h" #include "sharing/nearby_sharing_settings.h" +#include "sharing/outgoing_targets_manager.h" #include "sharing/share_target.h" #include "sharing/share_target_discovered_callback.h" #include "sharing/transfer_metadata.h" #include "sharing/transfer_update_callback.h" #include "sharing/wrapped_share_target_discovered_callback.h" -#include "internal/test/fake_clock.h" -#include "internal/test/fake_task_runner.h" -#include "location/nearby/sharing/lib/rpc/fake_nearby_share_client.h" -#include "location/nearby/sharing/lib/sync/sync_manager.h" -#include "sharing/analytics/analytics_recorder.h" -#include "sharing/fake_nearby_connections_manager.h" -#include "sharing/internal/test/fake_preference_manager.h" -#include "sharing/outgoing_targets_manager.h" namespace nearby { namespace sharing { @@ -157,7 +158,7 @@ class FakeNearbySharingService : public NearbySharingService { return connections_manager_; } FakeTaskRunner& fake_task_runner() { return service_thread_; } - analytics::AnalyticsRecorder& analytics_recorder() { + analytics::AnalyticsRecorderImpl& analytics_recorder() { return analytics_recorder_; } @@ -201,7 +202,7 @@ class FakeNearbySharingService : public NearbySharingService { FakeClock clock_; FakeTaskRunner service_thread_; FakeNearbyConnectionsManager connections_manager_; - analytics::AnalyticsRecorder analytics_recorder_; + analytics::AnalyticsRecorderImpl analytics_recorder_; FakePreferenceManager preference_manager_; FakeNearbyIdentityClient identity_rpc_client_; std::unique_ptr sync_manager_; diff --git a/sharing/incoming_share_session_test.cc b/sharing/incoming_share_session_test.cc index 4278e32a..f90be90a 100644 --- a/sharing/incoming_share_session_test.cc +++ b/sharing/incoming_share_session_test.cc @@ -24,6 +24,7 @@ #include #include +#include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" @@ -36,7 +37,6 @@ #include "internal/test/fake_device_info.h" #include "internal/test/fake_task_runner.h" #include "proto/sharing_enums.pb.h" -#include "sharing/analytics/analytics_recorder.h" #include "sharing/attachment_compare.h" // IWYU pragma: keep #include "sharing/fake_nearby_connections_manager.h" #include "sharing/file_attachment.h" @@ -186,8 +186,8 @@ class IncomingShareSessionTest : public ::testing::Test { FakeClock clock_; FakeTaskRunner task_runner_{&clock_, 1}; nearby::analytics::MockEventLogger mock_event_logger_; - analytics::AnalyticsRecorder analytics_recorder_{/*vendor_id=*/0, - &mock_event_logger_}; + analytics::AnalyticsRecorderImpl analytics_recorder_{/*vendor_id=*/0, + &mock_event_logger_}; ShareTarget share_target_; MockFunction transfer_metadata_callback_; diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index 6c05d4d6..fb503628 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -30,9 +30,10 @@ #include #include -#include "location/nearby/sharing/lib/account/signin_attempt.h" #include "location/nearby/sharing/lib/account/fake_account_manager.h" #include "location/nearby/sharing/lib/account/mock_account_observer.h" +#include "location/nearby/sharing/lib/account/signin_attempt.h" +#include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" #include "location/nearby/sharing/lib/rpc/fake_nearby_share_client.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" @@ -55,7 +56,6 @@ #include "internal/test/fake_task_runner.h" #include "sharing/advertisement.h" #include "sharing/advertisement_capabilities.h" -#include "sharing/analytics/analytics_recorder.h" #include "sharing/attachment_container.h" #include "sharing/certificates/fake_nearby_share_certificate_manager.h" #include "sharing/certificates/nearby_share_certificate_manager_impl.h" @@ -452,7 +452,7 @@ class NearbySharingServiceImplTest : public testing::Test { SetBluetoothIsPowered(true); SetScreenLocked(false); SetLanConnected(true); - analytics_recorder_ = std::make_unique( + analytics_recorder_ = std::make_unique( /*vendor_id=*/0, /*event_logger=*/nullptr); service_ = CreateService(std::move(fake_task_runner)); @@ -1269,7 +1269,7 @@ class NearbySharingServiceImplTest : public testing::Test { nearby_fast_initiation_factory_; std::unique_ptr connection_; StrictMock* mock_app_info_ = nullptr; - std::unique_ptr analytics_recorder_; + std::unique_ptr analytics_recorder_; std::unique_ptr service_; int expect_transfer_updates_count_ = 0; std::function expect_transfer_updates_callback_; @@ -4852,8 +4852,8 @@ TEST_F(NearbySharingServiceImplTest, RemoveIncomingPayloads) { unknown_file_paths_to_delete, UnorderedElementsAre(FilePath("test1.txt"), FilePath("test2.txt"))); nearby::analytics::MockEventLogger mock_event_logger; - analytics::AnalyticsRecorder analytics_recorder{/*vendor_id=*/0, - &mock_event_logger}; + analytics::AnalyticsRecorderImpl analytics_recorder{/*vendor_id=*/0, + &mock_event_logger}; ShareTarget share_target; share_target.is_incoming = true; IncomingShareSession session( diff --git a/sharing/outgoing_share_session_test.cc b/sharing/outgoing_share_session_test.cc index 38157909..6aed6372 100644 --- a/sharing/outgoing_share_session_test.cc +++ b/sharing/outgoing_share_session_test.cc @@ -22,6 +22,7 @@ #include #include +#include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" #include "net/proto2/contrib/parse_proto/parse_text_proto.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" @@ -36,7 +37,6 @@ #include "internal/test/fake_clock.h" #include "internal/test/fake_device_info.h" #include "internal/test/fake_task_runner.h" -#include "sharing/analytics/analytics_recorder.h" #include "sharing/attachment_container.h" #include "sharing/certificates/test_util.h" #include "sharing/common/nearby_share_enums.h" @@ -162,8 +162,8 @@ class OutgoingShareSessionTest : public ::testing::Test { FakeClock fake_clock_; FakeTaskRunner fake_task_runner_{&fake_clock_, 1}; nearby::analytics::MockEventLogger mock_event_logger_; - analytics::AnalyticsRecorder analytics_recorder_{/*vendor_id=*/0, - &mock_event_logger_}; + analytics::AnalyticsRecorderImpl analytics_recorder_{/*vendor_id=*/0, + &mock_event_logger_}; ShareTarget share_target_; MockFunction transfer_metadata_callback_; diff --git a/sharing/outgoing_targets_manager_test.cc b/sharing/outgoing_targets_manager_test.cc index e6f696eb..863d707b 100644 --- a/sharing/outgoing_targets_manager_test.cc +++ b/sharing/outgoing_targets_manager_test.cc @@ -18,6 +18,7 @@ #include #include +#include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" @@ -25,7 +26,6 @@ #include "internal/test/fake_clock.h" #include "internal/test/fake_device_info.h" #include "internal/test/fake_task_runner.h" -#include "sharing/analytics/analytics_recorder.h" #include "sharing/attachment_container.h" #include "sharing/certificates/nearby_share_decrypted_public_certificate.h" #include "sharing/certificates/test_util.h" @@ -61,7 +61,7 @@ class OutgoingTargetsManagerTest : public ::testing::Test { FakeClock clock_; FakeTaskRunner service_thread_; FakeNearbyConnectionsManager connections_manager_; - analytics::AnalyticsRecorder analytics_recorder_; + analytics::AnalyticsRecorderImpl analytics_recorder_; testing::MockFunction share_target_discovered_callback_; testing::MockFunction diff --git a/sharing/share_session_test.cc b/sharing/share_session_test.cc index ddb3d3b5..d82b8c14 100644 --- a/sharing/share_session_test.cc +++ b/sharing/share_session_test.cc @@ -21,6 +21,7 @@ #include #include +#include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" @@ -32,7 +33,6 @@ #include "internal/test/fake_clock.h" #include "internal/test/fake_device_info.h" #include "internal/test/fake_task_runner.h" -#include "sharing/analytics/analytics_recorder.h" #include "sharing/certificates/fake_nearby_share_certificate_manager.h" #include "sharing/fake_nearby_connections_manager.h" #include "sharing/nearby_connection.h" @@ -97,8 +97,8 @@ class TestShareSession : public ShareSession { FakeNearbyConnectionsManager connections_manager_; FakeDeviceInfo device_info_; nearby::analytics::MockEventLogger mock_event_logger_; - analytics::AnalyticsRecorder analytics_recorder_{/*vendor_id=*/0, - &mock_event_logger_}; + analytics::AnalyticsRecorderImpl analytics_recorder_{/*vendor_id=*/0, + &mock_event_logger_}; const bool is_incoming_; }; From b2e4290a86dd1ce84a864c8dd53985f71b088990 Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 26 May 2026 19:00:37 -0700 Subject: [PATCH 122/151] Automated Code Change PiperOrigin-RevId: 921810984 --- connections/implementation/payload_manager.cc | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/connections/implementation/payload_manager.cc b/connections/implementation/payload_manager.cc index e9f8b57b..f534a2ed 100644 --- a/connections/implementation/payload_manager.cc +++ b/connections/implementation/payload_manager.cc @@ -1102,9 +1102,7 @@ void PayloadManager::HandleSuccessfulOutgoingChunk( const PayloadTransferFrame::PayloadHeader& payload_header, std::int32_t payload_chunk_flags, std::int64_t payload_chunk_offset, std::int64_t payload_chunk_body_size) { - if (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnablePayloadManagerToSkipChunkUpdate)) { + { MutexLock lock(&chunk_update_mutex_); ++outgoing_chunk_update_count_; } @@ -1119,9 +1117,7 @@ void PayloadManager::HandleSuccessfulOutgoingChunk( (payload_chunk_flags & PayloadTransferFrame::PayloadChunk::LAST_CHUNK) != 0; - if (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnablePayloadManagerToSkipChunkUpdate)) { + { MutexLock lock(&chunk_update_mutex_); --outgoing_chunk_update_count_; if (payload_header.has_type() && @@ -1201,9 +1197,7 @@ void PayloadManager::HandleSuccessfulIncomingChunk( const PayloadTransferFrame::PayloadHeader& payload_header, std::int32_t payload_chunk_flags, std::int64_t payload_chunk_offset, std::int64_t payload_chunk_body_size) { - if (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnablePayloadManagerToSkipChunkUpdate)) { + { MutexLock lock(&chunk_update_mutex_); ++incoming_chunk_update_count_; } @@ -1217,9 +1211,7 @@ void PayloadManager::HandleSuccessfulIncomingChunk( (payload_chunk_flags & PayloadTransferFrame::PayloadChunk::LAST_CHUNK) != 0; - if (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnablePayloadManagerToSkipChunkUpdate)) { + { MutexLock lock(&chunk_update_mutex_); --incoming_chunk_update_count_; if (payload_header.has_type() && From f3a8df5db3789bb3fdfe78b6a41083e108e7f6c1 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 28 May 2026 10:08:10 -0700 Subject: [PATCH 123/151] Refactor AnalyticsRecorder into an abstract interface and decouple ClientProxy from logging protos. PiperOrigin-RevId: 922838021 --- Package.swift | 2 +- connections/implementation/BUILD | 13 +- connections/implementation/analytics/BUILD | 28 +- .../analytics/advertising_metadata_params.h | 5 +- .../analytics/analytics_recorder.cc | 1591 +--------------- .../analytics/analytics_recorder.h | 469 +---- .../analytics/analytics_recorder_impl.cc | 1643 +++++++++++++++++ .../analytics/analytics_recorder_impl.h | 459 +++++ ...est.cc => analytics_recorder_impl_test.cc} | 99 +- .../analytics/discovery_metadata_params.h | 5 +- .../analytics/operation_result_with_medium.h | 55 + .../implementation/base_endpoint_channel.cc | 13 +- .../implementation/base_endpoint_channel.h | 12 +- .../implementation/base_pcp_handler.cc | 97 +- connections/implementation/bwu_manager.cc | 7 +- .../implementation/bwu_manager_test.cc | 68 +- connections/implementation/client_proxy.cc | 19 +- connections/implementation/client_proxy.h | 8 +- .../implementation/encryption_runner_test.cc | 12 +- connections/implementation/endpoint_channel.h | 9 +- .../endpoint_channel_manager.cc | 10 +- .../implementation/endpoint_channel_manager.h | 11 +- .../endpoint_channel_manager_test.cc | 18 +- .../implementation/endpoint_manager.cc | 24 +- .../implementation/fake_endpoint_channel.h | 12 +- .../implementation/mock_endpoint_channel.h | 3 +- connections/implementation/payload_manager.cc | 13 +- 27 files changed, 2492 insertions(+), 2213 deletions(-) create mode 100644 connections/implementation/analytics/analytics_recorder_impl.cc create mode 100644 connections/implementation/analytics/analytics_recorder_impl.h rename connections/implementation/analytics/{analytics_recorder_test.cc => analytics_recorder_impl_test.cc} (97%) create mode 100644 connections/implementation/analytics/operation_result_with_medium.h diff --git a/Package.swift b/Package.swift index 27d9b761..50e2600f 100644 --- a/Package.swift +++ b/Package.swift @@ -368,7 +368,7 @@ let package = Package( "connections/implementation/payload_manager_test.cc", "connections/implementation/offline_frames_validator_test.cc", "connections/implementation/service_controller_router_test.cc", - "connections/implementation/analytics/analytics_recorder_test.cc", + "connections/implementation/analytics/analytics_recorder_impl_test.cc", "connections/implementation/analytics/throughput_recorder_test.cc", "connections/implementation/mediums/advertisements/data_element_test.cc", "connections/implementation/mediums/advertisements/dct_advertisement_test.cc", diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index b3bbee2d..c3723458 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -112,6 +112,7 @@ cc_library( deps = [ "//connections:core_types", "//connections/implementation/analytics", + "//connections/implementation/analytics:analytics_recorder_impl", "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums/advertisements:dct_advertisement", "//connections/implementation/proto:offline_wire_formats_cc_proto", @@ -130,7 +131,6 @@ cc_library( "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", "//internal/platform/implementation:types", - "//internal/proto/analytics:connections_log_cc_proto", "//proto:connections_enums_cc_proto", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", @@ -158,7 +158,6 @@ cc_library( deps = [ ":client_proxy", ":offline_frames", - ":types", "//connections:core_types", "//connections/implementation/analytics", "//connections/implementation/flags:connections_flags", @@ -167,7 +166,6 @@ cc_library( "//internal/platform:logging", "//internal/platform:types", "//internal/platform/implementation:types", - "//internal/proto/analytics:connections_log_cc_proto", "//proto:connections_enums_cc_proto", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", @@ -263,7 +261,6 @@ cc_library( "//internal/platform/implementation:platform", "//internal/platform/implementation:types", "//internal/platform/implementation:wifi_utils", - "//internal/proto/analytics:connections_log_cc_proto", "//proto:connections_enums_cc_proto", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:btree", @@ -341,22 +338,18 @@ cc_test( ":offline_frames", ":service_id_constants", "//connections:core_types", + "//connections/implementation/analytics", "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums", "//internal/flags:nearby_flags", "//internal/platform:base", - "//internal/platform:logging", - "//internal/platform:test_util", "//internal/platform:types", - "//internal/platform/flags:platform_flags", "//internal/platform/implementation:platform", # build_cleaner: keep "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/proto/analytics:connections_log_cc_proto", "//proto:connections_enums_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], ) @@ -556,13 +549,13 @@ cc_test( ":endpoint_channel", ":internal", ":offline_frames", + "//connections/implementation/analytics", "//connections/implementation/flags:connections_flags", "//internal/flags:nearby_flags", "//internal/platform:base", "//internal/platform:logging", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/proto/analytics:connections_log_cc_proto", "//proto:connections_enums_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings", diff --git a/connections/implementation/analytics/BUILD b/connections/implementation/analytics/BUILD index f84377b4..0e47a452 100644 --- a/connections/implementation/analytics/BUILD +++ b/connections/implementation/analytics/BUILD @@ -26,10 +26,30 @@ cc_library( "analytics_recorder.h", "connection_attempt_metadata_params.h", "discovery_metadata_params.h", + "operation_result_with_medium.h", ], copts = ["-DCORE_ADAPTER_DLL"], visibility = ["//connections:__subpackages__"], deps = [ + "//connections:core_types", + "//internal/platform:error_code_recorder", + "//proto:connections_enums_cc_proto", + "@com_google_absl//absl/time", + ], +) + +cc_library( + name = "analytics_recorder_impl", + srcs = [ + "analytics_recorder_impl.cc", + ], + hdrs = [ + "analytics_recorder_impl.h", + ], + copts = ["-DCORE_ADAPTER_DLL"], + visibility = ["//connections/implementation:__pkg__"], + deps = [ + ":analytics", "//connections:core_types", "//internal/analytics:event_logger", "//internal/platform:error_code_recorder", @@ -40,11 +60,8 @@ cc_library( "//proto:connections_enums_cc_proto", "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/base:no_destructor", "@com_google_absl//absl/container:btree", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/strings:str_format", + "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/time", "@com_google_protobuf//:protobuf_lite", ], @@ -54,11 +71,12 @@ cc_test( name = "analytics_test", size = "small", srcs = [ - "analytics_recorder_test.cc", + "analytics_recorder_impl_test.cc", ], shard_count = 16, deps = [ ":analytics", + ":analytics_recorder_impl", "//connections:core_types", "//internal/analytics:mock_event_logger", "//internal/platform:base", diff --git a/connections/implementation/analytics/advertising_metadata_params.h b/connections/implementation/analytics/advertising_metadata_params.h index 2b3b3372..2b40864b 100644 --- a/connections/implementation/analytics/advertising_metadata_params.h +++ b/connections/implementation/analytics/advertising_metadata_params.h @@ -17,7 +17,7 @@ #include -#include "internal/proto/analytics/connections_log.pb.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" namespace nearby { @@ -26,8 +26,7 @@ struct AdvertisingMetadataParams { bool is_extended_advertisement_supported = false; int connected_ap_frequency = 0; bool is_nfc_available = false; - std::vector + std::vector operation_result_with_mediums = {}; }; diff --git a/connections/implementation/analytics/analytics_recorder.cc b/connections/implementation/analytics/analytics_recorder.cc index f91edcef..67649104 100644 --- a/connections/implementation/analytics/analytics_recorder.cc +++ b/connections/implementation/analytics/analytics_recorder.cc @@ -14,921 +14,35 @@ #include "connections/implementation/analytics/analytics_recorder.h" -#include -#include -#include #include #include -#include #include -#include "absl/algorithm/container.h" -#include "absl/container/btree_map.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" #include "connections/implementation/analytics/advertising_metadata_params.h" #include "connections/implementation/analytics/connection_attempt_metadata_params.h" #include "connections/implementation/analytics/discovery_metadata_params.h" -#include "connections/payload_type.h" -#include "connections/strategy.h" -#include "internal/analytics/event_logger.h" -#include "internal/platform/error_code_params.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex_lock.h" -#include "internal/proto/analytics/connections_log.pb.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" #include "proto/connections_enums.pb.h" -#include "google/protobuf/repeated_ptr_field.h" -namespace nearby { -namespace analytics { +namespace nearby::analytics { -namespace { -// const char kVersion_1_0_0[] = "v1.0.0"; -const char kVersion[] = "v1.5.0"; -constexpr absl::string_view kOnStartClientSession = "OnStartClientSession"; -const absl::Duration kConnectionTokenMaxLife = absl::Hours(24); - -using ::location::nearby::analytics::proto::ConnectionsLog; -using ::location::nearby::proto::connections::ACCEPTED; -using ::location::nearby::proto::connections::ADVERTISER; -using ::location::nearby::proto::connections::BandwidthUpgradeErrorStage; -using ::location::nearby::proto::connections::BandwidthUpgradeResult; -using ::location::nearby::proto::connections::BYTES; -using ::location::nearby::proto::connections::CLIENT_SESSION; -using ::location::nearby::proto::connections::CONNECTION_CLOSED; -using ::location::nearby::proto::connections::ConnectionAttemptDirection; -using ::location::nearby::proto::connections::ConnectionAttemptResult; -using ::location::nearby::proto::connections::ConnectionAttemptType; using ::location::nearby::proto::connections::ConnectionBand; -using ::location::nearby::proto::connections::ConnectionRequestResponse; -using ::location::nearby::proto::connections::ConnectionsStrategy; using ::location::nearby::proto::connections::ConnectionTechnology; -using ::location::nearby::proto::connections::DisconnectionReason; -using ::location::nearby::proto::connections::DISCOVERER; -using ::location::nearby::proto::connections::ERROR_CODE; -using ::location::nearby::proto::connections::EventType; -using ::location::nearby::proto::connections::FILE; -using ::location::nearby::proto::connections::IGNORED; -using ::location::nearby::proto::connections::INCOMING; -using ::location::nearby::proto::connections::INITIAL; using ::location::nearby::proto::connections::Medium; -using ::location::nearby::proto::connections::MOVED_TO_NEW_MEDIUM; -using ::location::nearby::proto::connections::NOT_SENT; -using ::location::nearby::proto::connections::OperationResultCategory; using ::location::nearby::proto::connections::OperationResultCode; -using ::location::nearby::proto::connections::OUTGOING; -using ::location::nearby::proto::connections::P2P_CLUSTER; -using ::location::nearby::proto::connections::P2P_POINT_TO_POINT; -using ::location::nearby::proto::connections::P2P_STAR; -using ::location::nearby::proto::connections::PayloadStatus; -using ::location::nearby::proto::connections::PayloadType; -using ::location::nearby::proto::connections::REJECTED; -using ::location::nearby::proto::connections::RESULT_SUCCESS; -using ::location::nearby::proto::connections::SessionRole; -using ::location::nearby::proto::connections::START_CLIENT_SESSION; -using ::location::nearby::proto::connections::START_STRATEGY_SESSION; -using ::location::nearby::proto::connections::STOP_CLIENT_SESSION; -using ::location::nearby::proto::connections::STOP_STRATEGY_SESSION; -using ::location::nearby::proto::connections::StopAdvertisingReason; -using ::location::nearby::proto::connections::StopDiscoveringReason; -using ::location::nearby::proto::connections::STREAM; -using ::location::nearby::proto::connections::UNFINISHED; -using ::location::nearby::proto::connections::UNFINISHED_ERROR; -using ::location::nearby::proto::connections::UNKNOWN_MEDIUM; -using ::location::nearby::proto::connections::UNKNOWN_PAYLOAD_TYPE; -using ::location::nearby::proto::connections::UNKNOWN_STRATEGY; -using ::location::nearby::proto::connections::UPGRADE_RESULT_SUCCESS; -using ::location::nearby::proto::connections::UPGRADE_SUCCESS; -using ::location::nearby::proto::connections::UPGRADE_UNFINISHED; -using ::location::nearby::proto::connections::UPGRADED; -using ::nearby::analytics::EventLogger; -using SafeDisconnectionResult = ::location::nearby::analytics::proto:: - ConnectionsLog::EstablishedConnection::SafeDisconnectionResult; - -OperationResultCategory ConvertToOperationResultCategory( - OperationResultCode result_code) { - if (result_code == OperationResultCode::DETAIL_SUCCESS) { - return OperationResultCategory::CATEGORY_SUCCESS; - } - // TODO(b/409865630): check later if we need to add back the dct error. - // Section of CATEGORY_DCT_ERROR, from 5000 to 5499 if (result_code - // >= OperationResultCode::DCT_ERROR_BLE_DISABLED) { - // return OperationResultCategory::CATEGORY_DCT_ERROR; - //} - - // Section of CATEGORY_NEARBY_ERROR, starting from 4500 to 4999 - if (result_code >= - OperationResultCode::NEARBY_BLE_ADVERTISEMENT_MAPPING_TO_MAC_ERROR) { - return OperationResultCategory::CATEGORY_NEARBY_ERROR; - } - // Section of CATEGORY_CONNECTIVITY_ERROR, starting from 3500 to 4499 - if (result_code >= - OperationResultCode::CONNECTIVITY_WIFI_AWARE_ATTACH_FAILURE) { - return OperationResultCategory::CATEGORY_CONNECTIVITY_ERROR; - } - // Section of CATEGORY_IO_ERROR, from 3000 to 3499 - if (result_code >= OperationResultCode::IO_FILE_OPENING_ERROR) { - return OperationResultCategory::CATEGORY_IO_ERROR; - } - // Section of CATEGORY_MISCELLANEOUS, from 2500 to 2999 - if (result_code >= - OperationResultCode::MISCELLEANEOUS_BLUETOOTH_MAC_ADDRESS_NULL) { - return OperationResultCategory::CATEGORY_MISCELLANEOUS; - } - // Section of CATEGORY_CLIENT_ERROR, from 2000 to 2499 - if (result_code >= - OperationResultCode:: - CLIENT_WIFI_DIRECT_ALREADY_HOSTING_DIRECT_GROUP_FOR_THIS_CLIENT) { - return OperationResultCategory::CATEGORY_CLIENT_ERROR; - } - // Section of CATEGORY_MEDIUM_UNAVAILABLE, from 1500 to 1999 - if (result_code >= OperationResultCode:: - MEDIUM_UNAVAILABLE_WIFI_AWARE_RESOURCE_NOT_AVAILABLE) { - return OperationResultCategory::CATEGORY_MEDIUM_UNAVAILABLE; - } - // Section of CATEGORY_DEVICE_STATE_ERROR, from 1000 to 1499 - if (result_code >= - OperationResultCode::DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS) { - return OperationResultCategory::CATEGORY_DEVICE_STATE_ERROR; - } - // Section of CATEGORY_CLIENT_CANCELLATION, from 500 to 999 - if (result_code >= - OperationResultCode::CLIENT_CANCELLATION_REMOTE_IN_CANCELED_STATE) { - return OperationResultCategory::CATEGORY_CLIENT_CANCELLATION; - } - // Clarify other non success cases as unknown - return OperationResultCategory::CATEGORY_UNKNOWN; -} -} // namespace - -AnalyticsRecorder::AnalyticsRecorder(EventLogger* event_logger) - : event_logger_(event_logger) { - VLOG(1) << "Start AnalyticsRecorder ctor event_logger_=" << event_logger_; - LogStartSession(); -} - -AnalyticsRecorder::~AnalyticsRecorder() = default; - -bool AnalyticsRecorder::IsSessionLogged() { - MutexLock lock(&mutex_); - return session_was_logged_; -} - -int AnalyticsRecorder::GetLatestUpdateIndexLocked( - const std::vector& list) { - int latest_update_index = 0; - for (const auto& operation_result_with_medium : list) { - if (operation_result_with_medium.update_index() > latest_update_index) { - latest_update_index = operation_result_with_medium.update_index(); - } - } - return latest_update_index; -} - -void AnalyticsRecorder::OnStartAdvertising( - connections::Strategy strategy, const std::vector& mediums, - AdvertisingMetadataParams* advertising_metadata_params) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStartAdvertising")) { - return; - } - if (!strategy.IsValid()) { - LOG(INFO) << "AnalyticsRecorder OnStartAdvertising with unknown " - "strategy, bail out."; - return; - } - // Initialize/update a StrategySession. - UpdateStrategySessionLocked(strategy, ADVERTISER); - - // Initialize and set a AdvertisingPhase. - started_advertising_phase_time_ = SystemClock::ElapsedRealtime(); - current_advertising_phase_ = - std::make_unique(); - absl::c_copy(mediums, RepeatedFieldBackInserter( - current_advertising_phase_->mutable_medium())); - // Set a AdvertisingMetadata. - AdvertisingMetadataParams default_params = {}; - if (advertising_metadata_params == nullptr) { - advertising_metadata_params = &default_params; - } - if (!advertising_metadata_params->operation_result_with_mediums.empty()) { - absl::c_copy(advertising_metadata_params->operation_result_with_mediums, - RepeatedFieldBackInserter( - current_advertising_phase_->mutable_adv_dis_result())); - } - auto* advertising_metadata = - current_advertising_phase_->mutable_advertising_metadata(); - advertising_metadata->set_supports_extended_ble_advertisements( - advertising_metadata_params->is_extended_advertisement_supported); - advertising_metadata->set_connected_ap_frequency( - advertising_metadata_params->connected_ap_frequency); - advertising_metadata->set_supports_nfc_technology( - advertising_metadata_params->is_nfc_available); -} - -void AnalyticsRecorder::OnStopAdvertising() { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStopAdvertising")) { - return; - } - RecordAdvertisingPhaseDurationAndReasonLocked(/* on_stop= */ true); -} - -int AnalyticsRecorder::GetNextAdvertisingUpdateIndex() { - MutexLock lock(&mutex_); - - if (current_advertising_phase_ == nullptr) { - return 0; - } - return GetLatestUpdateIndexLocked( - std::vector( - current_advertising_phase_->adv_dis_result().begin(), - current_advertising_phase_->adv_dis_result().end())) + - 1; -} - -void AnalyticsRecorder::OnStartDiscovery( - connections::Strategy strategy, const std::vector& mediums, - DiscoveryMetadataParams* discovery_metadata_params) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStartDiscovery")) { - return; - } - if (!strategy.IsValid()) { - LOG(INFO) << "AnalyticsRecorder OnStartDiscovery unknown " - "strategy enter, bail out."; - return; - } - - // Initialize/update a StrategySession. - UpdateStrategySessionLocked(strategy, DISCOVERER); - - // Initialize and set a DiscoveryPhase. - started_discovery_phase_time_ = SystemClock::ElapsedRealtime(); - current_discovery_phase_ = std::make_unique(); - absl::c_copy(mediums, RepeatedFieldBackInserter( - current_discovery_phase_->mutable_medium())); - // Set a DiscoveryMetadata. - DiscoveryMetadataParams default_params = {}; - if (discovery_metadata_params == nullptr) { - discovery_metadata_params = &default_params; - } - if (!discovery_metadata_params->operation_result_with_mediums.empty()) { - absl::c_copy(discovery_metadata_params->operation_result_with_mediums, - RepeatedFieldBackInserter( - current_discovery_phase_->mutable_adv_dis_result())); - } - auto* discovery_metadata = - current_discovery_phase_->mutable_discovery_metadata(); - discovery_metadata->set_supports_extended_ble_advertisements( - discovery_metadata_params->is_extended_advertisement_supported); - discovery_metadata->set_connected_ap_frequency( - discovery_metadata_params->connected_ap_frequency); - discovery_metadata->set_supports_nfc_technology( - discovery_metadata_params->is_nfc_available); -} - -void AnalyticsRecorder::OnStopDiscovery() { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStopDiscovery")) { - return; - } - RecordDiscoveryPhaseDurationAndReasonLocked(/*on_stop=*/true); -} - -int AnalyticsRecorder::GetNextDiscoveryUpdateIndex() { - MutexLock lock(&mutex_); - if (current_discovery_phase_ == nullptr) { - return 0; - } - return GetLatestUpdateIndexLocked( - std::vector( - current_discovery_phase_->adv_dis_result().begin(), - current_discovery_phase_->adv_dis_result().end())) + - 1; -} - -void AnalyticsRecorder::OnStartedIncomingConnectionListening( - connections::Strategy strategy) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStartedIncomingConnectionListening")) { - return; - } - UpdateStrategySessionLocked(strategy, ADVERTISER); - if (started_advertising_phase_time_ == absl::InfinitePast()) { - started_advertising_phase_time_ = SystemClock::ElapsedRealtime(); - } -} - -void AnalyticsRecorder::OnStoppedIncomingConnectionListening() { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStoppedIncomingConnectionListening")) { - return; - } - RecordAdvertisingPhaseDurationAndReasonLocked(/* on_stop= */ false); -} - -void AnalyticsRecorder::OnEndpointFound(Medium medium) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnEndpointFound")) { - return; - } - if (current_discovery_phase_ == nullptr) { - LOG(INFO) << "Unable to record discovered endpoint due to null " - "current_discovery_phase_"; - return; - } - ConnectionsLog::DiscoveredEndpoint* discovered_endpoint = - current_discovery_phase_->add_discovered_endpoint(); - discovered_endpoint->set_medium(medium); - discovered_endpoint->set_latency_millis(absl::ToInt64Milliseconds( - SystemClock::ElapsedRealtime() - started_discovery_phase_time_)); -} - -void AnalyticsRecorder::OnRequestConnection( - const connections::Strategy& strategy, const std::string& endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("onRequestConnection")) { - return; - } - - UpdateStrategySessionLocked(strategy, DISCOVERER); - if (started_discovery_phase_time_ == absl::InfinitePast()) { - started_discovery_phase_time_ = SystemClock::ElapsedRealtime(); - } -} - -void AnalyticsRecorder::OnConnectionRequestReceived( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnConnectionRequestReceived")) { - return; - } - absl::Time current_time = SystemClock::ElapsedRealtime(); - auto connection_request = - std::make_unique(); - connection_request->set_duration_millis(absl::ToUnixMillis(current_time)); - connection_request->set_request_delay_millis(absl::ToInt64Milliseconds( - current_time - started_advertising_phase_time_)); - incoming_connection_requests_.insert( - {remote_endpoint_id, std::move(connection_request)}); -} - -void AnalyticsRecorder::OnConnectionRequestSent( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnConnectionRequestSent")) { - return; - } - absl::Time current_time = SystemClock::ElapsedRealtime(); - auto connection_request = - std::make_unique(); - connection_request->set_duration_millis(absl::ToUnixMillis(current_time)); - connection_request->set_request_delay_millis( - absl::ToInt64Milliseconds(current_time - started_discovery_phase_time_)); - outgoing_connection_requests_.insert( - {remote_endpoint_id, std::move(connection_request)}); -} - -void AnalyticsRecorder::OnRemoteEndpointAccepted( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnRemoteEndpointAccepted")) { - return; - } - RemoteEndpointRespondedLocked(remote_endpoint_id, ACCEPTED); -} - -void AnalyticsRecorder::OnLocalEndpointAccepted( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnLocalEndpointAccepted")) { - return; - } - LocalEndpointRespondedLocked(remote_endpoint_id, ACCEPTED); -} - -void AnalyticsRecorder::OnRemoteEndpointRejected( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnRemoteEndpointRejected")) { - return; - } - RemoteEndpointRespondedLocked(remote_endpoint_id, REJECTED); -} - -void AnalyticsRecorder::OnLocalEndpointRejected( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnLocalEndpointRejected")) { - return; - } - LocalEndpointRespondedLocked(remote_endpoint_id, REJECTED); -} - -void AnalyticsRecorder::OnIncomingConnectionAttempt( - ConnectionAttemptType type, Medium medium, ConnectionAttemptResult result, - absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnIncomingConnectionAttempt")) { - return; - } - if (current_strategy_session_ == nullptr) { - LOG(INFO) << "Unable to record incoming connection attempt due to " - "null current_strategy_session_"; - return; - } - - ConnectionAttemptMetadataParams default_params = {}; - if (connection_attempt_metadata_params == nullptr) { - connection_attempt_metadata_params = &default_params; - } - OnIncomingConnectionAttemptLocked(type, medium, result, duration, - connection_token, - connection_attempt_metadata_params); -} - -void AnalyticsRecorder::OnIncomingConnectionAttemptLocked( - location::nearby::proto::connections::ConnectionAttemptType type, - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::ConnectionAttemptResult result, - absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { - auto* connection_attempt = - current_strategy_session_->add_connection_attempt(); - connection_attempt->set_duration_millis(absl::ToInt64Milliseconds(duration)); - connection_attempt->set_type(type); - connection_attempt->set_direction(INCOMING); - connection_attempt->set_medium(medium); - connection_attempt->set_attempt_result(result); - connection_attempt->set_connection_token(connection_token); - - auto* connection_attempt_metadata = - connection_attempt->mutable_connection_attempt_metadata(); - connection_attempt_metadata->set_technology( - connection_attempt_metadata_params->technology); - connection_attempt_metadata->set_band( - connection_attempt_metadata_params->band); - connection_attempt_metadata->set_frequency( - connection_attempt_metadata_params->frequency); - connection_attempt_metadata->set_network_operator( - connection_attempt_metadata_params->network_operator); - connection_attempt_metadata->set_country_code( - connection_attempt_metadata_params->country_code); - connection_attempt_metadata->set_frequency( - connection_attempt_metadata_params->frequency); - connection_attempt_metadata->set_is_tdls_used( - connection_attempt_metadata_params->is_tdls_used); - connection_attempt_metadata->set_wifi_hotspot_status( - connection_attempt_metadata_params->wifi_hotspot_enabled); - connection_attempt_metadata->set_try_counts( - connection_attempt_metadata_params->try_count); - connection_attempt_metadata->set_max_tx_speed( - connection_attempt_metadata_params->max_wifi_tx_speed); - connection_attempt_metadata->set_max_rx_speed( - connection_attempt_metadata_params->max_wifi_rx_speed); - connection_attempt_metadata->set_wifi_channel_width( - connection_attempt_metadata_params->channel_width); - - auto operation_result_proto = - std::make_unique(); - operation_result_proto->set_result_code( - connection_attempt_metadata_params->operation_result_code); - operation_result_proto->set_result_category(ConvertToOperationResultCategory( - connection_attempt_metadata_params->operation_result_code)); - connection_attempt->set_allocated_operation_result( - operation_result_proto.release()); -} - -void AnalyticsRecorder::OnOutgoingConnectionAttempt( - const std::string& remote_endpoint_id, ConnectionAttemptType type, - Medium medium, ConnectionAttemptResult result, absl::Duration duration, - const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnOutgoingConnectionAttempt")) { - return; - } - if (current_strategy_session_ == nullptr) { - LOG(INFO) << "Unable to record outgoing connection attempt due to " - "null current_strategy_session_"; - return; - } - - ConnectionAttemptMetadataParams default_params = {}; - if (connection_attempt_metadata_params == nullptr) { - connection_attempt_metadata_params = &default_params; - } - - // For the case of transfer a big file and the upgrades always failure, then - // there will have repeating upgrade attempt and cause many same attempt value - // be log. So add a method to skip. - if (ConnectionAttemptResultCodeExistedLocked( - medium, OUTGOING, connection_token, type, - connection_attempt_metadata_params->operation_result_code)) { - return; - } - - OnOutgoingConnectionAttemptLocked(remote_endpoint_id, type, medium, result, - duration, connection_token, - connection_attempt_metadata_params); -} - -void AnalyticsRecorder::OnOutgoingConnectionAttemptLocked( - const std::string& remote_endpoint_id, ConnectionAttemptType type, - Medium medium, ConnectionAttemptResult result, absl::Duration duration, - const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { - auto* connection_attempt = - current_strategy_session_->add_connection_attempt(); - connection_attempt->set_duration_millis(absl::ToInt64Milliseconds(duration)); - connection_attempt->set_type(type); - connection_attempt->set_direction(OUTGOING); - connection_attempt->set_medium(medium); - connection_attempt->set_attempt_result(result); - connection_attempt->set_connection_token(connection_token); - - auto* connection_attempt_metadata = - connection_attempt->mutable_connection_attempt_metadata(); - connection_attempt_metadata->set_technology( - connection_attempt_metadata_params->technology); - connection_attempt_metadata->set_band( - connection_attempt_metadata_params->band); - connection_attempt_metadata->set_frequency( - connection_attempt_metadata_params->frequency); - connection_attempt_metadata->set_network_operator( - connection_attempt_metadata_params->network_operator); - connection_attempt_metadata->set_country_code( - connection_attempt_metadata_params->country_code); - connection_attempt_metadata->set_frequency( - connection_attempt_metadata_params->frequency); - connection_attempt_metadata->set_is_tdls_used( - connection_attempt_metadata_params->is_tdls_used); - connection_attempt_metadata->set_wifi_hotspot_status( - connection_attempt_metadata_params->wifi_hotspot_enabled); - connection_attempt_metadata->set_try_counts( - connection_attempt_metadata_params->try_count); - connection_attempt_metadata->set_max_tx_speed( - connection_attempt_metadata_params->max_wifi_tx_speed); - connection_attempt_metadata->set_max_rx_speed( - connection_attempt_metadata_params->max_wifi_rx_speed); - connection_attempt_metadata->set_wifi_channel_width( - connection_attempt_metadata_params->channel_width); - - auto operation_result_proto = - std::make_unique(); - operation_result_proto->set_result_code( - connection_attempt_metadata_params->operation_result_code); - operation_result_proto->set_result_category(ConvertToOperationResultCategory( - connection_attempt_metadata_params->operation_result_code)); - connection_attempt->set_allocated_operation_result( - operation_result_proto.release()); - - if (type == INITIAL && result != RESULT_SUCCESS) { - auto it = outgoing_connection_requests_.find(remote_endpoint_id); - if (it != outgoing_connection_requests_.end()) { - // An outgoing, initial ConnectionAttempt has a corresponding - // ConnectionRequest that, since the ConnectionAttempt has failed, will - // never be delivered to the advertiser. - auto pair = outgoing_connection_requests_.extract(it); - std::unique_ptr& connection_request = - pair.mapped(); - connection_request->set_local_response(NOT_SENT); - connection_request->set_remote_response(NOT_SENT); - UpdateDiscovererConnectionRequestLocked(connection_request.get()); - } - } -} - -void AnalyticsRecorder::OnConnectionEstablished( - const std::string& endpoint_id, Medium medium, - const std::string& connection_token) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnConnectionEstablished")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it != active_connections_.end()) { - const std::unique_ptr& logical_connection = it->second; - logical_connection->PhysicalConnectionEstablished(medium, connection_token); - } else { - active_connections_.insert( - {endpoint_id, - std::make_unique(medium, connection_token)}); - } -} - -void AnalyticsRecorder::OnConnectionClosed(const std::string& endpoint_id, - Medium medium, - DisconnectionReason reason, - SafeDisconnectionResult result) { - MutexLock lock(&mutex_); - LOG(INFO) << __func__ - << ": OnConnectionClosed is called with endpoint_id:" << endpoint_id - << ", medium:" << Medium_Name(medium) - << ", reason:" << DisconnectionReason_Name(reason) - << ", result:" << result; - - if (!CanRecordAnalyticsLocked("OnConnectionClosed")) { - return; - } - - if (current_strategy_session_ == nullptr) { - VLOG(1) << "AnalyticsRecorder CanRecordAnalytics Unexpected call " - << __func__ << " since current_strategy_session_ is required."; - return; - } - - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->PhysicalConnectionClosed(medium, reason, result); - if (reason != UPGRADED) { - // Unless this is an upgraded connection, remove this from our active - // connections. Any future communication with an endpoint will need to be - // re-established with a new ConnectionRequest. - auto pair = active_connections_.extract(it); - std::unique_ptr& logical_connection = pair.mapped(); - - absl::c_copy( - logical_connection->GetEstablisedConnections(), - RepeatedFieldBackInserter( - current_strategy_session_->mutable_established_connection())); - } -} - -void AnalyticsRecorder::OnIncomingPayloadStarted( - const std::string& endpoint_id, std::int64_t payload_id, - connections::PayloadType type, std::int64_t total_size_bytes) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnIncomingPayloadStarted")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->IncomingPayloadStarted( - payload_id, PayloadTypeToProtoPayloadType(type), total_size_bytes); -} - -void AnalyticsRecorder::OnPayloadChunkReceived(const std::string& endpoint_id, - std::int64_t payload_id, - std::int64_t chunk_size_bytes) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnPayloadChunkReceived")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->ChunkReceived(payload_id, chunk_size_bytes); -} - -void AnalyticsRecorder::OnIncomingPayloadDone( - const std::string& endpoint_id, std::int64_t payload_id, - PayloadStatus status, OperationResultCode operation_result_code) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnIncomingPayloadDone")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->IncomingPayloadDone(payload_id, status, - operation_result_code); -} - -void AnalyticsRecorder::OnOutgoingPayloadStarted( - const std::vector& endpoint_ids, std::int64_t payload_id, - connections::PayloadType type, std::int64_t total_size_bytes) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnOutgoingPayloadStarted")) { - return; - } - for (const auto& endpoint_id : endpoint_ids) { - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - continue; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->OutgoingPayloadStarted( - payload_id, PayloadTypeToProtoPayloadType(type), total_size_bytes); - } -} - -void AnalyticsRecorder::OnPayloadChunkSent(const std::string& endpoint_id, - std::int64_t payload_id, - std::int64_t chunk_size_bytes) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnPayloadChunkSent")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->ChunkSent(payload_id, chunk_size_bytes); -} - -void AnalyticsRecorder::OnOutgoingPayloadDone( - const std::string& endpoint_id, std::int64_t payload_id, - PayloadStatus status, OperationResultCode operation_result_code) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnOutgoingPayloadDone")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - - const std::unique_ptr& logical_connection = it->second; - logical_connection->OutgoingPayloadDone(payload_id, status, - operation_result_code); -} - -void AnalyticsRecorder::OnBandwidthUpgradeStarted( - const std::string& endpoint_id, Medium from_medium, Medium to_medium, - ConnectionAttemptDirection direction, const std::string& connection_token) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnBandwidthUpgradeStarted")) { - return; - } - auto bandwidth_upgrade_attempt = - std::make_unique(); - bandwidth_upgrade_attempt->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime())); - bandwidth_upgrade_attempt->set_from_medium(from_medium); - bandwidth_upgrade_attempt->set_to_medium(to_medium); - bandwidth_upgrade_attempt->set_direction(direction); - bandwidth_upgrade_attempt->set_connection_token(connection_token); - bandwidth_upgrade_attempts_.insert( - {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, - OperationResultCode operation_result_code) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnBandwidthUpgradeError")) { - return; - } - // If the same records existed, drop this one. - if (EraseIfBandwidthUpgradeRecordExistedLocked( - endpoint_id, result, error_stage, operation_result_code)) { - return; - } - FinishUpgradeAttemptLocked(endpoint_id, result, error_stage, - operation_result_code); -} - -void AnalyticsRecorder::OnBandwidthUpgradeSuccess( - const std::string& endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnBandwidthUpgradeSuccess")) { - return; - } - FinishUpgradeAttemptLocked(endpoint_id, UPGRADE_RESULT_SUCCESS, - UPGRADE_SUCCESS, - OperationResultCode::DETAIL_SUCCESS); -} - -void AnalyticsRecorder::OnErrorCode(const ErrorCodeParams& params) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnErrorCode")) { - return; - } - auto error_code = std::make_unique(); - error_code->set_medium(params.medium); - error_code->set_event(params.event); - error_code->set_connection_token(params.connection_token); - error_code->set_description(params.description); - - if (params.is_common_error) { - error_code->set_common_error(params.common_error); - } else { - switch (params.event) { - case location::nearby::errorcode::proto::START_ADVERTISING: - error_code->set_start_advertising_error(params.start_advertising_error); - break; - case location::nearby::errorcode::proto::STOP_ADVERTISING: - error_code->set_stop_advertising_error(params.stop_advertising_error); - break; - case location::nearby::errorcode::proto:: - START_LISTENING_INCOMING_CONNECTION: - error_code->set_start_listening_incoming_connection_error( - params.start_listening_incoming_connection_error); - break; - case location::nearby::errorcode::proto:: - STOP_LISTENING_INCOMING_CONNECTION: - error_code->set_stop_listening_incoming_connection_error( - params.stop_listening_incoming_connection_error); - break; - case location::nearby::errorcode::proto::START_DISCOVERING: - error_code->set_start_discovering_error(params.start_discovering_error); - break; - case location::nearby::errorcode::proto::STOP_DISCOVERING: - error_code->set_stop_discovering_error(params.stop_discovering_error); - break; - case location::nearby::errorcode::proto::CONNECT: - error_code->set_connect_error(params.connect_error); - break; - case location::nearby::errorcode::proto::DISCONNECT: - error_code->set_disconnect_error(params.disconnect_error); - break; - case location::nearby::errorcode::proto::UNKNOWN_EVENT: - default: - error_code->set_common_error(params.common_error); - break; - } - } - - ConnectionsLog connections_log; - connections_log.set_event_type(ERROR_CODE); - connections_log.set_version(kVersion); - connections_log.set_allocated_error_code(error_code.release()); - - VLOG(1) << "AnalyticsRecorder LogErrorCode connections_log=" - << connections_log.DebugString(); // NOLINT - - event_logger_->Log(connections_log); -} - -void AnalyticsRecorder::LogStartSession() { - MutexLock lock(&mutex_); - if (start_client_session_was_logged_) { - LOG(WARNING) << "AnalyticsRecorder CanRecordAnalytics Unexpected call " - << kOnStartClientSession - << " after start client session has already been logged."; - return; - } - - session_was_logged_ = false; - if (CanRecordAnalyticsLocked(kOnStartClientSession)) { - client_session_ = std::make_unique(); - started_client_session_time_ = SystemClock::ElapsedRealtime(); - start_client_session_was_logged_ = true; - LogEvent(START_CLIENT_SESSION); - } -} - -void AnalyticsRecorder::LogSession() { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("LogSession")) { - return; - } - FinishStrategySessionLocked(); - client_session_->set_duration_millis(absl::ToInt64Milliseconds( - SystemClock::ElapsedRealtime() - started_client_session_time_)); - LogClientSessionLocked(); - LogEvent(STOP_CLIENT_SESSION); - start_client_session_was_logged_ = false; - session_was_logged_ = true; -} std::unique_ptr AnalyticsRecorder::BuildAdvertisingMetadataParams( bool is_extended_advertisement_supported, int connected_ap_frequency, bool is_nfc_available, - const std::vector& + const std::vector& operation_result_with_mediums) { auto params = std::make_unique(); params->is_extended_advertisement_supported = is_extended_advertisement_supported; params->connected_ap_frequency = connected_ap_frequency; params->is_nfc_available = is_nfc_available; - params->operation_result_with_mediums = - std::move(operation_result_with_mediums); + params->operation_result_with_mediums = operation_result_with_mediums; return params; } @@ -936,15 +50,14 @@ std::unique_ptr AnalyticsRecorder::BuildDiscoveryMetadataParams( bool is_extended_advertisement_supported, int connected_ap_frequency, bool is_nfc_available, - const std::vector& + const std::vector& operation_result_with_mediums) { auto params = std::make_unique(); params->is_extended_advertisement_supported = is_extended_advertisement_supported; params->connected_ap_frequency = connected_ap_frequency; params->is_nfc_available = is_nfc_available; - params->operation_result_with_mediums = - std::move(operation_result_with_mediums); + params->operation_result_with_mediums = operation_result_with_mediums; return params; } @@ -1000,694 +113,4 @@ OperationResultCode AnalyticsRecorder::GetChannelIoErrorResultCodeFromMedium( } } -bool AnalyticsRecorder::CanRecordAnalyticsLocked( - absl::string_view method_name) { - VLOG(1) << "AnalyticsRecorder LogEvent " << method_name << " is calling."; - if (event_logger_ == nullptr) { - return false; - } - - if (session_was_logged_) { - VLOG(1) << "AnalyticsRecorder CanRecordAnalytics Unexpected call " - << method_name << " after session has already been logged."; - return false; - } - - return true; -} - -// TODO: b/391339677 - Investigate why we need to reset the resources. And -// verify in b/238375695 to see if we still meet the issue after removing the -// Reset function. -void AnalyticsRecorder::LogClientSessionLocked() { - ConnectionsLog connections_log; - connections_log.set_event_type(CLIENT_SESSION); - connections_log.set_allocated_client_session(client_session_.release()); - connections_log.set_version(kVersion); - - VLOG(1) << "AnalyticsRecorder LogClientSession connections_log=" - << connections_log.DebugString(); // NOLINT - - event_logger_->Log(connections_log); - client_session_ = nullptr; -} - -void AnalyticsRecorder::LogEvent(EventType event_type) { - ConnectionsLog connections_log; - connections_log.set_event_type(event_type); - connections_log.set_version(kVersion); - - VLOG(1) << "AnalyticsRecorder LogEvent connections_log=" - << connections_log.DebugString(); // NOLINT - - event_logger_->Log(connections_log); -} - -void AnalyticsRecorder::UpdateStrategySessionLocked( - connections::Strategy strategy, SessionRole role) { - // If we're not switching strategies, just update the current StrategySession - // with the new role. - if (strategy == current_strategy_ && current_strategy_session_ != nullptr) { - if (absl::c_linear_search(current_strategy_session_->role(), role)) { - // We've already acted as this role before, so make sure we've finished - // recording the previous round. - switch (role) { - case ADVERTISER: - FinishAdvertisingPhaseLocked(); - break; - case DISCOVERER: - FinishDiscoveryPhaseLocked(); - break; - default: - break; - } - } else { - current_strategy_session_->add_role(role); - } - } else { - // Otherwise, we're starting a new Strategy. - current_strategy_ = strategy; - FinishStrategySessionLocked(); - LogEvent(START_STRATEGY_SESSION); - current_strategy_session_ = - std::make_unique(); - started_strategy_session_time_ = SystemClock::ElapsedRealtime(); - current_strategy_session_->set_strategy( - StrategyToConnectionStrategy(strategy)); - current_strategy_session_->add_role(role); - } -} - -void AnalyticsRecorder::RecordAdvertisingPhaseDurationAndReasonLocked( - bool on_stop) const { - if (current_advertising_phase_ == nullptr) { - LOG(INFO) << "Unable to record advertising phase duration due to " - "null current_advertising_phase_"; - return; - } - if (!current_advertising_phase_->has_duration_millis()) { - current_advertising_phase_->set_duration_millis(absl::ToInt64Milliseconds( - SystemClock::ElapsedRealtime() - started_advertising_phase_time_)); - } - if (!current_advertising_phase_->has_stop_reason()) { - current_advertising_phase_->set_stop_reason( - on_stop ? StopAdvertisingReason::CLIENT_STOP_ADVERTISING - : StopAdvertisingReason::FINISH_SESSION_STOP_ADVERTISING); - } -} - -void AnalyticsRecorder::FinishAdvertisingPhaseLocked() { - if (current_advertising_phase_ != nullptr) { - for (const auto& item : incoming_connection_requests_) { - // ConnectionRequests still pending have been ignored by the local or - // remote (or both) endpoints. - const std::unique_ptr& - connection_request = item.second; - MarkConnectionRequestIgnoredLocked(connection_request.get()); - UpdateAdvertiserConnectionRequestLocked(connection_request.get()); - } - RecordAdvertisingPhaseDurationAndReasonLocked(/* on_stop= */ false); - if (current_strategy_session_ != nullptr) { - *current_strategy_session_->add_advertising_phase() = - *std::move(current_advertising_phase_); - } else { - LOG(INFO) << "Unable to record advertising phase due to null " - "current_strategy_session_"; - } - } - incoming_connection_requests_.clear(); -} - -void AnalyticsRecorder::RecordDiscoveryPhaseDurationAndReasonLocked( - bool on_stop) const { - if (current_discovery_phase_ == nullptr) { - LOG(INFO) << "Unable to record discovery phase duration due to " - "null current_discovery_phase_"; - return; - } - if (!current_discovery_phase_->has_duration_millis()) { - current_discovery_phase_->set_duration_millis(absl::ToInt64Milliseconds( - SystemClock::ElapsedRealtime() - started_discovery_phase_time_)); - } - // If the stop reason haven't been set yet, then set it. - if (!current_discovery_phase_->has_stop_reason()) { - current_discovery_phase_->set_stop_reason( - on_stop ? StopDiscoveringReason::CLIENT_STOP_DISCOVERING - : StopDiscoveringReason::FINISH_SESSION_STOP_DISCOVERING); - } -} - -void AnalyticsRecorder::FinishDiscoveryPhaseLocked() { - if (current_discovery_phase_ != nullptr) { - for (const auto& item : outgoing_connection_requests_) { - // ConnectionRequests still pending have been ignored by the local or - // remote (or both) endpoints. - const std::unique_ptr& - connection_request = item.second; - MarkConnectionRequestIgnoredLocked(connection_request.get()); - UpdateDiscovererConnectionRequestLocked(connection_request.get()); - } - RecordDiscoveryPhaseDurationAndReasonLocked(/* on_stop=*/false); - if (current_strategy_session_ != nullptr) { - *current_strategy_session_->add_discovery_phase() = - *std::move(current_discovery_phase_); - } else { - LOG(INFO) << "Unable to record discovery phase due to null " - "current_strategy_session_"; - } - } - outgoing_connection_requests_.clear(); -} - -bool AnalyticsRecorder::UpdateAdvertiserConnectionRequestLocked( - ConnectionsLog::ConnectionRequest* request) { - if (current_advertising_phase_ == nullptr) { - LOG(INFO) << "Unable to record advertiser connection request due to null " - "current_advertising_phase_"; - return false; - } - if (BothEndpointsRespondedLocked(request)) { - request->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - - request->duration_millis()); - *current_advertising_phase_->add_received_connection_request() = *request; - return true; - } - return false; -} - -bool AnalyticsRecorder::UpdateDiscovererConnectionRequestLocked( - ConnectionsLog::ConnectionRequest* request) { - if (current_discovery_phase_ == nullptr) { - LOG(INFO) << "Unable to record discoverer connection request due " - "to null current_discovery_phase_."; - return false; - } - if (BothEndpointsRespondedLocked(request) || - request->local_response() == NOT_SENT) { - request->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - - request->duration_millis()); - *current_discovery_phase_->add_sent_connection_request() = *request; - return true; - } - return false; -} - -bool AnalyticsRecorder::BothEndpointsRespondedLocked( - ConnectionsLog::ConnectionRequest* request) { - return request->has_local_response() && request->has_remote_response(); -} - -void AnalyticsRecorder::LocalEndpointRespondedLocked( - const std::string& remote_endpoint_id, ConnectionRequestResponse response) { - auto out = outgoing_connection_requests_.find(remote_endpoint_id); - if (out != outgoing_connection_requests_.end()) { - ConnectionsLog::ConnectionRequest* connection_request = out->second.get(); - connection_request->set_local_response(response); - if (UpdateDiscovererConnectionRequestLocked(connection_request)) { - outgoing_connection_requests_.erase(out); - } - } - auto in = incoming_connection_requests_.find(remote_endpoint_id); - if (in != incoming_connection_requests_.end()) { - ConnectionsLog::ConnectionRequest* connection_request = in->second.get(); - connection_request->set_local_response(response); - if (UpdateAdvertiserConnectionRequestLocked(connection_request)) { - incoming_connection_requests_.erase(in); - } - } -} - -void AnalyticsRecorder::RemoteEndpointRespondedLocked( - const std::string& remote_endpoint_id, ConnectionRequestResponse response) { - auto out = outgoing_connection_requests_.find(remote_endpoint_id); - if (out != outgoing_connection_requests_.end()) { - ConnectionsLog::ConnectionRequest* connection_request = out->second.get(); - connection_request->set_remote_response(response); - if (UpdateDiscovererConnectionRequestLocked(connection_request)) { - outgoing_connection_requests_.erase(out); - } - } - auto in = incoming_connection_requests_.find(remote_endpoint_id); - if (in != incoming_connection_requests_.end()) { - ConnectionsLog::ConnectionRequest* connection_request = in->second.get(); - connection_request->set_remote_response(response); - if (UpdateAdvertiserConnectionRequestLocked(connection_request)) { - incoming_connection_requests_.erase(in); - } - } -} - -void AnalyticsRecorder::MarkConnectionRequestIgnoredLocked( - ConnectionsLog::ConnectionRequest* request) { - if (!request->has_local_response()) { - request->set_local_response(IGNORED); - } - if (!request->has_remote_response()) { - request->set_remote_response(IGNORED); - } -} - -bool AnalyticsRecorder::ConnectionAttemptResultCodeExistedLocked( - Medium medium, ConnectionAttemptDirection direction, - const std::string& connection_token, ConnectionAttemptType type, - OperationResultCode operation_result_code) { - if (current_strategy_session_ == nullptr || - current_strategy_session_->connection_attempt_size() == 0) { - return false; - } - for (auto& connection_attempt : - current_strategy_session_->connection_attempt()) { - if (connection_attempt.medium() == medium && - connection_attempt.direction() == direction && - connection_attempt.connection_token() == connection_token && - connection_attempt.type() == type && - connection_attempt.operation_result().result_code() == - operation_result_code) { - return true; - } - } - - return false; -} - -// If bandwidth upgrade always failed on the same fromMedium, toMedium, result, -// stage and result code, we'll drop the duplicate logs for preventing the waste -// of log storage space -bool AnalyticsRecorder::EraseIfBandwidthUpgradeRecordExistedLocked( - const std::string& endpoint_id, BandwidthUpgradeResult result, - BandwidthUpgradeErrorStage error_stage, - OperationResultCode operation_result_code) { - if (current_strategy_session_ == nullptr) { - return false; - } - auto it = bandwidth_upgrade_attempts_.find(endpoint_id); - if (it != bandwidth_upgrade_attempts_.end()) { - ConnectionsLog::BandwidthUpgradeAttempt* attempt = it->second.get(); - for (auto& existing_attempt : - current_strategy_session_->upgrade_attempt()) { - if (attempt->from_medium() == existing_attempt.from_medium() && - attempt->to_medium() == existing_attempt.to_medium() && - result == existing_attempt.upgrade_result() && - error_stage == existing_attempt.error_stage() && - operation_result_code == - existing_attempt.operation_result().result_code()) { - bandwidth_upgrade_attempts_.erase(it); - return true; - } - } - } - return false; -} - -void AnalyticsRecorder::FinishUpgradeAttemptLocked( - const std::string& endpoint_id, BandwidthUpgradeResult result, - BandwidthUpgradeErrorStage error_stage, - OperationResultCode operation_result_code, bool erase_item) { - if (current_strategy_session_ == nullptr) { - LOG(INFO) << "Unable to record upgrade attempt due to null " - "current_strategy_session_"; - return; - } - // Add the BandwidthUpgradeAttempt in the current StrategySession. - auto it = bandwidth_upgrade_attempts_.find(endpoint_id); - if (it != bandwidth_upgrade_attempts_.end()) { - ConnectionsLog::BandwidthUpgradeAttempt* attempt = it->second.get(); - attempt->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - - attempt->duration_millis()); - attempt->set_error_stage(error_stage); - attempt->set_upgrade_result(result); - - auto operation_result_proto = - std::make_unique(); - operation_result_proto->set_result_code(operation_result_code); - operation_result_proto->set_result_category( - ConvertToOperationResultCategory(operation_result_code)); - attempt->set_allocated_operation_result(operation_result_proto.release()); - *current_strategy_session_->add_upgrade_attempt() = *attempt; - if (erase_item) { - bandwidth_upgrade_attempts_.erase(it); - } - } -} - -void AnalyticsRecorder::FinishStrategySessionLocked() { - if (current_strategy_session_ != nullptr) { - FinishAdvertisingPhaseLocked(); - FinishDiscoveryPhaseLocked(); - - // Finish any unfinished LogicalConnections. - for (const auto& item : active_connections_) { - const std::unique_ptr& logical_connection = - item.second; - logical_connection->CloseAllPhysicalConnections(); - absl::c_copy( - logical_connection->GetEstablisedConnections(), - RepeatedFieldBackInserter( - current_strategy_session_->mutable_established_connection())); - } - active_connections_.clear(); - - // Finish any pending upgrade attempts. - for (const auto& item : bandwidth_upgrade_attempts_) { - FinishUpgradeAttemptLocked( - item.first, UNFINISHED_ERROR, UPGRADE_UNFINISHED, - OperationResultCode::DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS, - /*erase_item=*/false); - } - bandwidth_upgrade_attempts_.clear(); - - // Add the StrategySession in ClientSession - if (current_strategy_session_ != nullptr) { - current_strategy_session_->set_duration_millis(absl::ToInt64Milliseconds( - SystemClock::ElapsedRealtime() - started_strategy_session_time_)); - *client_session_->add_strategy_session() = - *std::move(current_strategy_session_); - } - - current_strategy_session_ = nullptr; - current_strategy_ = connections::Strategy::kNone; - LogEvent(STOP_STRATEGY_SESSION); - } -} - -ConnectionsStrategy AnalyticsRecorder::StrategyToConnectionStrategy( - connections::Strategy strategy) { - if (strategy == connections::Strategy::kP2pCluster) { - return P2P_CLUSTER; - } - if (strategy == connections::Strategy::kP2pStar) { - return P2P_STAR; - } - if (strategy == connections::Strategy::kP2pPointToPoint) { - return P2P_POINT_TO_POINT; - } - return UNKNOWN_STRATEGY; -} - -PayloadType AnalyticsRecorder::PayloadTypeToProtoPayloadType( - connections::PayloadType type) { - switch (type) { - case connections::PayloadType::kBytes: - return BYTES; - case connections::PayloadType::kFile: - return FILE; - case connections::PayloadType::kStream: - return STREAM; - default: - return UNKNOWN_PAYLOAD_TYPE; - } -} - -void AnalyticsRecorder::PendingPayload::AddChunk( - std::int64_t chunk_size_bytes) { - num_bytes_transferred_ += chunk_size_bytes; - num_chunks_++; -} - -ConnectionsLog::Payload AnalyticsRecorder::PendingPayload::GetProtoPayload( - PayloadStatus status) { - ConnectionsLog::Payload payload; - payload.set_duration_millis( - absl::ToInt64Milliseconds(SystemClock::ElapsedRealtime() - start_time_)); - payload.set_type(type_); - payload.set_total_size_bytes(total_size_bytes_); - payload.set_num_bytes_transferred(num_bytes_transferred_); - payload.set_num_chunks(num_chunks_); - payload.set_status(status); - - auto operation_result_proto = - std::make_unique(); - operation_result_proto->set_result_code(operation_result_code_); - operation_result_proto->set_result_category( - ConvertToOperationResultCategory(operation_result_code_)); - payload.set_allocated_operation_result(operation_result_proto.release()); - - return payload; -} - -void AnalyticsRecorder::LogicalConnection::PhysicalConnectionEstablished( - Medium medium, const std::string& connection_token) { - if (current_medium_ != UNKNOWN_MEDIUM) { - LOG(WARNING) << "Unexpected call to PhysicalConnectionEstablished while " - "AnalyticsRecorder still has an active current medium."; - } - - auto established_connection = - std::make_unique(); - established_connection->set_medium(medium); - established_connection->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime())); - established_connection->set_connection_token(connection_token); - - auto operation_result_proto = - std::make_unique(); - operation_result_proto->set_result_code(OperationResultCode::DETAIL_SUCCESS); - operation_result_proto->set_result_category( - OperationResultCategory::CATEGORY_SUCCESS); - established_connection->set_allocated_operation_result( - operation_result_proto.release()); - physical_connections_.insert({medium, std::move(established_connection)}); - current_medium_ = medium; -} - -void AnalyticsRecorder::LogicalConnection::PhysicalConnectionClosed( - Medium medium, DisconnectionReason reason, SafeDisconnectionResult result) { - if (current_medium_ == UNKNOWN_MEDIUM) { - LOG(WARNING) << "Unexpected call to PhysicalConnectionClosed() for medium " - << Medium_Name(medium) - << " while AnalyticsRecorder has no active current medium"; - } else if (current_medium_ != medium) { - LOG(WARNING) << "Unexpected call to PhysicalConnectionClosed() for medium " - << Medium_Name(medium) - << "while AnalyticsRecorder has active medium " - << Medium_Name(current_medium_); - } - - auto it = physical_connections_.find(medium); - if (it == physical_connections_.end()) { - LOG(WARNING) - << "Unexpected call to physicalConnectionClosed() for medium " - << Medium_Name(medium) - << " with no corresponding EstablishedConnection that was previously" - " opened."; - return; - } - ConnectionsLog::EstablishedConnection* established_connection = - it->second.get(); - if (established_connection->has_disconnection_reason()) { - LOG(WARNING) << "Unexpected call to physicalConnectionClosed() for medium " - << Medium_Name(medium) - << " which already has disconnection reason " - << DisconnectionReason_Name( - established_connection->disconnection_reason()); - return; - } - FinishPhysicalConnection(established_connection, reason, result); - - if (medium == current_medium_) { - // If the EstablishedConnection we just closed was the one that we have - // marked as current, unset currentMedium. - current_medium_ = UNKNOWN_MEDIUM; - } -} - -void AnalyticsRecorder::LogicalConnection::CloseAllPhysicalConnections() { - for (const auto& physical_connection : physical_connections_) { - ConnectionsLog::EstablishedConnection* established_connection = - physical_connection.second.get(); - if (!established_connection->has_disconnection_reason()) { - FinishPhysicalConnection( - established_connection, UNFINISHED, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); - } - } - current_medium_ = UNKNOWN_MEDIUM; -} - -std::vector -AnalyticsRecorder::LogicalConnection::GetEstablisedConnections() { - std::vector established_connections; - if (current_medium_ != UNKNOWN_MEDIUM) { - LOG(WARNING) - << "AnalyticsRecorder expected no more active physical connections " - "before logging this endpoint connection."; - return established_connections; - } - std::transform(physical_connections_.begin(), physical_connections_.end(), - std::back_inserter(established_connections), - [](auto& kv) { return *kv.second; }); - physical_connections_.clear(); - - for (auto& established_connection : established_connections) { - if (absl::Milliseconds(established_connection.duration_millis()) >= - kConnectionTokenMaxLife) { - LOG(INFO) << "connection token exceed TTL, drop token."; - established_connection.set_connection_token(""); - } - } - - return established_connections; -} - -void AnalyticsRecorder::LogicalConnection::IncomingPayloadStarted( - std::int64_t payload_id, PayloadType type, std::int64_t total_size_bytes) { - incoming_payloads_.insert( - {payload_id, std::make_unique(type, total_size_bytes)}); -} - -void AnalyticsRecorder::LogicalConnection::ChunkReceived( - std::int64_t payload_id, std::int64_t size_bytes) { - auto it = incoming_payloads_.find(payload_id); - if (it == incoming_payloads_.end()) { - return; - } - PendingPayload* pending_payload = it->second.get(); - pending_payload->AddChunk(size_bytes); -} - -void AnalyticsRecorder::LogicalConnection::IncomingPayloadDone( - std::int64_t payload_id, PayloadStatus status, - OperationResultCode operation_result_code) { - if (current_medium_ == UNKNOWN_MEDIUM) { - LOG(WARNING) << "Unexpected call to incomingPayloadDone() while " - "AnalyticsRecorder has no active current medium."; - return; - } - auto it = physical_connections_.find(current_medium_); - if (it != physical_connections_.end()) { - const std::unique_ptr& - established_connection = it->second; - auto it = incoming_payloads_.find(payload_id); - if (it != incoming_payloads_.end()) { - it->second->SetOperationResultCode(operation_result_code); - *established_connection->add_received_payload() = - it->second->GetProtoPayload(status); - incoming_payloads_.erase(it); - } - } -} - -void AnalyticsRecorder::LogicalConnection::OutgoingPayloadStarted( - std::int64_t payload_id, PayloadType type, std::int64_t total_size_bytes) { - outgoing_payloads_.insert( - {payload_id, std::make_unique(type, total_size_bytes)}); -} - -void AnalyticsRecorder::LogicalConnection::ChunkSent(std::int64_t payload_id, - std::int64_t size_bytes) { - auto it = outgoing_payloads_.find(payload_id); - if (it == outgoing_payloads_.end()) { - return; - } - PendingPayload* payload = it->second.get(); - payload->AddChunk(size_bytes); -} - -void AnalyticsRecorder::LogicalConnection::OutgoingPayloadDone( - std::int64_t payload_id, PayloadStatus status, - OperationResultCode operation_result_code) { - if (current_medium_ == UNKNOWN_MEDIUM) { - LOG(WARNING) << "Unexpected call to outgoingPayloadDone() while " - "AnalyticsRecorder has no active current medium."; - return; - } - auto it = physical_connections_.find(current_medium_); - if (it != physical_connections_.end()) { - const std::unique_ptr& - established_connection = it->second; - auto it = outgoing_payloads_.find(payload_id); - if (it != outgoing_payloads_.end()) { - it->second->SetOperationResultCode(operation_result_code); - *established_connection->add_sent_payload() = - it->second->GetProtoPayload(status); - outgoing_payloads_.erase(it); - } - } -} - -void AnalyticsRecorder::LogicalConnection::FinishPhysicalConnection( - ConnectionsLog::EstablishedConnection* established_connection, - DisconnectionReason reason, SafeDisconnectionResult result) { - established_connection->set_disconnection_reason(reason); - established_connection->set_safe_disconnection_result(result); - established_connection->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - - established_connection->duration_millis()); - - // Add any not-yet-finished payloads to this EstablishedConnection. - std::vector in_payloads = - ResolvePendingPayloads(incoming_payloads_, reason); - absl::c_move(in_payloads, - RepeatedFieldBackInserter( - established_connection->mutable_received_payload())); - std::vector out_payloads = - ResolvePendingPayloads(outgoing_payloads_, reason); - absl::c_move(out_payloads, - RepeatedFieldBackInserter( - established_connection->mutable_sent_payload())); -} - -std::vector -AnalyticsRecorder::LogicalConnection::ResolvePendingPayloads( - absl::btree_map>& - pending_payloads, - DisconnectionReason reason) { - std::vector completed_payloads; - absl::btree_map> - upgraded_payloads; - PayloadStatus status = - reason == UPGRADED ? MOVED_TO_NEW_MEDIUM : CONNECTION_CLOSED; - - OperationResultCode operation_result_code = - GetPendingPayloadResultCodeFromReason(reason); - for (const auto& item : pending_payloads) { - const std::unique_ptr& pending_payload = item.second; - pending_payload->SetOperationResultCode(operation_result_code); - ConnectionsLog::Payload proto_payload = - pending_payload->GetProtoPayload(status); - completed_payloads.push_back(proto_payload); - if (reason == UPGRADED) { - upgraded_payloads.insert( - {item.first, - std::make_unique(pending_payload->type(), - pending_payload->total_size_bytes(), - operation_result_code)}); - } - } - pending_payloads.clear(); - - if (reason == UPGRADED) { - // Re-populate the map with a new PendingPayload for each pending payload, - // since we expect them to be completed on the next EstablishedConnection. - pending_payloads = std::move(upgraded_payloads); - } - // Return the list of completed payloads to be added to the current - // EstablishedConnection. - return completed_payloads; -} - -OperationResultCode -AnalyticsRecorder::LogicalConnection::GetPendingPayloadResultCodeFromReason( - DisconnectionReason reason) { - switch (reason) { - case UPGRADED: - return OperationResultCode::MISCELLEANEOUS_MOVE_TO_NEW_MEDIUM; - case DisconnectionReason::LOCAL_DISCONNECTION: - return OperationResultCode::CLIENT_CANCELLATION_LOCAL_DISCONNECT; - case DisconnectionReason::REMOTE_DISCONNECTION: - return OperationResultCode::CLIENT_CANCELLATION_REMOTE_DISCONNECT; - default: - return OperationResultCode::NEARBY_GENERIC_CONNECTION_CLOSED; - } -} - -OperationResultCategory AnalyticsRecorder::GetOperationResultCategory( - location::nearby::proto::connections::OperationResultCode result_code) { - return ConvertToOperationResultCategory(result_code); -} - -} // namespace analytics -} // namespace nearby +} // namespace nearby::analytics diff --git a/connections/implementation/analytics/analytics_recorder.h b/connections/implementation/analytics/analytics_recorder.h index b24232b3..601d12bc 100644 --- a/connections/implementation/analytics/analytics_recorder.h +++ b/connections/implementation/analytics/analytics_recorder.h @@ -18,118 +18,98 @@ #include #include #include -#include #include -#include "absl/base/thread_annotations.h" -#include "absl/container/btree_map.h" -#include "absl/strings/string_view.h" #include "absl/time/time.h" #include "connections/implementation/analytics/advertising_metadata_params.h" #include "connections/implementation/analytics/connection_attempt_metadata_params.h" #include "connections/implementation/analytics/discovery_metadata_params.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" #include "connections/payload_type.h" #include "connections/strategy.h" -#include "internal/analytics/event_logger.h" #include "internal/platform/error_code_params.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/mutex.h" -#include "internal/proto/analytics/connections_log.pb.h" #include "proto/connections_enums.pb.h" -namespace nearby { -namespace analytics { +namespace nearby::analytics { + +enum class SafeDisconnectionResult { + kUnknown = 0, + kSafeDisconnection = 1, + kUnsafeDisconnection = 2, +}; class AnalyticsRecorder { public: - explicit AnalyticsRecorder(::nearby::analytics::EventLogger* event_logger); - virtual ~AnalyticsRecorder(); + AnalyticsRecorder() = default; + virtual ~AnalyticsRecorder() = default; // Advertising phase - void OnStartAdvertising( + virtual void OnStartAdvertising( connections::Strategy strategy, const std::vector& mediums, - AdvertisingMetadataParams* advertising_metadata_params) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnStopAdvertising() ABSL_LOCKS_EXCLUDED(mutex_); + AdvertisingMetadataParams* advertising_metadata_params) = 0; + virtual void OnStopAdvertising() = 0; - // In case the client calls the {@link BasePcp#updateAdvertisingOptions()} - // multiple times, adds one index value to group the mediums results within - // the same UpdateAdvertisingOptions call, this API is to return the largest - // index value in current_advertising_phase. - int GetNextAdvertisingUpdateIndex() ABSL_LOCKS_EXCLUDED(mutex_); + virtual int GetNextAdvertisingUpdateIndex() = 0; // Connection listening - void OnStartedIncomingConnectionListening(connections::Strategy strategy) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnStoppedIncomingConnectionListening() ABSL_LOCKS_EXCLUDED(mutex_); + virtual void OnStartedIncomingConnectionListening( + connections::Strategy strategy) = 0; + virtual void OnStoppedIncomingConnectionListening() = 0; // Discovery phase - void OnStartDiscovery( + virtual void OnStartDiscovery( connections::Strategy strategy, const std::vector& mediums, - DiscoveryMetadataParams* discovery_metadata_params) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnStopDiscovery() ABSL_LOCKS_EXCLUDED(mutex_); + DiscoveryMetadataParams* discovery_metadata_params) = 0; + virtual void OnStopDiscovery() = 0; - // In case the client calls the {@link BasePcp#updateDiscoveryOptions()} - // multiple times, adds one index value to group the medium results within the - // same UpdateDiscoveryOptions call, this - // API is to return the latest index value in current_discovery_phase. - int GetNextDiscoveryUpdateIndex() ABSL_LOCKS_EXCLUDED(mutex_); - void OnEndpointFound(location::nearby::proto::connections::Medium medium) - ABSL_LOCKS_EXCLUDED(mutex_); + virtual int GetNextDiscoveryUpdateIndex() = 0; + virtual void OnEndpointFound( + location::nearby::proto::connections::Medium medium) = 0; // Connection request - void OnRequestConnection(const connections::Strategy& strategy, - const std::string& endpoint_id) - ABSL_LOCKS_EXCLUDED(mutex_); + virtual void OnRequestConnection(const connections::Strategy& strategy, + const std::string& endpoint_id) = 0; - void OnConnectionRequestReceived(const std::string& remote_endpoint_id) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnConnectionRequestSent(const std::string& remote_endpoint_id) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnRemoteEndpointAccepted(const std::string& remote_endpoint_id) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnLocalEndpointAccepted(const std::string& remote_endpoint_id) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnRemoteEndpointRejected(const std::string& remote_endpoint_id) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnLocalEndpointRejected(const std::string& remote_endpoint_id) - ABSL_LOCKS_EXCLUDED(mutex_); + virtual void OnConnectionRequestReceived( + const std::string& remote_endpoint_id) = 0; + virtual void OnConnectionRequestSent( + const std::string& remote_endpoint_id) = 0; + virtual void OnRemoteEndpointAccepted( + const std::string& remote_endpoint_id) = 0; + virtual void OnLocalEndpointAccepted( + const std::string& remote_endpoint_id) = 0; + virtual void OnRemoteEndpointRejected( + const std::string& remote_endpoint_id) = 0; + virtual void OnLocalEndpointRejected( + const std::string& remote_endpoint_id) = 0; // Connection attempt - // Records an attempt with meta data at establishing an incoming physical - // connection. - void OnIncomingConnectionAttempt( + virtual void OnIncomingConnectionAttempt( location::nearby::proto::connections::ConnectionAttemptType type, location::nearby::proto::connections::Medium medium, location::nearby::proto::connections::ConnectionAttemptResult result, absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) - ABSL_LOCKS_EXCLUDED(mutex_); - // Records an attempt with meta data at establishing an outgoing physical - // connection. - void OnOutgoingConnectionAttempt( + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) = 0; + virtual void OnOutgoingConnectionAttempt( const std::string& remote_endpoint_id, location::nearby::proto::connections::ConnectionAttemptType type, location::nearby::proto::connections::Medium medium, location::nearby::proto::connections::ConnectionAttemptResult result, absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) - ABSL_LOCKS_EXCLUDED(mutex_); + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) = 0; + static std::unique_ptr BuildAdvertisingMetadataParams( bool is_extended_advertisement_supported = false, int connected_ap_frequency = 0, bool is_nfc_available = false, - const std::vector& + const std::vector& operation_result_with_mediums = {}); static std::unique_ptr BuildDiscoveryMetadataParams( bool is_extended_advertisement_supported = false, int connected_ap_frequency = 0, bool is_nfc_available = false, - const std::vector& + const std::vector& operation_result_with_mediums = {}); static std::unique_ptr @@ -147,363 +127,78 @@ class AnalyticsRecorder { GetChannelIoErrorResultCodeFromMedium( location::nearby::proto::connections::Medium medium); - // Connection establishedSafeDisconnectionResult - void OnConnectionEstablished( + // Connection established + virtual void OnConnectionEstablished( const std::string& endpoint_id, location::nearby::proto::connections::Medium medium, - const std::string& connection_token) ABSL_LOCKS_EXCLUDED(mutex_); - void OnConnectionClosed( + const std::string& connection_token) = 0; + virtual void OnConnectionClosed( const std::string& endpoint_id, location::nearby::proto::connections::Medium medium, location::nearby::proto::connections::DisconnectionReason reason, - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection::SafeDisconnectionResult result) - ABSL_LOCKS_EXCLUDED(mutex_); + SafeDisconnectionResult result) = 0; // Payload - void OnIncomingPayloadStarted(const std::string& endpoint_id, - std::int64_t payload_id, - connections::PayloadType type, - std::int64_t total_size_bytes) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnPayloadChunkReceived(const std::string& endpoint_id, - std::int64_t payload_id, - std::int64_t chunk_size_bytes) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnIncomingPayloadDone( + virtual void OnIncomingPayloadStarted(const std::string& endpoint_id, + std::int64_t payload_id, + connections::PayloadType type, + std::int64_t total_size_bytes) = 0; + virtual void OnPayloadChunkReceived(const std::string& endpoint_id, + std::int64_t payload_id, + std::int64_t chunk_size_bytes) = 0; + virtual void OnIncomingPayloadDone( const std::string& endpoint_id, std::int64_t payload_id, location::nearby::proto::connections::PayloadStatus status, location::nearby::proto::connections::OperationResultCode - operation_result_code) ABSL_LOCKS_EXCLUDED(mutex_); - void OnOutgoingPayloadStarted(const std::vector& endpoint_ids, - std::int64_t payload_id, - connections::PayloadType type, - std::int64_t total_size_bytes) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnPayloadChunkSent(const std::string& endpoint_id, - std::int64_t payload_id, - std::int64_t chunk_size_bytes) - ABSL_LOCKS_EXCLUDED(mutex_); - void OnOutgoingPayloadDone( + operation_result_code) = 0; + virtual void OnOutgoingPayloadStarted( + const std::vector& endpoint_ids, std::int64_t payload_id, + connections::PayloadType type, std::int64_t total_size_bytes) = 0; + virtual void OnPayloadChunkSent(const std::string& endpoint_id, + std::int64_t payload_id, + std::int64_t chunk_size_bytes) = 0; + virtual void OnOutgoingPayloadDone( const std::string& endpoint_id, std::int64_t payload_id, location::nearby::proto::connections::PayloadStatus status, location::nearby::proto::connections::OperationResultCode - operation_result_code) ABSL_LOCKS_EXCLUDED(mutex_); + operation_result_code) = 0; // BandwidthUpgrade - void OnBandwidthUpgradeStarted( + virtual void OnBandwidthUpgradeStarted( const std::string& endpoint_id, location::nearby::proto::connections::Medium from_medium, location::nearby::proto::connections::Medium to_medium, 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& connection_token) = 0; + virtual void UpdateBwUpgradeNetworkInfo(const std::string& endpoint_id, + int num_interfaces, + int num_ipv6_only_interfaces) = 0; + virtual void OnBandwidthUpgradeError( const std::string& endpoint_id, location::nearby::proto::connections::BandwidthUpgradeResult result, location::nearby::proto::connections::BandwidthUpgradeErrorStage error_stage, location::nearby::proto::connections::OperationResultCode - operation_result_code) ABSL_LOCKS_EXCLUDED(mutex_); - void OnBandwidthUpgradeSuccess(const std::string& endpoint_id) - ABSL_LOCKS_EXCLUDED(mutex_); + operation_result_code) = 0; + virtual void OnBandwidthUpgradeSuccess(const std::string& endpoint_id) = 0; // Error Code - void OnErrorCode(const ErrorCodeParams& params); + virtual void OnErrorCode(const ErrorCodeParams& params) = 0; - // Log the start client session event with start client session logging - // resources setup (e.g. client_session_, started_client_session_time_) - void LogStartSession() ABSL_LOCKS_EXCLUDED(mutex_); + virtual void LogStartSession() = 0; + virtual void LogSession() = 0; - // Invokes event_logger_.Log() at the end of life of client. Log action is - // called in a separate thread to allow synchronous potentially lengthy - // execution. - void LogSession() ABSL_LOCKS_EXCLUDED(mutex_); + virtual bool IsSessionLogged() = 0; - bool IsSessionLogged(); - - location::nearby::proto::connections::OperationResultCategory + virtual location::nearby::proto::connections::OperationResultCategory GetOperationResultCategory( - location::nearby::proto::connections::OperationResultCode result_code); - - // Waits until all logs are sent to the backend. - // For testing only. - void Sync(); - - private: - // Tracks the chunks and duration of a Payload on a particular medium. - class PendingPayload { - public: - PendingPayload(location::nearby::proto::connections::PayloadType type, - std::int64_t total_size_bytes) - : PendingPayload(type, total_size_bytes, - location::nearby::proto::connections:: - OperationResultCode::DETAIL_UNKNOWN) {} - PendingPayload(location::nearby::proto::connections::PayloadType type, - std::int64_t total_size_bytes, - location::nearby::proto::connections::OperationResultCode - operation_result_code) - : start_time_(SystemClock::ElapsedRealtime()), - type_(type), - total_size_bytes_(total_size_bytes), - num_bytes_transferred_(0), - num_chunks_(0), - operation_result_code_(operation_result_code) {} - ~PendingPayload() = default; - - void AddChunk(std::int64_t chunk_size_bytes); - - location::nearby::analytics::proto::ConnectionsLog::Payload GetProtoPayload( - location::nearby::proto::connections::PayloadStatus status); - - location::nearby::proto::connections::PayloadType type() const { - return type_; - } - - std::int64_t total_size_bytes() const { return total_size_bytes_; } - - void SetOperationResultCode( - location::nearby::proto::connections::OperationResultCode - operation_result_code) { - operation_result_code_ = operation_result_code; - } - - private: - absl::Time start_time_; - location::nearby::proto::connections::PayloadType type_; - std::int64_t total_size_bytes_; - std::int64_t num_bytes_transferred_; - int num_chunks_; - location::nearby::proto::connections::OperationResultCode - operation_result_code_ = location::nearby::proto::connections:: - OperationResultCode::DETAIL_UNKNOWN; - }; - - class LogicalConnection { - public: - LogicalConnection( - location::nearby::proto::connections::Medium initial_medium, - const std::string& connection_token) { - PhysicalConnectionEstablished(initial_medium, connection_token); - } - LogicalConnection(const LogicalConnection&) = delete; - LogicalConnection(LogicalConnection&& other) - : current_medium_(std::move(other.current_medium_)), - physical_connections_(std::move(other.physical_connections_)), - incoming_payloads_(std::move(other.incoming_payloads_)), - outgoing_payloads_(std::move(other.outgoing_payloads_)) {} - LogicalConnection& operator=(const LogicalConnection&) = delete; - LogicalConnection&& operator=(LogicalConnection&&) = delete; - ~LogicalConnection() = default; - - void PhysicalConnectionEstablished( - location::nearby::proto::connections::Medium medium, - const std::string& connection_token); - void PhysicalConnectionClosed( - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::DisconnectionReason reason, - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection::SafeDisconnectionResult result); - void CloseAllPhysicalConnections(); - - void IncomingPayloadStarted( - std::int64_t payload_id, - location::nearby::proto::connections::PayloadType type, - std::int64_t total_size_bytes); - void ChunkReceived(std::int64_t payload_id, std::int64_t size_bytes); - void IncomingPayloadDone( - std::int64_t payload_id, - location::nearby::proto::connections::PayloadStatus status, - location::nearby::proto::connections::OperationResultCode - operation_result_code); - void OutgoingPayloadStarted( - std::int64_t payload_id, - location::nearby::proto::connections::PayloadType type, - std::int64_t total_size_bytes); - void ChunkSent(std::int64_t payload_id, std::int64_t size_bytes); - void OutgoingPayloadDone( - std::int64_t payload_id, - location::nearby::proto::connections::PayloadStatus status, - location::nearby::proto::connections::OperationResultCode - operation_result_code); - - std::vector - GetEstablisedConnections(); - - private: - void FinishPhysicalConnection( - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection* established_connection, - location::nearby::proto::connections::DisconnectionReason reason, - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection::SafeDisconnectionResult result); - std::vector - ResolvePendingPayloads( - absl::btree_map>& - pending_payloads, - location::nearby::proto::connections::DisconnectionReason reason); - location::nearby::proto::connections::OperationResultCode - GetPendingPayloadResultCodeFromReason( - location::nearby::proto::connections::DisconnectionReason reason); - - location::nearby::proto::connections::Medium current_medium_ = - location::nearby::proto::connections::UNKNOWN_MEDIUM; - absl::btree_map> - physical_connections_; - absl::btree_map> - incoming_payloads_; - absl::btree_map> - outgoing_payloads_; - }; - - bool CanRecordAnalyticsLocked(absl::string_view method_name) - ABSL_SHARED_LOCKS_REQUIRED(mutex_); - - // Callbacks the ConnectionsLog proto byte array data to the EventLogger with - // ClientSession sub-proto. - void LogClientSessionLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - // Callbacks the ConnectionsLog proto byte array data to the EventLogger. - void LogEvent(location::nearby::proto::connections::EventType event_type); - - void UpdateStrategySessionLocked( - connections::Strategy strategy, - location::nearby::proto::connections::SessionRole role) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - void RecordAdvertisingPhaseDurationAndReasonLocked(bool on_stop) const - ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void FinishAdvertisingPhaseLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - void RecordDiscoveryPhaseDurationAndReasonLocked(bool on_stop) const - ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void FinishDiscoveryPhaseLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - bool UpdateAdvertiserConnectionRequestLocked( - location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* - request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - bool UpdateDiscovererConnectionRequestLocked( - location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* - request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - bool BothEndpointsRespondedLocked( - location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* - request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void LocalEndpointRespondedLocked( - const std::string& remote_endpoint_id, - location::nearby::proto::connections::ConnectionRequestResponse response) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - void RemoteEndpointRespondedLocked( - const std::string& remote_endpoint_id, - location::nearby::proto::connections::ConnectionRequestResponse response) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - void MarkConnectionRequestIgnoredLocked( - location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* - request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void OnIncomingConnectionAttemptLocked( - location::nearby::proto::connections::ConnectionAttemptType type, - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::ConnectionAttemptResult result, - absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) - ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void OnOutgoingConnectionAttemptLocked( - const std::string& remote_endpoint_id, - location::nearby::proto::connections::ConnectionAttemptType type, - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::ConnectionAttemptResult result, - absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) - ABSL_SHARED_LOCKS_REQUIRED(mutex_); - bool ConnectionAttemptResultCodeExistedLocked( - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::ConnectionAttemptDirection - direction, - const std::string& connection_token, - location::nearby::proto::connections::ConnectionAttemptType type, location::nearby::proto::connections::OperationResultCode - operation_result_code) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - bool EraseIfBandwidthUpgradeRecordExistedLocked( - const std::string& endpoint_id, - location::nearby::proto::connections::BandwidthUpgradeResult result, - location::nearby::proto::connections::BandwidthUpgradeErrorStage - error_stage, - location::nearby::proto::connections::OperationResultCode - operation_result_code) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void FinishUpgradeAttemptLocked( - const std::string& endpoint_id, - location::nearby::proto::connections::BandwidthUpgradeResult result, - location::nearby::proto::connections::BandwidthUpgradeErrorStage - error_stage, - location::nearby::proto::connections::OperationResultCode - operation_result_code, - bool erase_item = true) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void FinishStrategySessionLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + result_code) = 0; - int GetLatestUpdateIndexLocked( - const std::vector& list) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - location::nearby::proto::connections::ConnectionsStrategy - StrategyToConnectionStrategy(connections::Strategy strategy); - location::nearby::proto::connections::PayloadType - PayloadTypeToProtoPayloadType(connections::PayloadType type); - - // Not owned by AnalyticsRecorder. Pointer must refer to a valid object - // that outlives the one constructed. - ::nearby::analytics::EventLogger* event_logger_; - - // Protects all sub-protos reading and writing in ConnectionLog. - Mutex mutex_; - - // ClientSession - std::unique_ptr< - location::nearby::analytics::proto::ConnectionsLog::ClientSession> - client_session_; - absl::Time started_client_session_time_; - bool session_was_logged_ ABSL_GUARDED_BY(mutex_) = false; - bool start_client_session_was_logged_ ABSL_GUARDED_BY(mutex_) = false; - - // Current StrategySession - connections::Strategy current_strategy_ ABSL_GUARDED_BY(mutex_) = - connections::Strategy::kNone; - std::unique_ptr< - location::nearby::analytics::proto::ConnectionsLog::StrategySession> - current_strategy_session_ ABSL_GUARDED_BY(mutex_); - absl::Time started_strategy_session_time_ ABSL_GUARDED_BY(mutex_); - - // Current AdvertisingPhase - std::unique_ptr< - location::nearby::analytics::proto::ConnectionsLog::AdvertisingPhase> - current_advertising_phase_; - absl::Time started_advertising_phase_time_ = absl::InfinitePast(); - - // Current DiscoveryPhase - std::unique_ptr< - location::nearby::analytics::proto::ConnectionsLog::DiscoveryPhase> - current_discovery_phase_; - absl::Time started_discovery_phase_time_ = absl::InfinitePast(); - - absl::btree_map> - incoming_connection_requests_ ABSL_GUARDED_BY(mutex_); - absl::btree_map> - outgoing_connection_requests_ ABSL_GUARDED_BY(mutex_); - absl::btree_map> - active_connections_ ABSL_GUARDED_BY(mutex_); - absl::btree_map> - bandwidth_upgrade_attempts_ ABSL_GUARDED_BY(mutex_); + virtual void Sync() = 0; }; -} // namespace analytics -} // namespace nearby +} // namespace nearby::analytics #endif // ANALYTICS_ANALYTICS_RECORDER_H_ diff --git a/connections/implementation/analytics/analytics_recorder_impl.cc b/connections/implementation/analytics/analytics_recorder_impl.cc new file mode 100644 index 00000000..211cc2dd --- /dev/null +++ b/connections/implementation/analytics/analytics_recorder_impl.cc @@ -0,0 +1,1643 @@ +// Copyright 2022-2023 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. + +#include "connections/implementation/analytics/analytics_recorder_impl.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "absl/algorithm/container.h" +#include "absl/container/btree_map.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "connections/implementation/analytics/advertising_metadata_params.h" +#include "connections/implementation/analytics/analytics_recorder.h" +#include "connections/implementation/analytics/connection_attempt_metadata_params.h" +#include "connections/implementation/analytics/discovery_metadata_params.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" +#include "connections/payload_type.h" +#include "connections/strategy.h" +#include "internal/analytics/event_logger.h" +#include "internal/platform/error_code_params.h" +#include "internal/platform/implementation/system_clock.h" +#include "internal/platform/logging.h" +#include "internal/platform/mutex_lock.h" +#include "internal/proto/analytics/connections_log.pb.h" +#include "proto/connections_enums.pb.h" +#include "google/protobuf/repeated_ptr_field.h" + +namespace nearby::analytics { + +namespace { +// const char kVersion_1_0_0[] = "v1.0.0"; +const char kVersion[] = "v1.5.0"; +constexpr absl::string_view kOnStartClientSession = "OnStartClientSession"; +const absl::Duration kConnectionTokenMaxLife = absl::Hours(24); + +using ::location::nearby::analytics::proto::ConnectionsLog; +using ::location::nearby::proto::connections::ACCEPTED; +using ::location::nearby::proto::connections::ADVERTISER; +using ::location::nearby::proto::connections::BandwidthUpgradeErrorStage; +using ::location::nearby::proto::connections::BandwidthUpgradeResult; +using ::location::nearby::proto::connections::BYTES; +using ::location::nearby::proto::connections::CLIENT_SESSION; +using ::location::nearby::proto::connections::CONNECTION_CLOSED; +using ::location::nearby::proto::connections::ConnectionAttemptDirection; +using ::location::nearby::proto::connections::ConnectionAttemptResult; +using ::location::nearby::proto::connections::ConnectionAttemptType; +using ::location::nearby::proto::connections::ConnectionRequestResponse; +using ::location::nearby::proto::connections::ConnectionsStrategy; +using ::location::nearby::proto::connections::DisconnectionReason; +using ::location::nearby::proto::connections::DISCOVERER; +using ::location::nearby::proto::connections::ERROR_CODE; +using ::location::nearby::proto::connections::EventType; +using ::location::nearby::proto::connections::FILE; +using ::location::nearby::proto::connections::IGNORED; +using ::location::nearby::proto::connections::INCOMING; +using ::location::nearby::proto::connections::INITIAL; +using ::location::nearby::proto::connections::Medium; +using ::location::nearby::proto::connections::MOVED_TO_NEW_MEDIUM; +using ::location::nearby::proto::connections::NOT_SENT; +using ::location::nearby::proto::connections::OperationResultCategory; +using ::location::nearby::proto::connections::OperationResultCode; +using ::location::nearby::proto::connections::OUTGOING; +using ::location::nearby::proto::connections::P2P_CLUSTER; +using ::location::nearby::proto::connections::P2P_POINT_TO_POINT; +using ::location::nearby::proto::connections::P2P_STAR; +using ::location::nearby::proto::connections::PayloadStatus; +using ::location::nearby::proto::connections::PayloadType; +using ::location::nearby::proto::connections::REJECTED; +using ::location::nearby::proto::connections::RESULT_SUCCESS; +using ::location::nearby::proto::connections::SessionRole; +using ::location::nearby::proto::connections::START_CLIENT_SESSION; +using ::location::nearby::proto::connections::START_STRATEGY_SESSION; +using ::location::nearby::proto::connections::STOP_CLIENT_SESSION; +using ::location::nearby::proto::connections::STOP_STRATEGY_SESSION; +using ::location::nearby::proto::connections::StopAdvertisingReason; +using ::location::nearby::proto::connections::StopDiscoveringReason; +using ::location::nearby::proto::connections::STREAM; +using ::location::nearby::proto::connections::UNFINISHED; +using ::location::nearby::proto::connections::UNFINISHED_ERROR; +using ::location::nearby::proto::connections::UNKNOWN_MEDIUM; +using ::location::nearby::proto::connections::UNKNOWN_PAYLOAD_TYPE; +using ::location::nearby::proto::connections::UNKNOWN_STRATEGY; +using ::location::nearby::proto::connections::UPGRADE_RESULT_SUCCESS; +using ::location::nearby::proto::connections::UPGRADE_SUCCESS; +using ::location::nearby::proto::connections::UPGRADE_UNFINISHED; +using ::location::nearby::proto::connections::UPGRADED; +using ::nearby::analytics::EventLogger; +using ProtoSafeDisconnectionResult = ::location::nearby::analytics::proto:: + ConnectionsLog::EstablishedConnection::SafeDisconnectionResult; + +OperationResultCategory ConvertToOperationResultCategory( + OperationResultCode result_code) { + if (result_code == OperationResultCode::DETAIL_SUCCESS) { + return OperationResultCategory::CATEGORY_SUCCESS; + } + // TODO(b/409865630): check later if we need to add back the dct error. + // Section of CATEGORY_DCT_ERROR, from 5000 to 5499 if (result_code + // >= OperationResultCode::DCT_ERROR_BLE_DISABLED) { + // return OperationResultCategory::CATEGORY_DCT_ERROR; + //} + + // Section of CATEGORY_NEARBY_ERROR, starting from 4500 to 4999 + if (result_code >= + OperationResultCode::NEARBY_BLE_ADVERTISEMENT_MAPPING_TO_MAC_ERROR) { + return OperationResultCategory::CATEGORY_NEARBY_ERROR; + } + // Section of CATEGORY_CONNECTIVITY_ERROR, starting from 3500 to 4499 + if (result_code >= + OperationResultCode::CONNECTIVITY_WIFI_AWARE_ATTACH_FAILURE) { + return OperationResultCategory::CATEGORY_CONNECTIVITY_ERROR; + } + // Section of CATEGORY_IO_ERROR, from 3000 to 3499 + if (result_code >= OperationResultCode::IO_FILE_OPENING_ERROR) { + return OperationResultCategory::CATEGORY_IO_ERROR; + } + // Section of CATEGORY_MISCELLANEOUS, from 2500 to 2999 + if (result_code >= + OperationResultCode::MISCELLEANEOUS_BLUETOOTH_MAC_ADDRESS_NULL) { + return OperationResultCategory::CATEGORY_MISCELLANEOUS; + } + // Section of CATEGORY_CLIENT_ERROR, from 2000 to 2499 + if (result_code >= + OperationResultCode:: + CLIENT_WIFI_DIRECT_ALREADY_HOSTING_DIRECT_GROUP_FOR_THIS_CLIENT) { + return OperationResultCategory::CATEGORY_CLIENT_ERROR; + } + // Section of CATEGORY_MEDIUM_UNAVAILABLE, from 1500 to 1999 + if (result_code >= OperationResultCode:: + MEDIUM_UNAVAILABLE_WIFI_AWARE_RESOURCE_NOT_AVAILABLE) { + return OperationResultCategory::CATEGORY_MEDIUM_UNAVAILABLE; + } + // Section of CATEGORY_DEVICE_STATE_ERROR, from 1000 to 1499 + if (result_code >= + OperationResultCode::DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS) { + return OperationResultCategory::CATEGORY_DEVICE_STATE_ERROR; + } + // Section of CATEGORY_CLIENT_CANCELLATION, from 500 to 999 + if (result_code >= + OperationResultCode::CLIENT_CANCELLATION_REMOTE_IN_CANCELED_STATE) { + return OperationResultCategory::CATEGORY_CLIENT_CANCELLATION; + } + // Clarify other non success cases as unknown + return OperationResultCategory::CATEGORY_UNKNOWN; +} + +ProtoSafeDisconnectionResult ConvertToProtoSafeDisconnectionResult( + SafeDisconnectionResult result) { + switch (result) { + case SafeDisconnectionResult::kSafeDisconnection: + return ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION; + case SafeDisconnectionResult::kUnsafeDisconnection: + return ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION; + default: + return ConnectionsLog::EstablishedConnection:: + UNKNOWN_SAFE_DISCONNECTION_RESULT; + } +} + +ConnectionsLog::OperationResultWithMedium +ConvertToProtoOperationResultWithMedium( + const nearby::analytics::OperationResultWithMedium& cpp_result) { + ConnectionsLog::OperationResultWithMedium proto_result; + proto_result.set_medium(cpp_result.medium); + if (cpp_result.update_index.has_value()) { + proto_result.set_update_index(cpp_result.update_index.value()); + } + proto_result.set_result_category(cpp_result.result_category); + proto_result.set_result_code(cpp_result.result_code); + if (cpp_result.connection_mode.has_value()) { + proto_result.set_connection_mode(cpp_result.connection_mode.value()); + } + return proto_result; +} + +} // namespace + +AnalyticsRecorderImpl::AnalyticsRecorderImpl(EventLogger* event_logger) + : event_logger_(event_logger) { + VLOG(1) << "Start AnalyticsRecorderImpl ctor event_logger_=" << event_logger_; + LogStartSession(); +} + +AnalyticsRecorderImpl::~AnalyticsRecorderImpl() = default; + +bool AnalyticsRecorderImpl::IsSessionLogged() { + MutexLock lock(&mutex_); + return session_was_logged_; +} + +int AnalyticsRecorderImpl::GetLatestUpdateIndexLocked( + const std::vector& list) { + int latest_update_index = 0; + for (const auto& operation_result_with_medium : list) { + if (operation_result_with_medium.update_index() > latest_update_index) { + latest_update_index = operation_result_with_medium.update_index(); + } + } + return latest_update_index; +} + +void AnalyticsRecorderImpl::OnStartAdvertising( + connections::Strategy strategy, const std::vector& mediums, + AdvertisingMetadataParams* advertising_metadata_params) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnStartAdvertising")) { + return; + } + if (!strategy.IsValid()) { + LOG(INFO) << "AnalyticsRecorderImpl OnStartAdvertising with unknown " + "strategy, bail out."; + return; + } + // Initialize/update a StrategySession. + UpdateStrategySessionLocked(strategy, ADVERTISER); + + // Initialize and set a AdvertisingPhase. + started_advertising_phase_time_ = SystemClock::ElapsedRealtime(); + current_advertising_phase_ = + std::make_unique(); + absl::c_copy(mediums, RepeatedFieldBackInserter( + current_advertising_phase_->mutable_medium())); + // Set a AdvertisingMetadata. + AdvertisingMetadataParams default_params = {}; + if (advertising_metadata_params == nullptr) { + advertising_metadata_params = &default_params; + } + if (!advertising_metadata_params->operation_result_with_mediums.empty()) { + for (const auto& cpp_result : + advertising_metadata_params->operation_result_with_mediums) { + *current_advertising_phase_->add_adv_dis_result() = + ConvertToProtoOperationResultWithMedium(cpp_result); + } + } + auto* advertising_metadata = + current_advertising_phase_->mutable_advertising_metadata(); + advertising_metadata->set_supports_extended_ble_advertisements( + advertising_metadata_params->is_extended_advertisement_supported); + advertising_metadata->set_connected_ap_frequency( + advertising_metadata_params->connected_ap_frequency); + advertising_metadata->set_supports_nfc_technology( + advertising_metadata_params->is_nfc_available); +} + +void AnalyticsRecorderImpl::OnStopAdvertising() { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnStopAdvertising")) { + return; + } + RecordAdvertisingPhaseDurationAndReasonLocked(/* on_stop= */ true); +} + +int AnalyticsRecorderImpl::GetNextAdvertisingUpdateIndex() { + MutexLock lock(&mutex_); + + if (current_advertising_phase_ == nullptr) { + return 0; + } + return GetLatestUpdateIndexLocked( + std::vector( + current_advertising_phase_->adv_dis_result().begin(), + current_advertising_phase_->adv_dis_result().end())) + + 1; +} + +void AnalyticsRecorderImpl::OnStartDiscovery( + connections::Strategy strategy, const std::vector& mediums, + DiscoveryMetadataParams* discovery_metadata_params) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnStartDiscovery")) { + return; + } + if (!strategy.IsValid()) { + LOG(INFO) << "AnalyticsRecorderImpl OnStartDiscovery unknown " + "strategy enter, bail out."; + return; + } + + // Initialize/update a StrategySession. + UpdateStrategySessionLocked(strategy, DISCOVERER); + + // Initialize and set a DiscoveryPhase. + started_discovery_phase_time_ = SystemClock::ElapsedRealtime(); + current_discovery_phase_ = std::make_unique(); + absl::c_copy(mediums, RepeatedFieldBackInserter( + current_discovery_phase_->mutable_medium())); + // Set a DiscoveryMetadata. + DiscoveryMetadataParams default_params = {}; + if (discovery_metadata_params == nullptr) { + discovery_metadata_params = &default_params; + } + if (!discovery_metadata_params->operation_result_with_mediums.empty()) { + for (const auto& cpp_result : + discovery_metadata_params->operation_result_with_mediums) { + *current_discovery_phase_->add_adv_dis_result() = + ConvertToProtoOperationResultWithMedium(cpp_result); + } + } + auto* discovery_metadata = + current_discovery_phase_->mutable_discovery_metadata(); + discovery_metadata->set_supports_extended_ble_advertisements( + discovery_metadata_params->is_extended_advertisement_supported); + discovery_metadata->set_connected_ap_frequency( + discovery_metadata_params->connected_ap_frequency); + discovery_metadata->set_supports_nfc_technology( + discovery_metadata_params->is_nfc_available); +} + +void AnalyticsRecorderImpl::OnStopDiscovery() { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnStopDiscovery")) { + return; + } + RecordDiscoveryPhaseDurationAndReasonLocked(/*on_stop=*/true); +} + +int AnalyticsRecorderImpl::GetNextDiscoveryUpdateIndex() { + MutexLock lock(&mutex_); + if (current_discovery_phase_ == nullptr) { + return 0; + } + return GetLatestUpdateIndexLocked( + std::vector( + current_discovery_phase_->adv_dis_result().begin(), + current_discovery_phase_->adv_dis_result().end())) + + 1; +} + +void AnalyticsRecorderImpl::OnStartedIncomingConnectionListening( + connections::Strategy strategy) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnStartedIncomingConnectionListening")) { + return; + } + UpdateStrategySessionLocked(strategy, ADVERTISER); + if (started_advertising_phase_time_ == absl::InfinitePast()) { + started_advertising_phase_time_ = SystemClock::ElapsedRealtime(); + } +} + +void AnalyticsRecorderImpl::OnStoppedIncomingConnectionListening() { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnStoppedIncomingConnectionListening")) { + return; + } + RecordAdvertisingPhaseDurationAndReasonLocked(/* on_stop= */ false); +} + +void AnalyticsRecorderImpl::OnEndpointFound(Medium medium) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnEndpointFound")) { + return; + } + if (current_discovery_phase_ == nullptr) { + LOG(INFO) << "Unable to record discovered endpoint due to null " + "current_discovery_phase_"; + return; + } + ConnectionsLog::DiscoveredEndpoint* discovered_endpoint = + current_discovery_phase_->add_discovered_endpoint(); + discovered_endpoint->set_medium(medium); + discovered_endpoint->set_latency_millis(absl::ToInt64Milliseconds( + SystemClock::ElapsedRealtime() - started_discovery_phase_time_)); +} + +void AnalyticsRecorderImpl::OnRequestConnection( + const connections::Strategy& strategy, const std::string& endpoint_id) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("onRequestConnection")) { + return; + } + + UpdateStrategySessionLocked(strategy, DISCOVERER); + if (started_discovery_phase_time_ == absl::InfinitePast()) { + started_discovery_phase_time_ = SystemClock::ElapsedRealtime(); + } +} + +void AnalyticsRecorderImpl::OnConnectionRequestReceived( + const std::string& remote_endpoint_id) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnConnectionRequestReceived")) { + return; + } + absl::Time current_time = SystemClock::ElapsedRealtime(); + auto connection_request = + std::make_unique(); + connection_request->set_duration_millis(absl::ToUnixMillis(current_time)); + connection_request->set_request_delay_millis(absl::ToInt64Milliseconds( + current_time - started_advertising_phase_time_)); + incoming_connection_requests_.insert( + {remote_endpoint_id, std::move(connection_request)}); +} + +void AnalyticsRecorderImpl::OnConnectionRequestSent( + const std::string& remote_endpoint_id) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnConnectionRequestSent")) { + return; + } + absl::Time current_time = SystemClock::ElapsedRealtime(); + auto connection_request = + std::make_unique(); + connection_request->set_duration_millis(absl::ToUnixMillis(current_time)); + connection_request->set_request_delay_millis( + absl::ToInt64Milliseconds(current_time - started_discovery_phase_time_)); + outgoing_connection_requests_.insert( + {remote_endpoint_id, std::move(connection_request)}); +} + +void AnalyticsRecorderImpl::OnRemoteEndpointAccepted( + const std::string& remote_endpoint_id) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnRemoteEndpointAccepted")) { + return; + } + RemoteEndpointRespondedLocked(remote_endpoint_id, ACCEPTED); +} + +void AnalyticsRecorderImpl::OnLocalEndpointAccepted( + const std::string& remote_endpoint_id) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnLocalEndpointAccepted")) { + return; + } + LocalEndpointRespondedLocked(remote_endpoint_id, ACCEPTED); +} + +void AnalyticsRecorderImpl::OnRemoteEndpointRejected( + const std::string& remote_endpoint_id) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnRemoteEndpointRejected")) { + return; + } + RemoteEndpointRespondedLocked(remote_endpoint_id, REJECTED); +} + +void AnalyticsRecorderImpl::OnLocalEndpointRejected( + const std::string& remote_endpoint_id) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnLocalEndpointRejected")) { + return; + } + LocalEndpointRespondedLocked(remote_endpoint_id, REJECTED); +} + +void AnalyticsRecorderImpl::OnIncomingConnectionAttempt( + ConnectionAttemptType type, Medium medium, ConnectionAttemptResult result, + absl::Duration duration, const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnIncomingConnectionAttempt")) { + return; + } + if (current_strategy_session_ == nullptr) { + LOG(INFO) << "Unable to record incoming connection attempt due to " + "null current_strategy_session_"; + return; + } + + ConnectionAttemptMetadataParams default_params = {}; + if (connection_attempt_metadata_params == nullptr) { + connection_attempt_metadata_params = &default_params; + } + OnIncomingConnectionAttemptLocked(type, medium, result, duration, + connection_token, + connection_attempt_metadata_params); +} + +void AnalyticsRecorderImpl::OnIncomingConnectionAttemptLocked( + location::nearby::proto::connections::ConnectionAttemptType type, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::ConnectionAttemptResult result, + absl::Duration duration, const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { + auto* connection_attempt = + current_strategy_session_->add_connection_attempt(); + connection_attempt->set_duration_millis(absl::ToInt64Milliseconds(duration)); + connection_attempt->set_type(type); + connection_attempt->set_direction(INCOMING); + connection_attempt->set_medium(medium); + connection_attempt->set_attempt_result(result); + connection_attempt->set_connection_token(connection_token); + + auto* connection_attempt_metadata = + connection_attempt->mutable_connection_attempt_metadata(); + connection_attempt_metadata->set_technology( + connection_attempt_metadata_params->technology); + connection_attempt_metadata->set_band( + connection_attempt_metadata_params->band); + connection_attempt_metadata->set_frequency( + connection_attempt_metadata_params->frequency); + connection_attempt_metadata->set_network_operator( + connection_attempt_metadata_params->network_operator); + connection_attempt_metadata->set_country_code( + connection_attempt_metadata_params->country_code); + connection_attempt_metadata->set_frequency( + connection_attempt_metadata_params->frequency); + connection_attempt_metadata->set_is_tdls_used( + connection_attempt_metadata_params->is_tdls_used); + connection_attempt_metadata->set_wifi_hotspot_status( + connection_attempt_metadata_params->wifi_hotspot_enabled); + connection_attempt_metadata->set_try_counts( + connection_attempt_metadata_params->try_count); + connection_attempt_metadata->set_max_tx_speed( + connection_attempt_metadata_params->max_wifi_tx_speed); + connection_attempt_metadata->set_max_rx_speed( + connection_attempt_metadata_params->max_wifi_rx_speed); + connection_attempt_metadata->set_wifi_channel_width( + connection_attempt_metadata_params->channel_width); + + auto operation_result_proto = + std::make_unique(); + operation_result_proto->set_result_code( + connection_attempt_metadata_params->operation_result_code); + operation_result_proto->set_result_category(ConvertToOperationResultCategory( + connection_attempt_metadata_params->operation_result_code)); + connection_attempt->set_allocated_operation_result( + operation_result_proto.release()); +} + +void AnalyticsRecorderImpl::OnOutgoingConnectionAttempt( + const std::string& remote_endpoint_id, ConnectionAttemptType type, + Medium medium, ConnectionAttemptResult result, absl::Duration duration, + const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnOutgoingConnectionAttempt")) { + return; + } + if (current_strategy_session_ == nullptr) { + LOG(INFO) << "Unable to record outgoing connection attempt due to " + "null current_strategy_session_"; + return; + } + + ConnectionAttemptMetadataParams default_params = {}; + if (connection_attempt_metadata_params == nullptr) { + connection_attempt_metadata_params = &default_params; + } + + // For the case of transfer a big file and the upgrades always failure, then + // there will have repeating upgrade attempt and cause many same attempt value + // be log. So add a method to skip. + if (ConnectionAttemptResultCodeExistedLocked( + medium, OUTGOING, connection_token, type, + connection_attempt_metadata_params->operation_result_code)) { + return; + } + + OnOutgoingConnectionAttemptLocked(remote_endpoint_id, type, medium, result, + duration, connection_token, + connection_attempt_metadata_params); +} + +void AnalyticsRecorderImpl::OnOutgoingConnectionAttemptLocked( + const std::string& remote_endpoint_id, ConnectionAttemptType type, + Medium medium, ConnectionAttemptResult result, absl::Duration duration, + const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { + auto* connection_attempt = + current_strategy_session_->add_connection_attempt(); + connection_attempt->set_duration_millis(absl::ToInt64Milliseconds(duration)); + connection_attempt->set_type(type); + connection_attempt->set_direction(OUTGOING); + connection_attempt->set_medium(medium); + connection_attempt->set_attempt_result(result); + connection_attempt->set_connection_token(connection_token); + + auto* connection_attempt_metadata = + connection_attempt->mutable_connection_attempt_metadata(); + connection_attempt_metadata->set_technology( + connection_attempt_metadata_params->technology); + connection_attempt_metadata->set_band( + connection_attempt_metadata_params->band); + connection_attempt_metadata->set_frequency( + connection_attempt_metadata_params->frequency); + connection_attempt_metadata->set_network_operator( + connection_attempt_metadata_params->network_operator); + connection_attempt_metadata->set_country_code( + connection_attempt_metadata_params->country_code); + connection_attempt_metadata->set_frequency( + connection_attempt_metadata_params->frequency); + connection_attempt_metadata->set_is_tdls_used( + connection_attempt_metadata_params->is_tdls_used); + connection_attempt_metadata->set_wifi_hotspot_status( + connection_attempt_metadata_params->wifi_hotspot_enabled); + connection_attempt_metadata->set_try_counts( + connection_attempt_metadata_params->try_count); + connection_attempt_metadata->set_max_tx_speed( + connection_attempt_metadata_params->max_wifi_tx_speed); + connection_attempt_metadata->set_max_rx_speed( + connection_attempt_metadata_params->max_wifi_rx_speed); + connection_attempt_metadata->set_wifi_channel_width( + connection_attempt_metadata_params->channel_width); + + auto operation_result_proto = + std::make_unique(); + operation_result_proto->set_result_code( + connection_attempt_metadata_params->operation_result_code); + operation_result_proto->set_result_category(ConvertToOperationResultCategory( + connection_attempt_metadata_params->operation_result_code)); + connection_attempt->set_allocated_operation_result( + operation_result_proto.release()); + + if (type == INITIAL && result != RESULT_SUCCESS) { + auto it = outgoing_connection_requests_.find(remote_endpoint_id); + if (it != outgoing_connection_requests_.end()) { + // An outgoing, initial ConnectionAttempt has a corresponding + // ConnectionRequest that, since the ConnectionAttempt has failed, will + // never be delivered to the advertiser. + auto pair = outgoing_connection_requests_.extract(it); + std::unique_ptr& connection_request = + pair.mapped(); + connection_request->set_local_response(NOT_SENT); + connection_request->set_remote_response(NOT_SENT); + UpdateDiscovererConnectionRequestLocked(connection_request.get()); + } + } +} + +void AnalyticsRecorderImpl::OnConnectionEstablished( + const std::string& endpoint_id, Medium medium, + const std::string& connection_token) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnConnectionEstablished")) { + return; + } + auto it = active_connections_.find(endpoint_id); + if (it != active_connections_.end()) { + const std::unique_ptr& logical_connection = it->second; + logical_connection->PhysicalConnectionEstablished(medium, connection_token); + } else { + active_connections_.insert( + {endpoint_id, + std::make_unique(medium, connection_token)}); + } +} + +void AnalyticsRecorderImpl::OnConnectionClosed(const std::string& endpoint_id, + Medium medium, + DisconnectionReason reason, + SafeDisconnectionResult result) { + MutexLock lock(&mutex_); + LOG(INFO) << __func__ + << ": OnConnectionClosed is called with endpoint_id:" << endpoint_id + << ", medium:" << Medium_Name(medium) + << ", reason:" << DisconnectionReason_Name(reason) + << ", result:" << static_cast(result); + + if (!CanRecordAnalyticsLocked("OnConnectionClosed")) { + return; + } + + if (current_strategy_session_ == nullptr) { + VLOG(1) << "AnalyticsRecorderImpl CanRecordAnalytics Unexpected call " + << __func__ << " since current_strategy_session_ is required."; + return; + } + + auto it = active_connections_.find(endpoint_id); + if (it == active_connections_.end()) { + return; + } + const std::unique_ptr& logical_connection = it->second; + logical_connection->PhysicalConnectionClosed(medium, reason, result); + if (reason != UPGRADED) { + // Unless this is an upgraded connection, remove this from our active + // connections. Any future communication with an endpoint will need to be + // re-established with a new ConnectionRequest. + auto pair = active_connections_.extract(it); + std::unique_ptr& logical_connection = pair.mapped(); + + absl::c_copy( + logical_connection->GetEstablisedConnections(), + RepeatedFieldBackInserter( + current_strategy_session_->mutable_established_connection())); + } +} + +void AnalyticsRecorderImpl::OnIncomingPayloadStarted( + const std::string& endpoint_id, std::int64_t payload_id, + connections::PayloadType type, std::int64_t total_size_bytes) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnIncomingPayloadStarted")) { + return; + } + auto it = active_connections_.find(endpoint_id); + if (it == active_connections_.end()) { + return; + } + const std::unique_ptr& logical_connection = it->second; + logical_connection->IncomingPayloadStarted( + payload_id, PayloadTypeToProtoPayloadType(type), total_size_bytes); +} + +void AnalyticsRecorderImpl::OnPayloadChunkReceived( + const std::string& endpoint_id, std::int64_t payload_id, + std::int64_t chunk_size_bytes) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnPayloadChunkReceived")) { + return; + } + auto it = active_connections_.find(endpoint_id); + if (it == active_connections_.end()) { + return; + } + const std::unique_ptr& logical_connection = it->second; + logical_connection->ChunkReceived(payload_id, chunk_size_bytes); +} + +void AnalyticsRecorderImpl::OnIncomingPayloadDone( + const std::string& endpoint_id, std::int64_t payload_id, + PayloadStatus status, OperationResultCode operation_result_code) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnIncomingPayloadDone")) { + return; + } + auto it = active_connections_.find(endpoint_id); + if (it == active_connections_.end()) { + return; + } + const std::unique_ptr& logical_connection = it->second; + logical_connection->IncomingPayloadDone(payload_id, status, + operation_result_code); +} + +void AnalyticsRecorderImpl::OnOutgoingPayloadStarted( + const std::vector& endpoint_ids, std::int64_t payload_id, + connections::PayloadType type, std::int64_t total_size_bytes) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnOutgoingPayloadStarted")) { + return; + } + for (const auto& endpoint_id : endpoint_ids) { + auto it = active_connections_.find(endpoint_id); + if (it == active_connections_.end()) { + continue; + } + const std::unique_ptr& logical_connection = it->second; + logical_connection->OutgoingPayloadStarted( + payload_id, PayloadTypeToProtoPayloadType(type), total_size_bytes); + } +} + +void AnalyticsRecorderImpl::OnPayloadChunkSent(const std::string& endpoint_id, + std::int64_t payload_id, + std::int64_t chunk_size_bytes) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnPayloadChunkSent")) { + return; + } + auto it = active_connections_.find(endpoint_id); + if (it == active_connections_.end()) { + return; + } + const std::unique_ptr& logical_connection = it->second; + logical_connection->ChunkSent(payload_id, chunk_size_bytes); +} + +void AnalyticsRecorderImpl::OnOutgoingPayloadDone( + const std::string& endpoint_id, std::int64_t payload_id, + PayloadStatus status, OperationResultCode operation_result_code) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnOutgoingPayloadDone")) { + return; + } + auto it = active_connections_.find(endpoint_id); + if (it == active_connections_.end()) { + return; + } + + const std::unique_ptr& logical_connection = it->second; + logical_connection->OutgoingPayloadDone(payload_id, status, + operation_result_code); +} + +void AnalyticsRecorderImpl::OnBandwidthUpgradeStarted( + const std::string& endpoint_id, Medium from_medium, Medium to_medium, + ConnectionAttemptDirection direction, const std::string& connection_token) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnBandwidthUpgradeStarted")) { + return; + } + auto bandwidth_upgrade_attempt = + std::make_unique(); + bandwidth_upgrade_attempt->set_duration_millis( + absl::ToUnixMillis(SystemClock::ElapsedRealtime())); + bandwidth_upgrade_attempt->set_from_medium(from_medium); + bandwidth_upgrade_attempt->set_to_medium(to_medium); + bandwidth_upgrade_attempt->set_direction(direction); + bandwidth_upgrade_attempt->set_connection_token(connection_token); + bandwidth_upgrade_attempts_.insert( + {endpoint_id, std::move(bandwidth_upgrade_attempt)}); +} + +void AnalyticsRecorderImpl::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 AnalyticsRecorderImpl::OnBandwidthUpgradeError( + const std::string& endpoint_id, BandwidthUpgradeResult result, + BandwidthUpgradeErrorStage error_stage, + OperationResultCode operation_result_code) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnBandwidthUpgradeError")) { + return; + } + // If the same records existed, drop this one. + if (EraseIfBandwidthUpgradeRecordExistedLocked( + endpoint_id, result, error_stage, operation_result_code)) { + return; + } + FinishUpgradeAttemptLocked(endpoint_id, result, error_stage, + operation_result_code); +} + +void AnalyticsRecorderImpl::OnBandwidthUpgradeSuccess( + const std::string& endpoint_id) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnBandwidthUpgradeSuccess")) { + return; + } + FinishUpgradeAttemptLocked(endpoint_id, UPGRADE_RESULT_SUCCESS, + UPGRADE_SUCCESS, + OperationResultCode::DETAIL_SUCCESS); +} + +void AnalyticsRecorderImpl::OnErrorCode(const ErrorCodeParams& params) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("OnErrorCode")) { + return; + } + auto error_code = std::make_unique(); + error_code->set_medium(params.medium); + error_code->set_event(params.event); + error_code->set_connection_token(params.connection_token); + error_code->set_description(params.description); + + if (params.is_common_error) { + error_code->set_common_error(params.common_error); + } else { + switch (params.event) { + case location::nearby::errorcode::proto::START_ADVERTISING: + error_code->set_start_advertising_error(params.start_advertising_error); + break; + case location::nearby::errorcode::proto::STOP_ADVERTISING: + error_code->set_stop_advertising_error(params.stop_advertising_error); + break; + case location::nearby::errorcode::proto:: + START_LISTENING_INCOMING_CONNECTION: + error_code->set_start_listening_incoming_connection_error( + params.start_listening_incoming_connection_error); + break; + case location::nearby::errorcode::proto:: + STOP_LISTENING_INCOMING_CONNECTION: + error_code->set_stop_listening_incoming_connection_error( + params.stop_listening_incoming_connection_error); + break; + case location::nearby::errorcode::proto::START_DISCOVERING: + error_code->set_start_discovering_error(params.start_discovering_error); + break; + case location::nearby::errorcode::proto::STOP_DISCOVERING: + error_code->set_stop_discovering_error(params.stop_discovering_error); + break; + case location::nearby::errorcode::proto::CONNECT: + error_code->set_connect_error(params.connect_error); + break; + case location::nearby::errorcode::proto::DISCONNECT: + error_code->set_disconnect_error(params.disconnect_error); + break; + case location::nearby::errorcode::proto::UNKNOWN_EVENT: + default: + error_code->set_common_error(params.common_error); + break; + } + } + + ConnectionsLog connections_log; + connections_log.set_event_type(ERROR_CODE); + connections_log.set_version(kVersion); + connections_log.set_allocated_error_code(error_code.release()); + + VLOG(1) << "AnalyticsRecorderImpl LogErrorCode connections_log=" + << connections_log.DebugString(); // NOLINT + + event_logger_->Log(connections_log); +} + +void AnalyticsRecorderImpl::LogStartSession() { + MutexLock lock(&mutex_); + if (start_client_session_was_logged_) { + LOG(WARNING) << "AnalyticsRecorderImpl CanRecordAnalytics Unexpected call " + << kOnStartClientSession + << " after start client session has already been logged."; + return; + } + + session_was_logged_ = false; + if (CanRecordAnalyticsLocked(kOnStartClientSession)) { + client_session_ = std::make_unique(); + started_client_session_time_ = SystemClock::ElapsedRealtime(); + start_client_session_was_logged_ = true; + LogEvent(START_CLIENT_SESSION); + } +} + +void AnalyticsRecorderImpl::LogSession() { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("LogSession")) { + return; + } + FinishStrategySessionLocked(); + client_session_->set_duration_millis(absl::ToInt64Milliseconds( + SystemClock::ElapsedRealtime() - started_client_session_time_)); + LogClientSessionLocked(); + LogEvent(STOP_CLIENT_SESSION); + start_client_session_was_logged_ = false; + session_was_logged_ = true; +} + +bool AnalyticsRecorderImpl::CanRecordAnalyticsLocked( + absl::string_view method_name) { + VLOG(1) << "AnalyticsRecorderImpl LogEvent " << method_name << " is calling."; + if (event_logger_ == nullptr) { + return false; + } + + if (session_was_logged_) { + VLOG(1) << "AnalyticsRecorderImpl CanRecordAnalytics Unexpected call " + << method_name << " after session has already been logged."; + return false; + } + + return true; +} + +// TODO: b/391339677 - Investigate why we need to reset the resources. And +// verify in b/238375695 to see if we still meet the issue after removing the +// Reset function. +void AnalyticsRecorderImpl::LogClientSessionLocked() { + ConnectionsLog connections_log; + connections_log.set_event_type(CLIENT_SESSION); + connections_log.set_allocated_client_session(client_session_.release()); + connections_log.set_version(kVersion); + + VLOG(1) << "AnalyticsRecorderImpl LogClientSession connections_log=" + << connections_log.DebugString(); // NOLINT + + event_logger_->Log(connections_log); + client_session_ = nullptr; +} + +void AnalyticsRecorderImpl::LogEvent(EventType event_type) { + ConnectionsLog connections_log; + connections_log.set_event_type(event_type); + connections_log.set_version(kVersion); + + VLOG(1) << "AnalyticsRecorderImpl LogEvent connections_log=" + << connections_log.DebugString(); // NOLINT + + event_logger_->Log(connections_log); +} + +void AnalyticsRecorderImpl::UpdateStrategySessionLocked( + connections::Strategy strategy, SessionRole role) { + // If we're not switching strategies, just update the current StrategySession + // with the new role. + if (strategy == current_strategy_ && current_strategy_session_ != nullptr) { + if (absl::c_linear_search(current_strategy_session_->role(), role)) { + // We've already acted as this role before, so make sure we've finished + // recording the previous round. + switch (role) { + case ADVERTISER: + FinishAdvertisingPhaseLocked(); + break; + case DISCOVERER: + FinishDiscoveryPhaseLocked(); + break; + default: + break; + } + } else { + current_strategy_session_->add_role(role); + } + } else { + // Otherwise, we're starting a new Strategy. + current_strategy_ = strategy; + FinishStrategySessionLocked(); + LogEvent(START_STRATEGY_SESSION); + current_strategy_session_ = + std::make_unique(); + started_strategy_session_time_ = SystemClock::ElapsedRealtime(); + current_strategy_session_->set_strategy( + StrategyToConnectionStrategy(strategy)); + current_strategy_session_->add_role(role); + } +} + +void AnalyticsRecorderImpl::RecordAdvertisingPhaseDurationAndReasonLocked( + bool on_stop) const { + if (current_advertising_phase_ == nullptr) { + LOG(INFO) << "Unable to record advertising phase duration due to " + "null current_advertising_phase_"; + return; + } + if (!current_advertising_phase_->has_duration_millis()) { + current_advertising_phase_->set_duration_millis(absl::ToInt64Milliseconds( + SystemClock::ElapsedRealtime() - started_advertising_phase_time_)); + } + if (!current_advertising_phase_->has_stop_reason()) { + current_advertising_phase_->set_stop_reason( + on_stop ? StopAdvertisingReason::CLIENT_STOP_ADVERTISING + : StopAdvertisingReason::FINISH_SESSION_STOP_ADVERTISING); + } +} + +void AnalyticsRecorderImpl::FinishAdvertisingPhaseLocked() { + if (current_advertising_phase_ != nullptr) { + for (const auto& item : incoming_connection_requests_) { + // ConnectionRequests still pending have been ignored by the local or + // remote (or both) endpoints. + const std::unique_ptr& + connection_request = item.second; + MarkConnectionRequestIgnoredLocked(connection_request.get()); + UpdateAdvertiserConnectionRequestLocked(connection_request.get()); + } + RecordAdvertisingPhaseDurationAndReasonLocked(/* on_stop= */ false); + if (current_strategy_session_ != nullptr) { + *current_strategy_session_->add_advertising_phase() = + *std::move(current_advertising_phase_); + } else { + LOG(INFO) << "Unable to record advertising phase due to null " + "current_strategy_session_"; + } + } + incoming_connection_requests_.clear(); +} + +void AnalyticsRecorderImpl::RecordDiscoveryPhaseDurationAndReasonLocked( + bool on_stop) const { + if (current_discovery_phase_ == nullptr) { + LOG(INFO) << "Unable to record discovery phase duration due to " + "null current_discovery_phase_"; + return; + } + if (!current_discovery_phase_->has_duration_millis()) { + current_discovery_phase_->set_duration_millis(absl::ToInt64Milliseconds( + SystemClock::ElapsedRealtime() - started_discovery_phase_time_)); + } + // If the stop reason haven't been set yet, then set it. + if (!current_discovery_phase_->has_stop_reason()) { + current_discovery_phase_->set_stop_reason( + on_stop ? StopDiscoveringReason::CLIENT_STOP_DISCOVERING + : StopDiscoveringReason::FINISH_SESSION_STOP_DISCOVERING); + } +} + +void AnalyticsRecorderImpl::FinishDiscoveryPhaseLocked() { + if (current_discovery_phase_ != nullptr) { + for (const auto& item : outgoing_connection_requests_) { + // ConnectionRequests still pending have been ignored by the local or + // remote (or both) endpoints. + const std::unique_ptr& + connection_request = item.second; + MarkConnectionRequestIgnoredLocked(connection_request.get()); + UpdateDiscovererConnectionRequestLocked(connection_request.get()); + } + RecordDiscoveryPhaseDurationAndReasonLocked(/* on_stop=*/false); + if (current_strategy_session_ != nullptr) { + *current_strategy_session_->add_discovery_phase() = + *std::move(current_discovery_phase_); + } else { + LOG(INFO) << "Unable to record discovery phase due to null " + "current_strategy_session_"; + } + } + outgoing_connection_requests_.clear(); +} + +bool AnalyticsRecorderImpl::UpdateAdvertiserConnectionRequestLocked( + ConnectionsLog::ConnectionRequest* request) { + if (current_advertising_phase_ == nullptr) { + LOG(INFO) << "Unable to record advertiser connection request due to null " + "current_advertising_phase_"; + return false; + } + if (BothEndpointsRespondedLocked(request)) { + request->set_duration_millis( + absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - + request->duration_millis()); + *current_advertising_phase_->add_received_connection_request() = *request; + return true; + } + return false; +} + +bool AnalyticsRecorderImpl::UpdateDiscovererConnectionRequestLocked( + ConnectionsLog::ConnectionRequest* request) { + if (current_discovery_phase_ == nullptr) { + LOG(INFO) << "Unable to record discoverer connection request due " + "to null current_discovery_phase_."; + return false; + } + if (BothEndpointsRespondedLocked(request) || + request->local_response() == NOT_SENT) { + request->set_duration_millis( + absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - + request->duration_millis()); + *current_discovery_phase_->add_sent_connection_request() = *request; + return true; + } + return false; +} + +bool AnalyticsRecorderImpl::BothEndpointsRespondedLocked( + ConnectionsLog::ConnectionRequest* request) { + return request->has_local_response() && request->has_remote_response(); +} + +void AnalyticsRecorderImpl::LocalEndpointRespondedLocked( + const std::string& remote_endpoint_id, ConnectionRequestResponse response) { + auto out = outgoing_connection_requests_.find(remote_endpoint_id); + if (out != outgoing_connection_requests_.end()) { + ConnectionsLog::ConnectionRequest* connection_request = out->second.get(); + connection_request->set_local_response(response); + if (UpdateDiscovererConnectionRequestLocked(connection_request)) { + outgoing_connection_requests_.erase(out); + } + } + auto in = incoming_connection_requests_.find(remote_endpoint_id); + if (in != incoming_connection_requests_.end()) { + ConnectionsLog::ConnectionRequest* connection_request = in->second.get(); + connection_request->set_local_response(response); + if (UpdateAdvertiserConnectionRequestLocked(connection_request)) { + incoming_connection_requests_.erase(in); + } + } +} + +void AnalyticsRecorderImpl::RemoteEndpointRespondedLocked( + const std::string& remote_endpoint_id, ConnectionRequestResponse response) { + auto out = outgoing_connection_requests_.find(remote_endpoint_id); + if (out != outgoing_connection_requests_.end()) { + ConnectionsLog::ConnectionRequest* connection_request = out->second.get(); + connection_request->set_remote_response(response); + if (UpdateDiscovererConnectionRequestLocked(connection_request)) { + outgoing_connection_requests_.erase(out); + } + } + auto in = incoming_connection_requests_.find(remote_endpoint_id); + if (in != incoming_connection_requests_.end()) { + ConnectionsLog::ConnectionRequest* connection_request = in->second.get(); + connection_request->set_remote_response(response); + if (UpdateAdvertiserConnectionRequestLocked(connection_request)) { + incoming_connection_requests_.erase(in); + } + } +} + +void AnalyticsRecorderImpl::MarkConnectionRequestIgnoredLocked( + ConnectionsLog::ConnectionRequest* request) { + if (!request->has_local_response()) { + request->set_local_response(IGNORED); + } + if (!request->has_remote_response()) { + request->set_remote_response(IGNORED); + } +} + +bool AnalyticsRecorderImpl::ConnectionAttemptResultCodeExistedLocked( + Medium medium, ConnectionAttemptDirection direction, + const std::string& connection_token, ConnectionAttemptType type, + OperationResultCode operation_result_code) { + if (current_strategy_session_ == nullptr || + current_strategy_session_->connection_attempt_size() == 0) { + return false; + } + for (auto& connection_attempt : + current_strategy_session_->connection_attempt()) { + if (connection_attempt.medium() == medium && + connection_attempt.direction() == direction && + connection_attempt.connection_token() == connection_token && + connection_attempt.type() == type && + connection_attempt.operation_result().result_code() == + operation_result_code) { + return true; + } + } + + return false; +} + +// If bandwidth upgrade always failed on the same fromMedium, toMedium, result, +// stage and result code, we'll drop the duplicate logs for preventing the waste +// of log storage space +bool AnalyticsRecorderImpl::EraseIfBandwidthUpgradeRecordExistedLocked( + const std::string& endpoint_id, BandwidthUpgradeResult result, + BandwidthUpgradeErrorStage error_stage, + OperationResultCode operation_result_code) { + if (current_strategy_session_ == nullptr) { + return false; + } + auto it = bandwidth_upgrade_attempts_.find(endpoint_id); + if (it != bandwidth_upgrade_attempts_.end()) { + ConnectionsLog::BandwidthUpgradeAttempt* attempt = it->second.get(); + for (auto& existing_attempt : + current_strategy_session_->upgrade_attempt()) { + if (attempt->from_medium() == existing_attempt.from_medium() && + attempt->to_medium() == existing_attempt.to_medium() && + result == existing_attempt.upgrade_result() && + error_stage == existing_attempt.error_stage() && + operation_result_code == + existing_attempt.operation_result().result_code()) { + bandwidth_upgrade_attempts_.erase(it); + return true; + } + } + } + return false; +} + +void AnalyticsRecorderImpl::FinishUpgradeAttemptLocked( + const std::string& endpoint_id, BandwidthUpgradeResult result, + BandwidthUpgradeErrorStage error_stage, + OperationResultCode operation_result_code, bool erase_item) { + if (current_strategy_session_ == nullptr) { + LOG(INFO) << "Unable to record upgrade attempt due to null " + "current_strategy_session_"; + return; + } + // Add the BandwidthUpgradeAttempt in the current StrategySession. + auto it = bandwidth_upgrade_attempts_.find(endpoint_id); + if (it != bandwidth_upgrade_attempts_.end()) { + ConnectionsLog::BandwidthUpgradeAttempt* attempt = it->second.get(); + attempt->set_duration_millis( + absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - + attempt->duration_millis()); + attempt->set_error_stage(error_stage); + attempt->set_upgrade_result(result); + + auto operation_result_proto = + std::make_unique(); + operation_result_proto->set_result_code(operation_result_code); + operation_result_proto->set_result_category( + ConvertToOperationResultCategory(operation_result_code)); + attempt->set_allocated_operation_result(operation_result_proto.release()); + *current_strategy_session_->add_upgrade_attempt() = *attempt; + if (erase_item) { + bandwidth_upgrade_attempts_.erase(it); + } + } +} + +void AnalyticsRecorderImpl::FinishStrategySessionLocked() { + if (current_strategy_session_ != nullptr) { + FinishAdvertisingPhaseLocked(); + FinishDiscoveryPhaseLocked(); + + // Finish any unfinished LogicalConnections. + for (const auto& item : active_connections_) { + const std::unique_ptr& logical_connection = + item.second; + logical_connection->CloseAllPhysicalConnections(); + absl::c_copy( + logical_connection->GetEstablisedConnections(), + RepeatedFieldBackInserter( + current_strategy_session_->mutable_established_connection())); + } + active_connections_.clear(); + + // Finish any pending upgrade attempts. + for (const auto& item : bandwidth_upgrade_attempts_) { + FinishUpgradeAttemptLocked( + item.first, UNFINISHED_ERROR, UPGRADE_UNFINISHED, + OperationResultCode::DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS, + /*erase_item=*/false); + } + bandwidth_upgrade_attempts_.clear(); + + // Add the StrategySession in ClientSession + if (current_strategy_session_ != nullptr) { + current_strategy_session_->set_duration_millis(absl::ToInt64Milliseconds( + SystemClock::ElapsedRealtime() - started_strategy_session_time_)); + *client_session_->add_strategy_session() = + *std::move(current_strategy_session_); + } + + current_strategy_session_ = nullptr; + current_strategy_ = connections::Strategy::kNone; + LogEvent(STOP_STRATEGY_SESSION); + } +} + +ConnectionsStrategy AnalyticsRecorderImpl::StrategyToConnectionStrategy( + connections::Strategy strategy) { + if (strategy == connections::Strategy::kP2pCluster) { + return P2P_CLUSTER; + } + if (strategy == connections::Strategy::kP2pStar) { + return P2P_STAR; + } + if (strategy == connections::Strategy::kP2pPointToPoint) { + return P2P_POINT_TO_POINT; + } + return UNKNOWN_STRATEGY; +} + +PayloadType AnalyticsRecorderImpl::PayloadTypeToProtoPayloadType( + connections::PayloadType type) { + switch (type) { + case connections::PayloadType::kBytes: + return BYTES; + case connections::PayloadType::kFile: + return FILE; + case connections::PayloadType::kStream: + return STREAM; + default: + return UNKNOWN_PAYLOAD_TYPE; + } +} + +void AnalyticsRecorderImpl::PendingPayload::AddChunk( + std::int64_t chunk_size_bytes) { + num_bytes_transferred_ += chunk_size_bytes; + num_chunks_++; +} + +ConnectionsLog::Payload AnalyticsRecorderImpl::PendingPayload::GetProtoPayload( + PayloadStatus status) { + ConnectionsLog::Payload payload; + payload.set_duration_millis( + absl::ToInt64Milliseconds(SystemClock::ElapsedRealtime() - start_time_)); + payload.set_type(type_); + payload.set_total_size_bytes(total_size_bytes_); + payload.set_num_bytes_transferred(num_bytes_transferred_); + payload.set_num_chunks(num_chunks_); + payload.set_status(status); + + auto operation_result_proto = + std::make_unique(); + operation_result_proto->set_result_code(operation_result_code_); + operation_result_proto->set_result_category( + ConvertToOperationResultCategory(operation_result_code_)); + payload.set_allocated_operation_result(operation_result_proto.release()); + + return payload; +} + +void AnalyticsRecorderImpl::LogicalConnection::PhysicalConnectionEstablished( + Medium medium, const std::string& connection_token) { + if (current_medium_ != UNKNOWN_MEDIUM) { + LOG(WARNING) << "Unexpected call to PhysicalConnectionEstablished while " + "AnalyticsRecorderImpl still has an active current medium."; + } + + auto established_connection = + std::make_unique(); + established_connection->set_medium(medium); + established_connection->set_duration_millis( + absl::ToUnixMillis(SystemClock::ElapsedRealtime())); + established_connection->set_connection_token(connection_token); + + auto operation_result_proto = + std::make_unique(); + operation_result_proto->set_result_code(OperationResultCode::DETAIL_SUCCESS); + operation_result_proto->set_result_category( + OperationResultCategory::CATEGORY_SUCCESS); + established_connection->set_allocated_operation_result( + operation_result_proto.release()); + physical_connections_.insert({medium, std::move(established_connection)}); + current_medium_ = medium; +} + +void AnalyticsRecorderImpl::LogicalConnection::PhysicalConnectionClosed( + Medium medium, DisconnectionReason reason, SafeDisconnectionResult result) { + if (current_medium_ == UNKNOWN_MEDIUM) { + LOG(WARNING) << "Unexpected call to PhysicalConnectionClosed() for medium " + << Medium_Name(medium) + << " while AnalyticsRecorderImpl has no active current medium"; + } else if (current_medium_ != medium) { + LOG(WARNING) << "Unexpected call to PhysicalConnectionClosed() for medium " + << Medium_Name(medium) + << "while AnalyticsRecorderImpl has active medium " + << Medium_Name(current_medium_); + } + + auto it = physical_connections_.find(medium); + if (it == physical_connections_.end()) { + LOG(WARNING) + << "Unexpected call to physicalConnectionClosed() for medium " + << Medium_Name(medium) + << " with no corresponding EstablishedConnection that was previously" + " opened."; + return; + } + ConnectionsLog::EstablishedConnection* established_connection = + it->second.get(); + if (established_connection->has_disconnection_reason()) { + LOG(WARNING) << "Unexpected call to physicalConnectionClosed() for medium " + << Medium_Name(medium) + << " which already has disconnection reason " + << DisconnectionReason_Name( + established_connection->disconnection_reason()); + return; + } + FinishPhysicalConnection(established_connection, reason, result); + + if (medium == current_medium_) { + // If the EstablishedConnection we just closed was the one that we have + // marked as current, unset currentMedium. + current_medium_ = UNKNOWN_MEDIUM; + } +} + +void AnalyticsRecorderImpl::LogicalConnection::CloseAllPhysicalConnections() { + for (const auto& physical_connection : physical_connections_) { + ConnectionsLog::EstablishedConnection* established_connection = + physical_connection.second.get(); + if (!established_connection->has_disconnection_reason()) { + FinishPhysicalConnection(established_connection, UNFINISHED, + SafeDisconnectionResult::kSafeDisconnection); + } + } + current_medium_ = UNKNOWN_MEDIUM; +} + +std::vector +AnalyticsRecorderImpl::LogicalConnection::GetEstablisedConnections() { + std::vector established_connections; + if (current_medium_ != UNKNOWN_MEDIUM) { + LOG(WARNING) + << "AnalyticsRecorderImpl expected no more active physical connections " + "before logging this endpoint connection."; + return established_connections; + } + std::transform(physical_connections_.begin(), physical_connections_.end(), + std::back_inserter(established_connections), + [](auto& kv) { return *kv.second; }); + physical_connections_.clear(); + + for (auto& established_connection : established_connections) { + if (absl::Milliseconds(established_connection.duration_millis()) >= + kConnectionTokenMaxLife) { + LOG(INFO) << "connection token exceed TTL, drop token."; + established_connection.set_connection_token(""); + } + } + + return established_connections; +} + +void AnalyticsRecorderImpl::LogicalConnection::IncomingPayloadStarted( + std::int64_t payload_id, PayloadType type, std::int64_t total_size_bytes) { + incoming_payloads_.insert( + {payload_id, std::make_unique(type, total_size_bytes)}); +} + +void AnalyticsRecorderImpl::LogicalConnection::ChunkReceived( + std::int64_t payload_id, std::int64_t size_bytes) { + auto it = incoming_payloads_.find(payload_id); + if (it == incoming_payloads_.end()) { + return; + } + PendingPayload* pending_payload = it->second.get(); + pending_payload->AddChunk(size_bytes); +} + +void AnalyticsRecorderImpl::LogicalConnection::IncomingPayloadDone( + std::int64_t payload_id, PayloadStatus status, + OperationResultCode operation_result_code) { + if (current_medium_ == UNKNOWN_MEDIUM) { + LOG(WARNING) << "Unexpected call to incomingPayloadDone() while " + "AnalyticsRecorderImpl has no active current medium."; + return; + } + auto it = physical_connections_.find(current_medium_); + if (it != physical_connections_.end()) { + const std::unique_ptr& + established_connection = it->second; + auto it = incoming_payloads_.find(payload_id); + if (it != incoming_payloads_.end()) { + it->second->SetOperationResultCode(operation_result_code); + *established_connection->add_received_payload() = + it->second->GetProtoPayload(status); + incoming_payloads_.erase(it); + } + } +} + +void AnalyticsRecorderImpl::LogicalConnection::OutgoingPayloadStarted( + std::int64_t payload_id, PayloadType type, std::int64_t total_size_bytes) { + outgoing_payloads_.insert( + {payload_id, std::make_unique(type, total_size_bytes)}); +} + +void AnalyticsRecorderImpl::LogicalConnection::ChunkSent( + std::int64_t payload_id, std::int64_t size_bytes) { + auto it = outgoing_payloads_.find(payload_id); + if (it == outgoing_payloads_.end()) { + return; + } + PendingPayload* payload = it->second.get(); + payload->AddChunk(size_bytes); +} + +void AnalyticsRecorderImpl::LogicalConnection::OutgoingPayloadDone( + std::int64_t payload_id, PayloadStatus status, + OperationResultCode operation_result_code) { + if (current_medium_ == UNKNOWN_MEDIUM) { + LOG(WARNING) << "Unexpected call to outgoingPayloadDone() while " + "AnalyticsRecorderImpl has no active current medium."; + return; + } + auto it = physical_connections_.find(current_medium_); + if (it != physical_connections_.end()) { + const std::unique_ptr& + established_connection = it->second; + auto it = outgoing_payloads_.find(payload_id); + if (it != outgoing_payloads_.end()) { + it->second->SetOperationResultCode(operation_result_code); + *established_connection->add_sent_payload() = + it->second->GetProtoPayload(status); + outgoing_payloads_.erase(it); + } + } +} + +void AnalyticsRecorderImpl::LogicalConnection::FinishPhysicalConnection( + ConnectionsLog::EstablishedConnection* established_connection, + DisconnectionReason reason, SafeDisconnectionResult result) { + established_connection->set_disconnection_reason(reason); + established_connection->set_safe_disconnection_result( + ConvertToProtoSafeDisconnectionResult(result)); + established_connection->set_duration_millis( + absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - + established_connection->duration_millis()); + + // Add any not-yet-finished payloads to this EstablishedConnection. + std::vector in_payloads = + ResolvePendingPayloads(incoming_payloads_, reason); + absl::c_move(in_payloads, + RepeatedFieldBackInserter( + established_connection->mutable_received_payload())); + std::vector out_payloads = + ResolvePendingPayloads(outgoing_payloads_, reason); + absl::c_move(out_payloads, + RepeatedFieldBackInserter( + established_connection->mutable_sent_payload())); +} + +std::vector +AnalyticsRecorderImpl::LogicalConnection::ResolvePendingPayloads( + absl::btree_map>& + pending_payloads, + DisconnectionReason reason) { + std::vector completed_payloads; + absl::btree_map> + upgraded_payloads; + PayloadStatus status = + reason == UPGRADED ? MOVED_TO_NEW_MEDIUM : CONNECTION_CLOSED; + + OperationResultCode operation_result_code = + GetPendingPayloadResultCodeFromReason(reason); + for (const auto& item : pending_payloads) { + const std::unique_ptr& pending_payload = item.second; + pending_payload->SetOperationResultCode(operation_result_code); + ConnectionsLog::Payload proto_payload = + pending_payload->GetProtoPayload(status); + completed_payloads.push_back(proto_payload); + if (reason == UPGRADED) { + upgraded_payloads.insert( + {item.first, + std::make_unique(pending_payload->type(), + pending_payload->total_size_bytes(), + operation_result_code)}); + } + } + pending_payloads.clear(); + + if (reason == UPGRADED) { + // Re-populate the map with a new PendingPayload for each pending payload, + // since we expect them to be completed on the next EstablishedConnection. + pending_payloads = std::move(upgraded_payloads); + } + // Return the list of completed payloads to be added to the current + // EstablishedConnection. + return completed_payloads; +} + +OperationResultCode +AnalyticsRecorderImpl::LogicalConnection::GetPendingPayloadResultCodeFromReason( + DisconnectionReason reason) { + switch (reason) { + case UPGRADED: + return OperationResultCode::MISCELLEANEOUS_MOVE_TO_NEW_MEDIUM; + case DisconnectionReason::LOCAL_DISCONNECTION: + return OperationResultCode::CLIENT_CANCELLATION_LOCAL_DISCONNECT; + case DisconnectionReason::REMOTE_DISCONNECTION: + return OperationResultCode::CLIENT_CANCELLATION_REMOTE_DISCONNECT; + default: + return OperationResultCode::NEARBY_GENERIC_CONNECTION_CLOSED; + } +} + +OperationResultCategory AnalyticsRecorderImpl::GetOperationResultCategory( + location::nearby::proto::connections::OperationResultCode result_code) { + return ConvertToOperationResultCategory(result_code); +} + +void AnalyticsRecorderImpl::Sync() { MutexLock lock(&mutex_); } + +} // namespace nearby::analytics diff --git a/connections/implementation/analytics/analytics_recorder_impl.h b/connections/implementation/analytics/analytics_recorder_impl.h new file mode 100644 index 00000000..dfe0a342 --- /dev/null +++ b/connections/implementation/analytics/analytics_recorder_impl.h @@ -0,0 +1,459 @@ +// Copyright 2022-2023 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 ANALYTICS_ANALYTICS_RECORDER_IMPL_H_ +#define ANALYTICS_ANALYTICS_RECORDER_IMPL_H_ + +#include +#include +#include +#include +#include + +#include "absl/base/thread_annotations.h" +#include "absl/container/btree_map.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "connections/implementation/analytics/advertising_metadata_params.h" +#include "connections/implementation/analytics/analytics_recorder.h" +#include "connections/implementation/analytics/connection_attempt_metadata_params.h" +#include "connections/implementation/analytics/discovery_metadata_params.h" +#include "connections/payload_type.h" +#include "connections/strategy.h" +#include "internal/analytics/event_logger.h" +#include "internal/platform/error_code_params.h" +#include "internal/platform/implementation/system_clock.h" +#include "internal/platform/mutex.h" +#include "internal/proto/analytics/connections_log.pb.h" +#include "proto/connections_enums.pb.h" + +namespace nearby::analytics { + +class AnalyticsRecorderImpl : public AnalyticsRecorder { + public: + explicit AnalyticsRecorderImpl( + ::nearby::analytics::EventLogger* event_logger); + ~AnalyticsRecorderImpl() override; + + // Advertising phase + void OnStartAdvertising( + connections::Strategy strategy, + const std::vector& mediums, + AdvertisingMetadataParams* advertising_metadata_params) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnStopAdvertising() override ABSL_LOCKS_EXCLUDED(mutex_); + + int GetNextAdvertisingUpdateIndex() override ABSL_LOCKS_EXCLUDED(mutex_); + + // Connection listening + void OnStartedIncomingConnectionListening( + connections::Strategy strategy) override ABSL_LOCKS_EXCLUDED(mutex_); + void OnStoppedIncomingConnectionListening() override + ABSL_LOCKS_EXCLUDED(mutex_); + + // Discovery phase + void OnStartDiscovery( + connections::Strategy strategy, + const std::vector& mediums, + DiscoveryMetadataParams* discovery_metadata_params) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnStopDiscovery() override ABSL_LOCKS_EXCLUDED(mutex_); + + int GetNextDiscoveryUpdateIndex() override ABSL_LOCKS_EXCLUDED(mutex_); + void OnEndpointFound(location::nearby::proto::connections::Medium medium) + override ABSL_LOCKS_EXCLUDED(mutex_); + + // Connection request + void OnRequestConnection(const connections::Strategy& strategy, + const std::string& endpoint_id) override + ABSL_LOCKS_EXCLUDED(mutex_); + + void OnConnectionRequestReceived(const std::string& remote_endpoint_id) + override ABSL_LOCKS_EXCLUDED(mutex_); + void OnConnectionRequestSent(const std::string& remote_endpoint_id) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnRemoteEndpointAccepted(const std::string& remote_endpoint_id) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnLocalEndpointAccepted(const std::string& remote_endpoint_id) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnRemoteEndpointRejected(const std::string& remote_endpoint_id) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnLocalEndpointRejected(const std::string& remote_endpoint_id) override + ABSL_LOCKS_EXCLUDED(mutex_); + + // Connection attempt + void OnIncomingConnectionAttempt( + location::nearby::proto::connections::ConnectionAttemptType type, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::ConnectionAttemptResult result, + absl::Duration duration, const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) + override ABSL_LOCKS_EXCLUDED(mutex_); + void OnOutgoingConnectionAttempt( + const std::string& remote_endpoint_id, + location::nearby::proto::connections::ConnectionAttemptType type, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::ConnectionAttemptResult result, + absl::Duration duration, const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) + override ABSL_LOCKS_EXCLUDED(mutex_); + + // Connection established + void OnConnectionEstablished( + const std::string& endpoint_id, + location::nearby::proto::connections::Medium medium, + const std::string& connection_token) override ABSL_LOCKS_EXCLUDED(mutex_); + void OnConnectionClosed( + const std::string& endpoint_id, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::DisconnectionReason reason, + SafeDisconnectionResult result) override ABSL_LOCKS_EXCLUDED(mutex_); + + // Payload + void OnIncomingPayloadStarted(const std::string& endpoint_id, + std::int64_t payload_id, + connections::PayloadType type, + std::int64_t total_size_bytes) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnPayloadChunkReceived(const std::string& endpoint_id, + std::int64_t payload_id, + std::int64_t chunk_size_bytes) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnIncomingPayloadDone( + const std::string& endpoint_id, std::int64_t payload_id, + location::nearby::proto::connections::PayloadStatus status, + location::nearby::proto::connections::OperationResultCode + operation_result_code) override ABSL_LOCKS_EXCLUDED(mutex_); + void OnOutgoingPayloadStarted(const std::vector& endpoint_ids, + std::int64_t payload_id, + connections::PayloadType type, + std::int64_t total_size_bytes) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnPayloadChunkSent(const std::string& endpoint_id, + std::int64_t payload_id, + std::int64_t chunk_size_bytes) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnOutgoingPayloadDone( + const std::string& endpoint_id, std::int64_t payload_id, + location::nearby::proto::connections::PayloadStatus status, + location::nearby::proto::connections::OperationResultCode + operation_result_code) override ABSL_LOCKS_EXCLUDED(mutex_); + + // BandwidthUpgrade + void OnBandwidthUpgradeStarted( + const std::string& endpoint_id, + location::nearby::proto::connections::Medium from_medium, + location::nearby::proto::connections::Medium to_medium, + location::nearby::proto::connections::ConnectionAttemptDirection + direction, + const std::string& connection_token) override ABSL_LOCKS_EXCLUDED(mutex_); + void UpdateBwUpgradeNetworkInfo(const std::string& endpoint_id, + int num_interfaces, + int num_ipv6_only_interfaces) override + ABSL_LOCKS_EXCLUDED(mutex_); + void OnBandwidthUpgradeError( + const std::string& endpoint_id, + location::nearby::proto::connections::BandwidthUpgradeResult result, + location::nearby::proto::connections::BandwidthUpgradeErrorStage + error_stage, + location::nearby::proto::connections::OperationResultCode + operation_result_code) override ABSL_LOCKS_EXCLUDED(mutex_); + void OnBandwidthUpgradeSuccess(const std::string& endpoint_id) override + ABSL_LOCKS_EXCLUDED(mutex_); + + // Error Code + void OnErrorCode(const ErrorCodeParams& params) override; + + void LogStartSession() override ABSL_LOCKS_EXCLUDED(mutex_); + void LogSession() override ABSL_LOCKS_EXCLUDED(mutex_); + + bool IsSessionLogged() override; + + location::nearby::proto::connections::OperationResultCategory + GetOperationResultCategory( + location::nearby::proto::connections::OperationResultCode result_code) + override; + + void Sync() override; + + private: + // Tracks the chunks and duration of a Payload on a particular medium. + class PendingPayload { + public: + PendingPayload(location::nearby::proto::connections::PayloadType type, + std::int64_t total_size_bytes) + : PendingPayload(type, total_size_bytes, + location::nearby::proto::connections:: + OperationResultCode::DETAIL_UNKNOWN) {} + PendingPayload(location::nearby::proto::connections::PayloadType type, + std::int64_t total_size_bytes, + location::nearby::proto::connections::OperationResultCode + operation_result_code) + : start_time_(SystemClock::ElapsedRealtime()), + type_(type), + total_size_bytes_(total_size_bytes), + num_bytes_transferred_(0), + num_chunks_(0), + operation_result_code_(operation_result_code) {} + ~PendingPayload() = default; + + void AddChunk(std::int64_t chunk_size_bytes); + + location::nearby::analytics::proto::ConnectionsLog::Payload GetProtoPayload( + location::nearby::proto::connections::PayloadStatus status); + + location::nearby::proto::connections::PayloadType type() const { + return type_; + } + + std::int64_t total_size_bytes() const { return total_size_bytes_; } + + void SetOperationResultCode( + location::nearby::proto::connections::OperationResultCode + operation_result_code) { + operation_result_code_ = operation_result_code; + } + + private: + absl::Time start_time_; + location::nearby::proto::connections::PayloadType type_; + std::int64_t total_size_bytes_; + std::int64_t num_bytes_transferred_; + int num_chunks_; + location::nearby::proto::connections::OperationResultCode + operation_result_code_ = location::nearby::proto::connections:: + OperationResultCode::DETAIL_UNKNOWN; + }; + + class LogicalConnection { + public: + LogicalConnection( + location::nearby::proto::connections::Medium initial_medium, + const std::string& connection_token) { + PhysicalConnectionEstablished(initial_medium, connection_token); + } + LogicalConnection(const LogicalConnection&) = delete; + LogicalConnection(LogicalConnection&& other) + : current_medium_(std::move(other.current_medium_)), + physical_connections_(std::move(other.physical_connections_)), + incoming_payloads_(std::move(other.incoming_payloads_)), + outgoing_payloads_(std::move(other.outgoing_payloads_)) {} + LogicalConnection& operator=(const LogicalConnection&) = delete; + LogicalConnection&& operator=(LogicalConnection&&) = delete; + ~LogicalConnection() = default; + + void PhysicalConnectionEstablished( + location::nearby::proto::connections::Medium medium, + const std::string& connection_token); + void PhysicalConnectionClosed( + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::DisconnectionReason reason, + SafeDisconnectionResult result); + void CloseAllPhysicalConnections(); + + void IncomingPayloadStarted( + std::int64_t payload_id, + location::nearby::proto::connections::PayloadType type, + std::int64_t total_size_bytes); + void ChunkReceived(std::int64_t payload_id, std::int64_t size_bytes); + void IncomingPayloadDone( + std::int64_t payload_id, + location::nearby::proto::connections::PayloadStatus status, + location::nearby::proto::connections::OperationResultCode + operation_result_code); + void OutgoingPayloadStarted( + std::int64_t payload_id, + location::nearby::proto::connections::PayloadType type, + std::int64_t total_size_bytes); + void ChunkSent(std::int64_t payload_id, std::int64_t size_bytes); + void OutgoingPayloadDone( + std::int64_t payload_id, + location::nearby::proto::connections::PayloadStatus status, + location::nearby::proto::connections::OperationResultCode + operation_result_code); + + std::vector + GetEstablisedConnections(); + + private: + void FinishPhysicalConnection( + location::nearby::analytics::proto::ConnectionsLog:: + EstablishedConnection* established_connection, + location::nearby::proto::connections::DisconnectionReason reason, + SafeDisconnectionResult result); + std::vector + ResolvePendingPayloads( + absl::btree_map>& + pending_payloads, + location::nearby::proto::connections::DisconnectionReason reason); + location::nearby::proto::connections::OperationResultCode + GetPendingPayloadResultCodeFromReason( + location::nearby::proto::connections::DisconnectionReason reason); + + location::nearby::proto::connections::Medium current_medium_ = + location::nearby::proto::connections::UNKNOWN_MEDIUM; + absl::btree_map> + physical_connections_; + absl::btree_map> + incoming_payloads_; + absl::btree_map> + outgoing_payloads_; + }; + + bool CanRecordAnalyticsLocked(absl::string_view method_name) + ABSL_SHARED_LOCKS_REQUIRED(mutex_); + + // Callbacks the ConnectionsLog proto byte array data to the EventLogger with + // ClientSession sub-proto. + void LogClientSessionLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + // Callbacks the ConnectionsLog proto byte array data to the EventLogger. + void LogEvent(location::nearby::proto::connections::EventType event_type); + + void UpdateStrategySessionLocked( + connections::Strategy strategy, + location::nearby::proto::connections::SessionRole role) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + void RecordAdvertisingPhaseDurationAndReasonLocked(bool on_stop) const + ABSL_SHARED_LOCKS_REQUIRED(mutex_); + void FinishAdvertisingPhaseLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + void RecordDiscoveryPhaseDurationAndReasonLocked(bool on_stop) const + ABSL_SHARED_LOCKS_REQUIRED(mutex_); + void FinishDiscoveryPhaseLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + bool UpdateAdvertiserConnectionRequestLocked( + location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* + request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); + bool UpdateDiscovererConnectionRequestLocked( + location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* + request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); + bool BothEndpointsRespondedLocked( + location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* + request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); + void LocalEndpointRespondedLocked( + const std::string& remote_endpoint_id, + location::nearby::proto::connections::ConnectionRequestResponse response) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + void RemoteEndpointRespondedLocked( + const std::string& remote_endpoint_id, + location::nearby::proto::connections::ConnectionRequestResponse response) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + void MarkConnectionRequestIgnoredLocked( + location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* + request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); + void OnIncomingConnectionAttemptLocked( + location::nearby::proto::connections::ConnectionAttemptType type, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::ConnectionAttemptResult result, + absl::Duration duration, const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) + ABSL_SHARED_LOCKS_REQUIRED(mutex_); + void OnOutgoingConnectionAttemptLocked( + const std::string& remote_endpoint_id, + location::nearby::proto::connections::ConnectionAttemptType type, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::ConnectionAttemptResult result, + absl::Duration duration, const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) + ABSL_SHARED_LOCKS_REQUIRED(mutex_); + bool ConnectionAttemptResultCodeExistedLocked( + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::ConnectionAttemptDirection + direction, + const std::string& connection_token, + location::nearby::proto::connections::ConnectionAttemptType type, + location::nearby::proto::connections::OperationResultCode + operation_result_code) ABSL_SHARED_LOCKS_REQUIRED(mutex_); + bool EraseIfBandwidthUpgradeRecordExistedLocked( + const std::string& endpoint_id, + location::nearby::proto::connections::BandwidthUpgradeResult result, + location::nearby::proto::connections::BandwidthUpgradeErrorStage + error_stage, + location::nearby::proto::connections::OperationResultCode + operation_result_code) ABSL_SHARED_LOCKS_REQUIRED(mutex_); + void FinishUpgradeAttemptLocked( + const std::string& endpoint_id, + location::nearby::proto::connections::BandwidthUpgradeResult result, + location::nearby::proto::connections::BandwidthUpgradeErrorStage + error_stage, + location::nearby::proto::connections::OperationResultCode + operation_result_code, + bool erase_item = true) ABSL_SHARED_LOCKS_REQUIRED(mutex_); + void FinishStrategySessionLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + int GetLatestUpdateIndexLocked( + const std::vector& list) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + location::nearby::proto::connections::ConnectionsStrategy + StrategyToConnectionStrategy(connections::Strategy strategy); + location::nearby::proto::connections::PayloadType + PayloadTypeToProtoPayloadType(connections::PayloadType type); + + // Not owned by AnalyticsRecorderImpl. Pointer must refer to a valid object + // that outlives the one constructed. + ::nearby::analytics::EventLogger* event_logger_; + + // Protects all sub-protos reading and writing in ConnectionLog. + Mutex mutex_; + + // ClientSession + std::unique_ptr< + location::nearby::analytics::proto::ConnectionsLog::ClientSession> + client_session_; + absl::Time started_client_session_time_; + bool session_was_logged_ ABSL_GUARDED_BY(mutex_) = false; + bool start_client_session_was_logged_ ABSL_GUARDED_BY(mutex_) = false; + + // Current StrategySession + connections::Strategy current_strategy_ ABSL_GUARDED_BY(mutex_) = + connections::Strategy::kNone; + std::unique_ptr< + location::nearby::analytics::proto::ConnectionsLog::StrategySession> + current_strategy_session_ ABSL_GUARDED_BY(mutex_); + absl::Time started_strategy_session_time_ ABSL_GUARDED_BY(mutex_); + + // Current AdvertisingPhase + std::unique_ptr< + location::nearby::analytics::proto::ConnectionsLog::AdvertisingPhase> + current_advertising_phase_; + absl::Time started_advertising_phase_time_ = absl::InfinitePast(); + + // Current DiscoveryPhase + std::unique_ptr< + location::nearby::analytics::proto::ConnectionsLog::DiscoveryPhase> + current_discovery_phase_; + absl::Time started_discovery_phase_time_ = absl::InfinitePast(); + + absl::btree_map> + incoming_connection_requests_ ABSL_GUARDED_BY(mutex_); + absl::btree_map> + outgoing_connection_requests_ ABSL_GUARDED_BY(mutex_); + absl::btree_map> + active_connections_ ABSL_GUARDED_BY(mutex_); + absl::btree_map> + bandwidth_upgrade_attempts_ ABSL_GUARDED_BY(mutex_); +}; + +} // namespace nearby::analytics + +#endif // ANALYTICS_ANALYTICS_RECORDER_IMPL_H_ diff --git a/connections/implementation/analytics/analytics_recorder_test.cc b/connections/implementation/analytics/analytics_recorder_impl_test.cc similarity index 97% rename from connections/implementation/analytics/analytics_recorder_test.cc rename to connections/implementation/analytics/analytics_recorder_impl_test.cc index 5b46b4ea..53bf6afe 100644 --- a/connections/implementation/analytics/analytics_recorder_test.cc +++ b/connections/implementation/analytics/analytics_recorder_impl_test.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "connections/implementation/analytics/analytics_recorder.h" +#include "connections/implementation/analytics/analytics_recorder_impl.h" #include @@ -26,7 +26,9 @@ #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/time/time.h" +#include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/analytics/connection_attempt_metadata_params.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" #include "connections/payload_type.h" #include "connections/strategy.h" #include "internal/analytics/mock_event_logger.h" @@ -36,14 +38,13 @@ #include "internal/platform/exception.h" #include "internal/platform/medium_environment.h" #include "internal/proto/analytics/connections_log.proto.h" -#include "internal/test/fake_clock.h" #include "proto/connections_enums.proto.h" -namespace nearby { -namespace analytics { +namespace nearby::analytics { namespace { using ::location::nearby::analytics::proto::ConnectionsLog; +using SafeDisconnectionResult = nearby::analytics::SafeDisconnectionResult; using ::location::nearby::errorcode::proto::DISCONNECT; using ::location::nearby::errorcode::proto::DISCONNECT_NETWORK_FAILED; using ::location::nearby::errorcode::proto::INVALID_PARAMETER; @@ -158,7 +159,7 @@ class AnalyticsRecorderTest : public ::testing::Test { TEST_F(AnalyticsRecorderTest, SessionOnlyLoggedOnceWorks) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); analytics_recorder.LogSession(); analytics_recorder.LogSession(); @@ -175,9 +176,9 @@ TEST_F(AnalyticsRecorderTest, SetFieldsCorrectlyForNestedAdvertisingCalls) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); - ConnectionsLog::OperationResultWithMedium operation_result; + OperationResultWithMedium operation_result; operation_result.set_medium(BLUETOOTH); operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); operation_result.set_result_category( @@ -251,14 +252,14 @@ TEST_F(AnalyticsRecorderTest, SetFieldsCorrectlyForNestedDiscoveryCalls) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); - ConnectionsLog::OperationResultWithMedium operation_result; + OperationResultWithMedium operation_result; operation_result.set_medium(BLUETOOTH); operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); operation_result.set_result_category( OperationResultCategory::CATEGORY_SUCCESS); - ConnectionsLog::OperationResultWithMedium operation_result2; + OperationResultWithMedium operation_result2; operation_result2.set_medium(BLE); operation_result2.set_result_code(OperationResultCode::DETAIL_SUCCESS); operation_result2.set_result_category( @@ -350,7 +351,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); @@ -482,9 +483,9 @@ TEST_F(AnalyticsRecorderTest, AdvertiserConnectionRequestsWorks) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); - ConnectionsLog::OperationResultWithMedium operation_result; + OperationResultWithMedium operation_result; operation_result.set_medium(BLE); operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); operation_result.set_result_category( @@ -586,9 +587,9 @@ TEST_F(AnalyticsRecorderTest, DiscoveryConnectionRequestsWorks) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); - ConnectionsLog::OperationResultWithMedium operation_result; + OperationResultWithMedium operation_result; operation_result.set_medium(BLUETOOTH); operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); operation_result.set_result_category( @@ -691,9 +692,9 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); - ConnectionsLog::OperationResultWithMedium operation_result; + OperationResultWithMedium operation_result; operation_result.set_medium(BLUETOOTH); operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); operation_result.set_result_category( @@ -781,9 +782,9 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); - ConnectionsLog::OperationResultWithMedium operation_result; + OperationResultWithMedium operation_result; operation_result.set_medium(BLUETOOTH); operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); operation_result.set_result_category( @@ -866,9 +867,9 @@ TEST_F(AnalyticsRecorderTest, TEST_F(AnalyticsRecorderTest, SuccessfulIncomingConnectionAttempt) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); - ConnectionsLog::OperationResultWithMedium operation_result; + OperationResultWithMedium operation_result; operation_result.set_medium(BLUETOOTH); operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); operation_result.set_result_category( @@ -957,7 +958,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto connections_attempt_metadata_params = analytics_recorder.BuildConnectionAttemptMetadataParams( @@ -1049,7 +1050,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); @@ -1061,9 +1062,8 @@ TEST_F(AnalyticsRecorderTest, analytics_recorder.OnConnectionEstablished(endpoint_id, BLUETOOTH, connection_token); MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnConnectionClosed( - endpoint_id, BLUETOOTH, UPGRADED, - ConnectionsLog::EstablishedConnection::UNKNOWN_SAFE_DISCONNECTION_RESULT); + analytics_recorder.OnConnectionClosed(endpoint_id, BLUETOOTH, UPGRADED, + SafeDisconnectionResult::kUnknown); MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); analytics_recorder.OnConnectionEstablished(endpoint_id, WIFI_LAN, connection_token); @@ -1125,7 +1125,7 @@ TEST_F(AnalyticsRecorderTest, OutgoingPayloadUpgraded) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); @@ -1146,7 +1146,7 @@ TEST_F(AnalyticsRecorderTest, OutgoingPayloadUpgraded) { MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.OnConnectionClosed( endpoint_id, BLUETOOTH, UPGRADED, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + SafeDisconnectionResult::kSafeDisconnection); MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); analytics_recorder.OnConnectionEstablished(endpoint_id, WIFI_LAN, connection_token); @@ -1162,7 +1162,7 @@ TEST_F(AnalyticsRecorderTest, OutgoingPayloadUpgraded) { MediumEnvironment::Instance().FastForward(absl::Milliseconds(1200)); analytics_recorder.OnConnectionClosed( endpoint_id, WIFI_LAN, LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + SafeDisconnectionResult::kSafeDisconnection); MediumEnvironment::Instance().FastForward(absl::Milliseconds(1300)); analytics_recorder.LogSession(); @@ -1246,7 +1246,7 @@ TEST_F(AnalyticsRecorderTest, UpgradeAttemptWorks) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); @@ -1350,7 +1350,7 @@ TEST_F(AnalyticsRecorderTest, StartListeningForIncomingConnectionsWorks) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); analytics_recorder.OnStartedIncomingConnectionListening( @@ -1418,7 +1418,7 @@ TEST_F(AnalyticsRecorderTest, StartListeningForIncomingConnectionsWorks) { TEST_F(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectly) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); @@ -1452,7 +1452,7 @@ TEST_F(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectlyForUnknownDescription) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); @@ -1488,7 +1488,7 @@ TEST_F(AnalyticsRecorderTest, TEST_F(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectlyForCommonError) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); @@ -1521,7 +1521,7 @@ TEST_F(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectlyForCommonError) { TEST_F(AnalyticsRecorderTest, CheckIfSessionWasLogged) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); // LogSession to count down client_session_done_latch. @@ -1538,7 +1538,7 @@ TEST_F(AnalyticsRecorderTest, ConstructAnalyticsRecorder) { &start_client_session_done_latch); // Call the constructor to count down the session_done_latch. - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); ASSERT_TRUE(start_client_session_done_latch.Await(kDefaultTimeout).result()); std::vector event_types = event_logger.GetLoggedEventTypes(); @@ -1555,7 +1555,7 @@ TEST_F( &start_client_session_done_latch); // Call the constructor to count down the start_client_session_done_latch. - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); ASSERT_TRUE(start_client_session_done_latch.Await(kDefaultTimeout).result()); // Log start client session once. @@ -1584,7 +1584,7 @@ TEST_F(AnalyticsRecorderTest, &start_client_session_done_latch); // Call the constructor to count down the start_client_session_done_latch. - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); ASSERT_TRUE(start_client_session_done_latch.Await(kDefaultTimeout).result()); // Log start client session once. @@ -1621,7 +1621,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); @@ -1753,7 +1753,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams(); @@ -1887,7 +1887,7 @@ TEST_F(AnalyticsRecorderTest, ClearcActiveConnectionsAfterSessionWasLogged) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); @@ -2010,7 +2010,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); @@ -2202,7 +2202,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); @@ -2256,7 +2256,7 @@ TEST_F(AnalyticsRecorderTest, NotLogSameStrategySessionProtoAfterSessionWasLogged) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); // Via OnStartAdvertising, current_strategy_session_is set in // UpdateStrategySessionLocked. @@ -2323,7 +2323,7 @@ TEST_F(AnalyticsRecorderTest, NotLogDuplicateAdvertisingPhaseAfterSessionWasLogged) { CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto advertising_metadata_params = analytics_recorder.BuildAdvertisingMetadataParams(); @@ -2418,7 +2418,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); auto discovery_metadata_params = analytics_recorder.BuildDiscoveryMetadataParams( @@ -2517,7 +2517,7 @@ TEST_F(AnalyticsRecorderTest, CountDownLatch client_session_done_latch(1); FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorder analytics_recorder(&event_logger); + AnalyticsRecorderImpl analytics_recorder(&event_logger); // via OnStartAdvertising, current_strategy_session_ is set in // UpdateStrategySessionLocked. @@ -2566,7 +2566,7 @@ TEST_F(AnalyticsRecorderTest, MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); analytics_recorder.OnConnectionClosed( endpoint_id, BLUETOOTH, UPGRADED, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + SafeDisconnectionResult::kSafeDisconnection); MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); analytics_recorder.LogSession(); @@ -2576,5 +2576,4 @@ TEST_F(AnalyticsRecorderTest, } } // namespace -} // namespace analytics -} // namespace nearby +} // namespace nearby::analytics diff --git a/connections/implementation/analytics/discovery_metadata_params.h b/connections/implementation/analytics/discovery_metadata_params.h index 6442b03c..b90b2703 100644 --- a/connections/implementation/analytics/discovery_metadata_params.h +++ b/connections/implementation/analytics/discovery_metadata_params.h @@ -17,7 +17,7 @@ #include -#include "internal/proto/analytics/connections_log.pb.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" namespace nearby { @@ -26,8 +26,7 @@ struct DiscoveryMetadataParams { bool is_extended_advertisement_supported = false; int connected_ap_frequency = 0; bool is_nfc_available = false; - std::vector + std::vector operation_result_with_mediums = {}; }; diff --git a/connections/implementation/analytics/operation_result_with_medium.h b/connections/implementation/analytics/operation_result_with_medium.h new file mode 100644 index 00000000..483acc14 --- /dev/null +++ b/connections/implementation/analytics/operation_result_with_medium.h @@ -0,0 +1,55 @@ +// Copyright 2026 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 ANALYTICS_OPERATION_RESULT_WITH_MEDIUM_H_ +#define ANALYTICS_OPERATION_RESULT_WITH_MEDIUM_H_ + +#include + +#include "proto/connections_enums.pb.h" + +namespace nearby::analytics { + +struct OperationResultWithMedium { + location::nearby::proto::connections::Medium medium = + location::nearby::proto::connections::UNKNOWN_MEDIUM; + std::optional update_index; + location::nearby::proto::connections::OperationResultCategory + result_category = location::nearby::proto::connections::CATEGORY_UNKNOWN; + location::nearby::proto::connections::OperationResultCode result_code = + location::nearby::proto::connections::DETAIL_UNKNOWN; + std::optional + connection_mode; + + void set_medium(location::nearby::proto::connections::Medium m) { + medium = m; + } + void set_update_index(int i) { update_index = i; } + void set_result_category( + location::nearby::proto::connections::OperationResultCategory c) { + result_category = c; + } + void set_result_code( + location::nearby::proto::connections::OperationResultCode c) { + result_code = c; + } + void set_connection_mode( + location::nearby::proto::connections::ConnectionMode m) { + connection_mode = m; + } +}; + +} // namespace nearby::analytics + +#endif // ANALYTICS_OPERATION_RESULT_WITH_MEDIUM_H_ diff --git a/connections/implementation/base_endpoint_channel.cc b/connections/implementation/base_endpoint_channel.cc index 16baec65..79ba0de0 100644 --- a/connections/implementation/base_endpoint_channel.cc +++ b/connections/implementation/base_endpoint_channel.cc @@ -40,15 +40,13 @@ #include "internal/platform/mutex_lock.h" #include "internal/platform/output_stream.h" -namespace nearby { -namespace connections { +namespace nearby::connections { namespace { -using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::proto::connections::Medium::BLE; using ::location::nearby::proto::connections::Medium::BLE_L2CAP; -using DisconnectionReason = - ::location::nearby::proto::connections::DisconnectionReason; +using ::nearby::analytics::SafeDisconnectionResult; +using ::location::nearby::proto::connections::DisconnectionReason; Exception WriteInt(OutputStream* writer, std::int32_t value) { return Base64Utils::WriteInt(writer, value); @@ -304,7 +302,7 @@ void BaseEndpointChannel::SetAnalyticsRecorder( void BaseEndpointChannel::Close( location::nearby::proto::connections::DisconnectionReason reason) { - Close(reason, ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + Close(reason, SafeDisconnectionResult::kSafeDisconnection); } void BaseEndpointChannel::Close( @@ -468,5 +466,4 @@ std::unique_ptr BaseEndpointChannel::EncodeMessageForTests( return crypto_context_->EncodeMessageToPeer(data); } -} // namespace connections -} // namespace nearby +} // namespace nearby::connections diff --git a/connections/implementation/base_endpoint_channel.h b/connections/implementation/base_endpoint_channel.h index c426c118..421a8a9f 100644 --- a/connections/implementation/base_endpoint_channel.h +++ b/connections/implementation/base_endpoint_channel.h @@ -31,8 +31,7 @@ #include "internal/platform/mutex.h" #include "internal/platform/output_stream.h" -namespace nearby { -namespace connections { +namespace nearby::connections { class BaseEndpointChannel : public EndpointChannel { public: @@ -56,10 +55,8 @@ class BaseEndpointChannel : public EndpointChannel { void Close() ABSL_LOCKS_EXCLUDED(is_paused_mutex_) override; void Close(location::nearby::proto::connections::DisconnectionReason reason) override; - void Close( - location::nearby::proto::connections::DisconnectionReason reason, - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection::SafeDisconnectionResult result) override; + void Close(location::nearby::proto::connections::DisconnectionReason reason, + nearby::analytics::SafeDisconnectionResult result) override; bool IsClosed() const ABSL_LOCKS_EXCLUDED(is_paused_mutex_) override; std::string GetType() const override; std::string GetServiceId() const override; @@ -171,7 +168,6 @@ class BaseEndpointChannel : public EndpointChannel { std::string endpoint_id_ = ""; }; -} // namespace connections -} // namespace nearby +} // namespace nearby::connections #endif // CORE_INTERNAL_BASE_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 59418df5..85a82eae 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -36,7 +36,9 @@ #include "connections/advertising_options.h" #include "connections/connection_options.h" #include "connections/discovery_options.h" +#include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/analytics/connection_attempt_metadata_params.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" #include "connections/implementation/bwu_manager.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/connections_authentication_transport.h" @@ -89,6 +91,20 @@ namespace nearby::connections { namespace { +using ::location::nearby::analytics::proto::ConnectionsLog; +using ::location::nearby::connections::ConnectionRequestFrame; +using ::location::nearby::connections::ConnectionResponseFrame; +using ::location::nearby::connections::ConnectionsDevice; +using ::location::nearby::connections::MediumMetadata; +using ::location::nearby::connections::OfflineFrame; +using ::location::nearby::connections::OsInfo; +using ::location::nearby::connections::PresenceDevice; +using ::location::nearby::connections::V1Frame; +using ::location::nearby::proto::connections::OperationResultCode; +using ::location::nearby::proto::connections::WifiDirectAuthType; +using ::nearby::analytics::AnalyticsRecorder; +using ::securegcm::UKey2Handshake; + constexpr int kEndpointCancelAlarmTimeout = 10; std::string AuthenticationStatusToString(nearby::AuthenticationStatus status) { @@ -101,20 +117,30 @@ std::string AuthenticationStatusToString(nearby::AuthenticationStatus status) { return "failure"; } } -} // namespace -using ::location::nearby::analytics::proto::ConnectionsLog; -using ::location::nearby::connections::ConnectionRequestFrame; -using ::location::nearby::connections::ConnectionResponseFrame; -using ::location::nearby::connections::ConnectionsDevice; -using ::location::nearby::connections::MediumMetadata; -using ::location::nearby::connections::OfflineFrame; -using ::location::nearby::connections::OsInfo; -using ::location::nearby::connections::PresenceDevice; -using ::location::nearby::connections::V1Frame; -using ::location::nearby::proto::connections::OperationResultCode; -using ::location::nearby::proto::connections::WifiDirectAuthType; -using ::securegcm::UKey2Handshake; +std::vector +ConvertToCppOperationResultWithMediums( + const std::vector& + proto_results) { + std::vector cpp_results; + cpp_results.reserve(proto_results.size()); + for (const auto& proto_result : proto_results) { + analytics::OperationResultWithMedium cpp_result; + cpp_result.medium = proto_result.medium(); + if (proto_result.has_update_index()) { + cpp_result.update_index = proto_result.update_index(); + } + cpp_result.result_category = proto_result.result_category(); + cpp_result.result_code = proto_result.result_code(); + if (proto_result.has_connection_mode()) { + cpp_result.connection_mode = proto_result.connection_mode(); + } + cpp_results.push_back(cpp_result); + } + return cpp_results; +} + +} // namespace BasePcpHandler::BasePcpHandler(Mediums* mediums, EndpointManager* endpoint_manager, @@ -278,11 +304,11 @@ Status BasePcpHandler::StartAdvertising( // Save the advertising options for local reference in later process // like upgrading bandwidth. advertising_listener_ = info.listener; - client->StartedAdvertising( - service_id, GetStrategy(), info.listener, - absl::MakeSpan(result.mediums), - std::move(result.operation_result_with_mediums), - compatible_advertising_options); + client->StartedAdvertising(service_id, GetStrategy(), info.listener, + absl::MakeSpan(result.mediums), + ConvertToCppOperationResultWithMediums( + result.operation_result_with_mediums), + compatible_advertising_options); client->UpdateLocalEndpointInfo(info.endpoint_info.string_data()); response.Set({Status::kSuccess}); }); @@ -509,11 +535,12 @@ Status BasePcpHandler::StartDiscovery(ClientProxy* client, MutexLock lock(&discovered_endpoint_mutex_); discovered_endpoints_.clear(); } - client->StartedDiscovery( - service_id, GetStrategy(), std::move(listener), - absl::MakeSpan(result.mediums), - std::move(result.operation_result_with_mediums), - stripped_discovery_options); + client->StartedDiscovery(service_id, GetStrategy(), + std::move(listener), + absl::MakeSpan(result.mediums), + ConvertToCppOperationResultWithMediums( + result.operation_result_with_mediums), + stripped_discovery_options); response.Set({Status::kSuccess}); }); return WaitForResult(absl::StrCat("StartDiscovery(", service_id, ")"), @@ -1011,8 +1038,8 @@ Status BasePcpHandler::RequestConnection( client, channel_medium, endpoint_id, channel.get(), /*is_incoming=*/false, /*log_failure=*/true, start_time, {Status::kEndpointIoError}, - client->GetAnalyticsRecorder() - .GetChannelIoErrorResultCodeFromMedium(channel_medium), + AnalyticsRecorder::GetChannelIoErrorResultCodeFromMedium( + channel_medium), result.get()); return; } @@ -1173,8 +1200,8 @@ Status BasePcpHandler::RequestConnectionV3( client, channel_medium, endpoint_id, channel.get(), /*is_incoming=*/false, /*log_failure=*/true, start_time, {Status::kEndpointIoError}, - client->GetAnalyticsRecorder() - .GetChannelIoErrorResultCodeFromMedium(channel_medium), + AnalyticsRecorder::GetChannelIoErrorResultCodeFromMedium( + channel_medium), result.get()); return; } @@ -2032,8 +2059,7 @@ Exception BasePcpHandler::OnIncomingConnection( /*is_incoming=*/true, /*log_failure=*/wrapped_frame.exception() != Exception::kNoData, start_time, {Status::kError}, - client->GetAnalyticsRecorder().GetChannelIoErrorResultCodeFromMedium( - medium), + AnalyticsRecorder::GetChannelIoErrorResultCodeFromMedium(medium), nullptr); } return wrapped_frame.GetException(); @@ -2584,7 +2610,7 @@ void BasePcpHandler::LogConnectionAttemptFailure( connections_attempt_metadata_params; if (endpoint_channel != nullptr) { connections_attempt_metadata_params = - client->GetAnalyticsRecorder().BuildConnectionAttemptMetadataParams( + AnalyticsRecorder::BuildConnectionAttemptMetadataParams( endpoint_channel->GetTechnology(), endpoint_channel->GetBand(), endpoint_channel->GetFrequency(), endpoint_channel->GetTryCount()); connections_attempt_metadata_params->operation_result_code = @@ -2610,12 +2636,11 @@ void BasePcpHandler::LogConnectionAttemptSuccess( connections_attempt_metadata_params; if (pending_connection_info.channel != nullptr) { connections_attempt_metadata_params = - pending_connection_info.client->GetAnalyticsRecorder() - .BuildConnectionAttemptMetadataParams( - pending_connection_info.channel->GetTechnology(), - pending_connection_info.channel->GetBand(), - pending_connection_info.channel->GetFrequency(), - pending_connection_info.channel->GetTryCount()); + AnalyticsRecorder::BuildConnectionAttemptMetadataParams( + pending_connection_info.channel->GetTechnology(), + pending_connection_info.channel->GetBand(), + pending_connection_info.channel->GetFrequency(), + pending_connection_info.channel->GetTryCount()); connections_attempt_metadata_params->operation_result_code = OperationResultCode::DETAIL_SUCCESS; } else { diff --git a/connections/implementation/bwu_manager.cc b/connections/implementation/bwu_manager.cc index 48a70718..76b93cc6 100644 --- a/connections/implementation/bwu_manager.cc +++ b/connections/implementation/bwu_manager.cc @@ -25,6 +25,7 @@ #include "absl/functional/bind_front.h" #include "absl/strings/str_cat.h" #include "absl/time/time.h" +#include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/analytics/connection_attempt_metadata_params.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" @@ -61,6 +62,8 @@ using ::location::nearby::proto::connections::ConnectionAttemptResult; using ::location::nearby::proto::connections::ConnectionAttemptType; using ::location::nearby::proto::connections::DisconnectionReason; using ::location::nearby::proto::connections::OperationResultCode; +using ::nearby::analytics::AnalyticsRecorder; + } // namespace BwuManager::BwuManager( @@ -663,7 +666,7 @@ void BwuManager::OnIncomingConnection( connections_attempt_metadata_params; if (channel != nullptr) { connections_attempt_metadata_params = - client->GetAnalyticsRecorder().BuildConnectionAttemptMetadataParams( + AnalyticsRecorder::BuildConnectionAttemptMetadataParams( channel->GetTechnology(), channel->GetBand(), channel->GetFrequency(), channel->GetTryCount()); connections_attempt_metadata_params->operation_result_code = @@ -874,7 +877,7 @@ void BwuManager::ProcessBwuPathAvailableEvent( if (channel != nullptr) { std::unique_ptr connections_attempt_metadata_params = - client->GetAnalyticsRecorder().BuildConnectionAttemptMetadataParams( + AnalyticsRecorder::BuildConnectionAttemptMetadataParams( channel->GetTechnology(), channel->GetBand(), channel->GetFrequency(), channel->GetTryCount()); connections_attempt_metadata_params->operation_result_code = diff --git a/connections/implementation/bwu_manager_test.cc b/connections/implementation/bwu_manager_test.cc index 6a6495c5..dd858901 100644 --- a/connections/implementation/bwu_manager_test.cc +++ b/connections/implementation/bwu_manager_test.cc @@ -22,6 +22,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" #include "connections/connection_options.h" +#include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" @@ -41,19 +42,17 @@ #include "internal/platform/exception.h" #include "internal/platform/feature_flags.h" #include "internal/platform/service_address.h" -#include "internal/proto/analytics/connections_log.pb.h" #include "proto/connections_enums.pb.h" -namespace nearby { -namespace connections { +namespace nearby::connections { namespace { -using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::connections::BandwidthUpgradeNegotiationFrame; using ::location::nearby::connections::MediumRole; using ::location::nearby::connections::OfflineFrame; using ::location::nearby::connections::OsInfo; using ::location::nearby::connections::V1Frame; using ::location::nearby::proto::connections::DisconnectionReason; +using ::nearby::analytics::SafeDisconnectionResult; constexpr absl::string_view kServiceIdA = "ServiceA"; constexpr absl::string_view kServiceIdB = "ServiceB"; @@ -148,7 +147,7 @@ class BwuManagerTest : public ::testing::Test { void UnRegisterChannelForEndpoint(absl::string_view endpoint_id) { ecm_.UnregisterChannelForEndpoint( std::string(endpoint_id), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + SafeDisconnectionResult::kSafeDisconnection); } // Upgrade from |initial_medium| to |upgrade_medium|, close down the BLUETOOTH @@ -232,9 +231,9 @@ TEST(BwuManagerBaseTest, AllowToUpgradeMedium) { bwu_manager->InitiateBwuForEndpoint(&client, std::string(kEndpointId1), Medium::WIFI_LAN); EXPECT_TRUE(bwu_manager->IsUpgradeOngoing(std::string(kEndpointId1))); - ecm.UnregisterChannelForEndpoint( - std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + ecm.UnregisterChannelForEndpoint(std::string(kEndpointId1), + DisconnectionReason::LOCAL_DISCONNECTION, + SafeDisconnectionResult::kSafeDisconnection); auto channel2 = std::make_unique( Medium::BLUETOOTH, std::string(kServiceIdA)); @@ -243,9 +242,9 @@ TEST(BwuManagerBaseTest, AllowToUpgradeMedium) { bwu_manager->InitiateBwuForEndpoint(&client, std::string(kEndpointId2), Medium::WIFI_HOTSPOT); EXPECT_TRUE(bwu_manager->IsUpgradeOngoing(std::string(kEndpointId2))); - ecm.UnregisterChannelForEndpoint( - std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + ecm.UnregisterChannelForEndpoint(std::string(kEndpointId2), + DisconnectionReason::LOCAL_DISCONNECTION, + SafeDisconnectionResult::kSafeDisconnection); auto channel3 = std::make_unique( Medium::BLUETOOTH, std::string(kServiceIdA)); @@ -254,9 +253,9 @@ TEST(BwuManagerBaseTest, AllowToUpgradeMedium) { bwu_manager->InitiateBwuForEndpoint(&client, std::string(kEndpointId3), Medium::WIFI_DIRECT); EXPECT_TRUE(bwu_manager->IsUpgradeOngoing(std::string(kEndpointId3))); - ecm.UnregisterChannelForEndpoint( - std::string(kEndpointId3), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + ecm.UnregisterChannelForEndpoint(std::string(kEndpointId3), + DisconnectionReason::LOCAL_DISCONNECTION, + SafeDisconnectionResult::kSafeDisconnection); auto channel4 = std::make_unique( Medium::WEB_RTC, std::string(kServiceIdA)); @@ -265,9 +264,9 @@ TEST(BwuManagerBaseTest, AllowToUpgradeMedium) { bwu_manager->InitiateBwuForEndpoint(&client, std::string(kEndpointId4), Medium::BLUETOOTH); EXPECT_FALSE(bwu_manager->IsUpgradeOngoing(std::string(kEndpointId4))); - ecm.UnregisterChannelForEndpoint( - std::string(kEndpointId4), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + ecm.UnregisterChannelForEndpoint(std::string(kEndpointId4), + DisconnectionReason::LOCAL_DISCONNECTION, + SafeDisconnectionResult::kSafeDisconnection); bwu_manager->Shutdown(); } @@ -307,9 +306,9 @@ TEST(BwuManagerBaseTest, InitiateBwu_NeedToSwitchRole_Success) { Medium::WIFI_HOTSPOT); EXPECT_FALSE(bwu_manager->IsUpgradeOngoing(std::string(kEndpointId1))); - ecm.UnregisterChannelForEndpoint( - std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + ecm.UnregisterChannelForEndpoint(std::string(kEndpointId1), + DisconnectionReason::LOCAL_DISCONNECTION, + SafeDisconnectionResult::kSafeDisconnection); bwu_manager->Shutdown(); NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature:: @@ -500,7 +499,7 @@ TEST_F(BwuManagerTest, CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id, std::string(kEndpointId1), latch, DisconnectionReason::LOCAL_DISCONNECTION); @@ -514,7 +513,7 @@ TEST_F(BwuManagerTest, CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id, std::string(kEndpointId2), latch, DisconnectionReason::LOCAL_DISCONNECTION); @@ -548,7 +547,7 @@ TEST_F(BwuManagerTest, CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id, std::string(kEndpointId1), latch, DisconnectionReason::LOCAL_DISCONNECTION); @@ -568,7 +567,7 @@ TEST_F(BwuManagerTest, CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id, std::string(kEndpointId2), latch, DisconnectionReason::LOCAL_DISCONNECTION); @@ -605,7 +604,7 @@ TEST_F(BwuManagerTest, EXPECT_EQ(2u, ecm_.GetConnectedEndpointsCount()); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); EXPECT_EQ(1u, ecm_.GetConnectedEndpointsCount()); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id_A, std::string(kEndpointId1), latch, @@ -625,7 +624,7 @@ TEST_F(BwuManagerTest, CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); EXPECT_EQ(0u, ecm_.GetConnectedEndpointsCount()); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id_B, std::string(kEndpointId2), latch, @@ -659,7 +658,7 @@ TEST_F(BwuManagerTest, EXPECT_EQ(2u, ecm_.GetConnectedEndpointsCount()); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); EXPECT_EQ(1u, ecm_.GetConnectedEndpointsCount()); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id_A, std::string(kEndpointId1), latch, @@ -679,7 +678,7 @@ TEST_F(BwuManagerTest, CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); EXPECT_EQ(0u, ecm_.GetConnectedEndpointsCount()); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id_B, std::string(kEndpointId2), latch, @@ -735,7 +734,7 @@ TEST_F( CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id_A, std::string(kEndpointId1), latch, DisconnectionReason::LOCAL_DISCONNECTION); @@ -760,7 +759,7 @@ TEST_F( CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id_A, std::string(kEndpointId2), latch, DisconnectionReason::LOCAL_DISCONNECTION); @@ -781,7 +780,7 @@ TEST_F( CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId3), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id_B, std::string(kEndpointId3), latch, DisconnectionReason::LOCAL_DISCONNECTION); @@ -802,7 +801,7 @@ TEST_F( CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId4), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id_B, std::string(kEndpointId4), latch, DisconnectionReason::LOCAL_DISCONNECTION); @@ -825,7 +824,7 @@ TEST_F( CountDownLatch latch(1); ecm_.UnregisterChannelForEndpoint( std::string(kEndpointId5), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION); + SafeDisconnectionResult::kUnsafeDisconnection); bwu_manager_->OnEndpointDisconnect( &client_, upgrade_service_id_B, std::string(kEndpointId5), latch, DisconnectionReason::LOCAL_DISCONNECTION); @@ -1094,5 +1093,4 @@ INSTANTIATE_TEST_SUITE_P(BwuManagerTestParam, BwuManagerTestParam, testing::Bool()); } // namespace -} // namespace connections -} // namespace nearby +} // namespace nearby::connections diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index f35d9f6d..e4737d0f 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -38,7 +38,9 @@ #include "connections/discovery_options.h" #include "connections/implementation/analytics/advertising_metadata_params.h" #include "connections/implementation/analytics/analytics_recorder.h" +#include "connections/implementation/analytics/analytics_recorder_impl.h" #include "connections/implementation/analytics/discovery_metadata_params.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/mediums/advertisements/dct_advertisement.h" #include "connections/listeners.h" @@ -79,9 +81,9 @@ namespace nearby::connections { namespace { -using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::connections::MediumRole; using ::location::nearby::connections::OsInfo; +using ::nearby::analytics::AnalyticsRecorder; constexpr char kEndpointIdChars[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', @@ -111,7 +113,7 @@ ClientProxy::ClientProxy(::nearby::analytics::EventLogger* event_logger) is_dct_enabled_ = NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature::kEnableDct); analytics_recorder_ = - std::make_unique(event_logger); + std::make_unique(event_logger); error_code_recorder_ = std::make_unique( [this](const ErrorCodeParams& params) { analytics_recorder_->OnErrorCode(params); @@ -262,7 +264,7 @@ void ClientProxy::StartedAdvertising( const std::string& service_id, Strategy strategy, const ConnectionListener& listener, absl::Span mediums, - const std::vector& + const std::vector& operation_result_with_mediums, const AdvertisingOptions& advertising_options) { MutexLock lock(&mutex_); @@ -283,9 +285,9 @@ void ClientProxy::StartedAdvertising( mediums.begin(), mediums.end()); std::unique_ptr advertising_metadata_params; advertising_metadata_params = - GetAnalyticsRecorder().BuildAdvertisingMetadataParams(); + AnalyticsRecorder::BuildAdvertisingMetadataParams(); advertising_metadata_params->operation_result_with_mediums = - std::move(operation_result_with_mediums); + operation_result_with_mediums; analytics_recorder_->OnStartAdvertising(strategy, medium_vector, advertising_metadata_params.get()); } @@ -401,7 +403,7 @@ void ClientProxy::StartedDiscovery( const std::string& service_id, Strategy strategy, DiscoveryListener listener, absl::Span mediums, - const std::vector& + const std::vector& operation_result_with_mediums, const DiscoveryOptions& discovery_options) { MutexLock lock(&mutex_); @@ -411,10 +413,9 @@ void ClientProxy::StartedDiscovery( const std::vector medium_vector( mediums.begin(), mediums.end()); std::unique_ptr discovery_metadata_params; - discovery_metadata_params = - GetAnalyticsRecorder().BuildDiscoveryMetadataParams(); + discovery_metadata_params = AnalyticsRecorder::BuildDiscoveryMetadataParams(); discovery_metadata_params->operation_result_with_mediums = - std::move(operation_result_with_mediums); + operation_result_with_mediums; analytics_recorder_->OnStartDiscovery(strategy, medium_vector, discovery_metadata_params.get()); } diff --git a/connections/implementation/client_proxy.h b/connections/implementation/client_proxy.h index 685765a8..e4929736 100644 --- a/connections/implementation/client_proxy.h +++ b/connections/implementation/client_proxy.h @@ -32,6 +32,7 @@ #include "connections/connection_options.h" #include "connections/discovery_options.h" #include "connections/implementation/analytics/analytics_recorder.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "connections/listeners.h" #include "connections/medium_selector.h" @@ -54,7 +55,6 @@ #include "internal/platform/mutex.h" #include "internal/platform/os_name.h" #include "internal/platform/scheduled_executor.h" -#include "internal/proto/analytics/connections_log.pb.h" namespace nearby::connections { @@ -109,8 +109,7 @@ class ClientProxy final { const std::string& service_id, Strategy strategy, const ConnectionListener& connection_lifecycle_listener, absl::Span mediums, - const std::vector& + const std::vector& operation_result_with_medium, const AdvertisingOptions& advertising_options = AdvertisingOptions{}); // Marks this client as not advertising. @@ -134,8 +133,7 @@ class ClientProxy final { const std::string& service_id, Strategy strategy, DiscoveryListener discovery_listener, absl::Span mediums, - const std::vector& + const std::vector& operation_result_with_medium, const DiscoveryOptions& discovery_options = DiscoveryOptions{}); // Marks this client as not discovering at all. diff --git a/connections/implementation/encryption_runner_test.cc b/connections/implementation/encryption_runner_test.cc index ee9bbc1d..743c1658 100644 --- a/connections/implementation/encryption_runner_test.cc +++ b/connections/implementation/encryption_runner_test.cc @@ -35,8 +35,7 @@ #include "proto/connections_enums.pb.h" #include "third_party/ukey2/src/main/cpp/include/securegcm/ukey2_handshake.h" -namespace nearby { -namespace connections { +namespace nearby::connections { namespace { using ::location::nearby::proto::connections::Medium; @@ -65,10 +64,8 @@ class FakeEndpointChannel : public EndpointChannel { override { Close(); } - void Close( - location::nearby::proto::connections::DisconnectionReason reason, - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection::SafeDisconnectionResult result) override { + void Close(location::nearby::proto::connections::DisconnectionReason reason, + nearby::analytics::SafeDisconnectionResult result) override { Close(); } bool IsClosed() const override { return false; } @@ -410,5 +407,4 @@ TEST(EncryptionRunnerTest, ClientSendsGarbageMessage3) { } } // namespace -} // namespace connections -} // namespace nearby +} // namespace nearby::connections diff --git a/connections/implementation/endpoint_channel.h b/connections/implementation/endpoint_channel.h index fc0d87cf..1b286475 100644 --- a/connections/implementation/endpoint_channel.h +++ b/connections/implementation/endpoint_channel.h @@ -26,8 +26,7 @@ #include "internal/platform/byte_array.h" #include "internal/platform/exception.h" -namespace nearby { -namespace connections { +namespace nearby::connections { class EndpointChannel { public: @@ -51,8 +50,7 @@ class EndpointChannel { // and safe disconnection result. virtual void Close( location::nearby::proto::connections::DisconnectionReason reason, - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection::SafeDisconnectionResult result) = 0; + nearby::analytics::SafeDisconnectionResult result) = 0; // True if the EndpointChannel is currently closed. virtual bool IsClosed() const = 0; @@ -141,7 +139,6 @@ inline bool operator!=(const EndpointChannel& lhs, const EndpointChannel& rhs) { return !(lhs == rhs); } -} // namespace connections -} // namespace nearby +} // namespace nearby::connections #endif // CORE_INTERNAL_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/endpoint_channel_manager.cc b/connections/implementation/endpoint_channel_manager.cc index c6af41d4..ab2af35d 100644 --- a/connections/implementation/endpoint_channel_manager.cc +++ b/connections/implementation/endpoint_channel_manager.cc @@ -29,10 +29,7 @@ #include "internal/platform/mutex.h" #include "internal/platform/mutex_lock.h" -namespace nearby { -namespace connections { -using ::location::nearby::analytics::proto::ConnectionsLog; - +namespace nearby::connections { namespace { const absl::Duration kDataTransferDelay = absl::Milliseconds(500); } @@ -183,7 +180,7 @@ void EndpointChannelManager::ChannelState::DestroyAll() { for (auto& item : endpoints_) { RemoveEndpoint(item.first, DisconnectionReason::SHUTDOWN, /* safe_to_disconnect_enabled */ false, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + SafeDisconnectionResult::kSafeDisconnection); } endpoints_.clear(); } @@ -365,5 +362,4 @@ bool EndpointChannelManager::UnregisterChannelForEndpoint( return true; } -} // namespace connections -} // namespace nearby +} // namespace nearby::connections diff --git a/connections/implementation/endpoint_channel_manager.h b/connections/implementation/endpoint_channel_manager.h index 19183ee0..47878023 100644 --- a/connections/implementation/endpoint_channel_manager.h +++ b/connections/implementation/endpoint_channel_manager.h @@ -21,18 +21,16 @@ #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" #include "absl/time/time.h" +#include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "internal/platform/mutex.h" -#include "internal/proto/analytics/connections_log.pb.h" #include "proto/connections_enums.pb.h" -namespace nearby { -namespace connections { +namespace nearby::connections { using DisconnectionReason = ::location::nearby::proto::connections::DisconnectionReason; -using SafeDisconnectionResult = ::location::nearby::analytics::proto:: - ConnectionsLog::EstablishedConnection::SafeDisconnectionResult; +using SafeDisconnectionResult = nearby::analytics::SafeDisconnectionResult; // NOTE(std::string): // All the strings in internal class public interfaces should be exchanged as @@ -215,7 +213,6 @@ class EndpointChannelManager final { ChannelState channel_state_; }; -} // namespace connections -} // namespace nearby +} // namespace nearby::connections #endif // CORE_INTERNAL_ENDPOINT_CHANNEL_MANAGER_H_ diff --git a/connections/implementation/endpoint_channel_manager_test.cc b/connections/implementation/endpoint_channel_manager_test.cc index d73b746b..0bdbb6d1 100644 --- a/connections/implementation/endpoint_channel_manager_test.cc +++ b/connections/implementation/endpoint_channel_manager_test.cc @@ -27,6 +27,7 @@ #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "absl/time/time.h" +#include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/base_endpoint_channel.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/encryption_runner.h" @@ -39,16 +40,14 @@ #include "internal/platform/multi_thread_executor.h" #include "internal/platform/output_stream.h" #include "internal/platform/pipe.h" -#include "internal/proto/analytics/connections_log.pb.h" #include "proto/connections_enums.pb.h" -namespace nearby { -namespace connections { +namespace nearby::connections { namespace { -using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::proto::connections::DisconnectionReason; using ::location::nearby::proto::connections::Medium; +using ::nearby::analytics::SafeDisconnectionResult; using EncryptionContext = BaseEndpointChannel::EncryptionContext; constexpr size_t kChunkSize = 64 * 1024; @@ -243,10 +242,10 @@ TEST(BaseEndpointChannelManagerTest, RegisterChannelEncryptedReadwrite) { channel_b_raw->Close(DisconnectionReason::REMOTE_DISCONNECTION); ecm_a.UnregisterChannelForEndpoint( std::string(kEndpointId), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + SafeDisconnectionResult::kSafeDisconnection); ecm_b.UnregisterChannelForEndpoint( std::string(kEndpointId), DisconnectionReason::REMOTE_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + SafeDisconnectionResult::kSafeDisconnection); } TEST(BaseEndpointChannelManagerTest, ReplaceChannelNoEncrypted) { @@ -311,12 +310,11 @@ TEST(BaseEndpointChannelManagerTest, ReplaceChannelNoEncrypted) { channel_b_raw->Close(DisconnectionReason::REMOTE_DISCONNECTION); ecm_a.UnregisterChannelForEndpoint( std::string(kEndpointId), DisconnectionReason::LOCAL_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + SafeDisconnectionResult::kSafeDisconnection); ecm_b.UnregisterChannelForEndpoint( std::string(kEndpointId), DisconnectionReason::REMOTE_DISCONNECTION, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + SafeDisconnectionResult::kSafeDisconnection); } } // namespace -} // namespace connections -} // namespace nearby +} // namespace nearby::connections diff --git a/connections/implementation/endpoint_manager.cc b/connections/implementation/endpoint_manager.cc index 5070d390..31b4454b 100644 --- a/connections/implementation/endpoint_manager.cc +++ b/connections/implementation/endpoint_manager.cc @@ -24,6 +24,7 @@ #include "absl/functional/any_invocable.h" #include "absl/time/time.h" #include "connections/connection_options.h" +#include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/endpoint_channel_manager.h" @@ -42,19 +43,17 @@ #include "internal/platform/mutex_lock.h" #include "internal/platform/runnable.h" #include "internal/platform/single_thread_executor.h" -#include "internal/proto/analytics/connections_log.pb.h" #include "proto/connections_enums.pb.h" -namespace nearby { -namespace connections { +namespace nearby::connections { namespace { -using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::connections::KeepAliveFrame; using ::location::nearby::connections::OfflineFrame; using ::location::nearby::connections::PayloadTransferFrame; using ::location::nearby::connections::V1Frame; using ::location::nearby::proto::connections::DisconnectionReason; +using ::nearby::analytics::SafeDisconnectionResult; // We set this to 11s to provide sufficient time for an in-progress WebRTC // bandwidth upgrade to resolve. This is chosen to be slightly longer than the @@ -743,7 +742,7 @@ void EndpointManager::RemoveEndpoint(ClientProxy* client, << ", reason: " << reason; SafeDisconnectionResult safe_disconnect_result = - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION; + SafeDisconnectionResult::kSafeDisconnection; // Grab the service ID before we destroy the channel. EndpointChannel* channel = @@ -756,11 +755,13 @@ void EndpointManager::RemoveEndpoint(ClientProxy* client, bool is_safe_disconnection = ApplySafeToDisconnect(endpoint_id, channel, reason); safe_disconnect_result = - is_safe_disconnection - ? ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION - : ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION; + is_safe_disconnection ? SafeDisconnectionResult::kSafeDisconnection + : SafeDisconnectionResult::kUnsafeDisconnection; LOG(INFO) << "[safe-to-disconnect] safe_disconnect_result:" - << (safe_disconnect_result ? "true" : "false"); + << (safe_disconnect_result == + SafeDisconnectionResult::kSafeDisconnection + ? "true" + : "false"); } } @@ -953,7 +954,7 @@ EndpointManager::EndpointState::~EndpointState() { VLOG(1) << "EndpointState destructor " << endpoint_id_; channel_manager_->UnregisterChannelForEndpoint( endpoint_id_, DisconnectionReason::SHUTDOWN, - ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION); + SafeDisconnectionResult::kSafeDisconnection); } // Make sure the KeepAlive thread isn't blocking shutdown. @@ -982,5 +983,4 @@ void EndpointManager::RunOnEndpointManagerThread(const std::string& name, serial_executor_->Execute(name, std::move(runnable)); } -} // namespace connections -} // namespace nearby +} // namespace nearby::connections diff --git a/connections/implementation/fake_endpoint_channel.h b/connections/implementation/fake_endpoint_channel.h index cb03659f..01bb92fe 100644 --- a/connections/implementation/fake_endpoint_channel.h +++ b/connections/implementation/fake_endpoint_channel.h @@ -27,8 +27,7 @@ #include "internal/platform/exception.h" #include "internal/platform/implementation/system_clock.h" -namespace nearby { -namespace connections { +namespace nearby::connections { // An endpoint channel implementation used for testing. The read and write // output can be set. @@ -56,10 +55,8 @@ class FakeEndpointChannel : public EndpointChannel { is_closed_ = true; disconnection_reason_ = reason; } - void Close( - location::nearby::proto::connections::DisconnectionReason reason, - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection::SafeDisconnectionResult result) override { + void Close(location::nearby::proto::connections::DisconnectionReason reason, + nearby::analytics::SafeDisconnectionResult result) override { Close(reason); } bool IsClosed() const override { return is_closed_; } @@ -119,7 +116,6 @@ class FakeEndpointChannel : public EndpointChannel { mutable uint32_t next_keep_alive_seq_no_ = 0; }; -} // namespace connections -} // namespace nearby +} // namespace nearby::connections #endif // NEARBY_CONNECTIONS_IMPLEMENTATION_FAKE_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/mock_endpoint_channel.h b/connections/implementation/mock_endpoint_channel.h index 87f51995..14ea499e 100644 --- a/connections/implementation/mock_endpoint_channel.h +++ b/connections/implementation/mock_endpoint_channel.h @@ -40,8 +40,7 @@ class MockEndpointChannel : public EndpointChannel { (override)); MOCK_METHOD(void, Close, (location::nearby::proto::connections::DisconnectionReason reason, - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection::SafeDisconnectionResult result), + nearby::analytics::SafeDisconnectionResult result), (override)); MOCK_METHOD(bool, IsClosed, (), (const, override)); MOCK_METHOD(std::string, GetType, (), (const, override)); diff --git a/connections/implementation/payload_manager.cc b/connections/implementation/payload_manager.cc index f534a2ed..6529b211 100644 --- a/connections/implementation/payload_manager.cc +++ b/connections/implementation/payload_manager.cc @@ -29,6 +29,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/time/time.h" +#include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel_manager.h" #include "connections/implementation/endpoint_manager.h" @@ -63,7 +64,7 @@ using ::location::nearby::connections::V1Frame; using ::location::nearby::proto::connections::Medium; using ::location::nearby::proto::connections::OperationResultCode; using ::location::nearby::proto::connections::PayloadStatus; -using PayloadDirection = ::nearby::connections::PayloadDirection; +using ::nearby::analytics::AnalyticsRecorder; constexpr absl::Duration kMinTransferUpdateInterval = absl::Milliseconds(50); } // namespace @@ -620,9 +621,8 @@ void PayloadManager::OnEndpointDisconnect(ClientProxy* client, default: payload_status = PayloadStatus::ENDPOINT_IO_ERROR; operation_result_code = - client->GetAnalyticsRecorder() - .GetChannelIoErrorResultCodeFromMedium( - client->GetConnectedMedium(endpoint_id)); + AnalyticsRecorder::GetChannelIoErrorResultCodeFromMedium( + client->GetConnectedMedium(endpoint_id)); break; } @@ -839,9 +839,8 @@ void PayloadManager::SendClientCallbacksForFinishedOutgoingPayload( endpoint_id, payload_header.id(), status, (operation_result_code == OperationResultCode::DETAIL_UNKNOWN && status == PayloadStatus::ENDPOINT_IO_ERROR) - ? client->GetAnalyticsRecorder() - .GetChannelIoErrorResultCodeFromMedium( - client->GetConnectedMedium(endpoint_id)) + ? AnalyticsRecorder::GetChannelIoErrorResultCodeFromMedium( + client->GetConnectedMedium(endpoint_id)) : operation_result_code); } From 01ff913277d2eaab8b6ced5576f761b775720a25 Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 28 May 2026 17:24:44 -0700 Subject: [PATCH 124/151] routing change. PiperOrigin-RevId: 923062880 --- proto/sharing_enums.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index e0891933..d2f0b0bc 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -321,6 +321,7 @@ enum EventType { /*[ device_role = DEVICE_ROLE_INITIATOR ]*/; CLOUD_REGISTER_RECEIVER = 75 /*[ device_role = DEVICE_ROLE_REMOTE ]*/; + // Cloud upload events (routing updated in nearby_event_codes.proto). CLOUD_UPLOAD_START = 76 /*[ device_role = DEVICE_ROLE_INITIATOR ]*/; CLOUD_UPLOAD_END = 77 /*[ device_role = DEVICE_ROLE_INITIATOR ]*/; From d4cd7ba4be72bbdd6474bda0ad4640a739c373c1 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Fri, 29 May 2026 05:05:21 -0700 Subject: [PATCH 125/151] [Nearby Connections] Fix UAF in OfflineServiceController during shutdown PiperOrigin-RevId: 923343443 --- .../offline_service_controller.cc | 2 ++ .../offline_service_controller_test.cc | 27 +++++++++++++++++++ connections/implementation/pcp_manager.cc | 1 + 3 files changed, 30 insertions(+) diff --git a/connections/implementation/offline_service_controller.cc b/connections/implementation/offline_service_controller.cc index 4e667773..af10471e 100644 --- a/connections/implementation/offline_service_controller.cc +++ b/connections/implementation/offline_service_controller.cc @@ -90,6 +90,7 @@ OfflineServiceController::StartListeningForIncomingConnections( ClientProxy* client, absl::string_view service_id, v3::ConnectionListener listener, const v3::ConnectionListeningOptions& options) { + if (stop_) return {{Status::kOutOfOrderApiCall}, {}}; LOG(INFO) << "Client " << client->GetClientId() << " requested to start listening for service_id " << service_id; return pcp_manager_.StartListeningForIncomingConnections( @@ -98,6 +99,7 @@ OfflineServiceController::StartListeningForIncomingConnections( void OfflineServiceController::StopListeningForIncomingConnections( ClientProxy* client) { + if (stop_) return; LOG(INFO) << "Client " << client->GetClientId() << " requested to stop listening for service_id " << client->GetListeningForIncomingConnectionsServiceId(); diff --git a/connections/implementation/offline_service_controller_test.cc b/connections/implementation/offline_service_controller_test.cc index d82d1893..59fb79cb 100644 --- a/connections/implementation/offline_service_controller_test.cc +++ b/connections/implementation/offline_service_controller_test.cc @@ -567,6 +567,33 @@ TEST_P(OfflineServiceControllerTest, ShutdownBwuManagerExecutors) { env_.Stop(); } +TEST_P(OfflineServiceControllerTest, TestNoStartListeningAfterStop) { + env_.Start(); + OfflineSimulationUser user_a(kDeviceA, GetParam()); + v3::ConnectionListener listener; + v3::ConnectionListeningOptions options; + + user_a.Stop(); + + auto result = user_a.StartListeningForIncomingConnections( + std::string(kServiceId), listener, options); + EXPECT_EQ(result.first.value, Status::kOutOfOrderApiCall); + + env_.Stop(); +} + +TEST_P(OfflineServiceControllerTest, TestNoStopListeningAfterStop) { + env_.Start(); + OfflineSimulationUser user_a(kDeviceA, GetParam()); + + user_a.Stop(); + + // Verify that calling StopListening after Stop does not crash. + user_a.StopListeningForIncomingConnections(); + + env_.Stop(); +} + INSTANTIATE_TEST_SUITE_P(ParametrisedOfflineServiceControllerTest, OfflineServiceControllerTest, ::testing::ValuesIn(kTestCases)); diff --git a/connections/implementation/pcp_manager.cc b/connections/implementation/pcp_manager.cc index eb35652a..b99dec20 100644 --- a/connections/implementation/pcp_manager.cc +++ b/connections/implementation/pcp_manager.cc @@ -122,6 +122,7 @@ PcpManager::StartListeningForIncomingConnections( ClientProxy* client, absl::string_view service_id, v3::ConnectionListener listener, const v3::ConnectionListeningOptions& options) { + if (shutdown_) return {{Status::kOutOfOrderApiCall}, {}}; if (!SetCurrentPcpHandler(options.strategy)) { return {{Status::kError}, {}}; } From 7c31996db2fd0831d6b5cb379a531634a19941f2 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Fri, 29 May 2026 05:34:20 -0700 Subject: [PATCH 126/151] Remediate ClientProxy data races, UAF, and BleSocket deadlocks (b/511806593). PiperOrigin-RevId: 923354836 --- connections/implementation/BUILD | 2 + connections/implementation/client_proxy.cc | 51 ++- connections/implementation/client_proxy.h | 9 +- .../implementation/client_proxy_test.cc | 30 +- .../mediums/awdl_bwu_handler.cc | 8 +- connections/implementation/mediums/ble/BUILD | 1 - .../implementation/mediums/ble/ble_socket.cc | 43 ++- .../implementation/mediums/ble/ble_socket.h | 8 +- .../mediums/bluetooth_bwu_handler.cc | 9 +- .../mediums/bluetooth_bwu_handler_test.cc | 41 ++- .../implementation/mediums/webrtc/BUILD | 6 + .../mediums/webrtc/webrtc_bwu_handler.cc | 6 +- .../mediums/webrtc/webrtc_bwu_handler_test.cc | 139 ++++++++ .../mediums/wifi_direct_bwu_handler.cc | 7 +- .../mediums/wifi_hotspot_bwu_handler.cc | 5 +- .../mediums/wifi_lan_bwu_handler.cc | 10 +- .../implementation/p2p_cluster_pcp_handler.cc | 41 +-- .../p2p_cluster_pcp_handler_test.cc | 310 +++++++++++------- 18 files changed, 524 insertions(+), 202 deletions(-) create mode 100644 connections/implementation/mediums/webrtc/webrtc_bwu_handler_test.cc diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index c3723458..1dd42abe 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -251,6 +251,7 @@ cc_library( "//internal/interop:authentication_transport_interface", "//internal/interop:device", "//internal/platform:base", + "//internal/platform:cancellation_flag", "//internal/platform:comm", "//internal/platform:connection_info", "//internal/platform:logging", @@ -478,6 +479,7 @@ cc_test( "//internal/platform/implementation/g3", # build_cleaner: keep "//proto:connections_enums_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/time", diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index e4737d0f..31bfc12b 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -190,6 +190,7 @@ const NearbyDevice* ClientProxy::GetLocalDevice() { } std::string ClientProxy::GetConnectionToken(const std::string& endpoint_id) { + MutexLock lock(&mutex_); ConnectionPair* item = LookupConnection(endpoint_id); if (item != nullptr) { return item->first.connection_token; @@ -220,6 +221,7 @@ std::string ClientProxy::GetSavePath( std::optional ClientProxy::GetBluetoothMacAddress( const std::string& endpoint_id) { + MutexLock lock(&mutex_); auto item = bluetooth_mac_addresses_.find(endpoint_id); if (item != bluetooth_mac_addresses_.end()) return item->second; return std::nullopt; @@ -227,6 +229,7 @@ std::optional ClientProxy::GetBluetoothMacAddress( void ClientProxy::SetBluetoothMacAddress(const std::string& endpoint_id, MacAddress bluetooth_mac_address) { + MutexLock lock(&mutex_); bluetooth_mac_addresses_[endpoint_id] = bluetooth_mac_address; } @@ -878,16 +881,19 @@ bool ClientProxy::IsConnectionRejected(const std::string& endpoint_id) const { } bool ClientProxy::LocalConnectionIsAccepted(std::string endpoint_id) const { + MutexLock lock(&mutex_); return ConnectionStatusesContains( endpoint_id, ClientProxy::Connection::kLocalEndpointAccepted); } bool ClientProxy::RemoteConnectionIsAccepted(std::string endpoint_id) const { + MutexLock lock(&mutex_); return ConnectionStatusesContains( endpoint_id, ClientProxy::Connection::kRemoteEndpointAccepted); } bool ClientProxy::AutoUpgradeBandwidth() const { + MutexLock lock(&mutex_); bool result = false; if (IsAdvertising() && (GetAdvertisingOptions().strategy.IsNone() || GetAdvertisingOptions().auto_upgrade_bandwidth)) { @@ -902,6 +908,7 @@ bool ClientProxy::AutoUpgradeBandwidth() const { } bool ClientProxy::ShouldEnforceTopologyConstraints() const { + MutexLock lock(&mutex_); bool result = false; if (IsAdvertising() && (GetAdvertisingOptions().strategy.IsNone() || @@ -922,6 +929,7 @@ void ClientProxy::AddCancellationFlag(const std::string& endpoint_id) { return; } + MutexLock lock(&mutex_); auto item = cancellation_flags_.find(endpoint_id); if (item != cancellation_flags_.end()) { // A new flag may be added to the map with the same endpoint, even if a @@ -936,19 +944,21 @@ void ClientProxy::AddCancellationFlag(const std::string& endpoint_id) { return; } cancellation_flags_.emplace(endpoint_id, - std::make_unique()); + std::make_shared()); } -CancellationFlag* ClientProxy::GetCancellationFlag( +std::shared_ptr ClientProxy::GetCancellationFlag( const std::string& endpoint_id) { + MutexLock lock(&mutex_); const auto item = cancellation_flags_.find(endpoint_id); if (item == cancellation_flags_.end()) { - return default_cancellation_flag_.get(); + return default_cancellation_flag_; } - return item->second.get(); + return item->second; } void ClientProxy::CancelEndpoint(const std::string& endpoint_id) { + MutexLock lock(&mutex_); const auto item = cancellation_flags_.find(endpoint_id); if (item != cancellation_flags_.end()) { item->second->Cancel(); @@ -959,6 +969,7 @@ const OsInfo& ClientProxy::GetLocalOsInfo() const { return local_os_info_; } std::optional ClientProxy::GetRemoteOsInfo( absl::string_view endpoint_id) const { + MutexLock lock(&mutex_); const ConnectionPair* item = LookupConnection(endpoint_id); if (item != nullptr) { return item->first.os_info; @@ -968,11 +979,13 @@ std::optional ClientProxy::GetRemoteOsInfo( void ClientProxy::SetLocalOsType( const location::nearby::connections::OsInfo::OsType& os_type) { + MutexLock lock(&mutex_); local_os_info_.set_type(os_type); } void ClientProxy::SetRemoteOsInfo(absl::string_view endpoint_id, const OsInfo& remote_os_info) { + MutexLock lock(&mutex_); ConnectionPair* item = LookupConnection(endpoint_id); if (item != nullptr) { item->first.os_info.emplace(remote_os_info); @@ -1019,8 +1032,9 @@ bool ClientProxy::IsPayloadReceivedAckEnabled(absl::string_view endpoint_id) { } void ClientProxy::CancelAllEndpoints() { + MutexLock lock(&mutex_); for (const auto& item : cancellation_flags_) { - CancellationFlag* cancellation_flag = item.second.get(); + std::shared_ptr cancellation_flag = item.second; if (cancellation_flag->Cancelled()) { continue; } @@ -1123,14 +1137,17 @@ void ClientProxy::AppendConnectionStatus(const std::string& endpoint_id, } AdvertisingOptions ClientProxy::GetAdvertisingOptions() const { + MutexLock lock(&mutex_); return advertising_options_; } DiscoveryOptions ClientProxy::GetDiscoveryOptions() const { + MutexLock lock(&mutex_); return discovery_options_; } v3::ConnectionListeningOptions ClientProxy::GetListeningOptions() const { + MutexLock lock(&mutex_); return listening_options_; } @@ -1208,11 +1225,13 @@ OsInfo::OsType ClientProxy::OSNameToOsInfoType(api::OSName osName) { } std::int32_t ClientProxy::GetLocalMultiplexSocketBitmask() const { + MutexLock lock(&mutex_); return 0; } void ClientProxy::SetRemoteMultiplexSocketBitmask( absl::string_view endpoint_id, int remote_multiplex_socket_bitmask) { + MutexLock lock(&mutex_); ConnectionPair* item = LookupConnection(endpoint_id); if (item != nullptr) { item->first.remote_multiplex_socket_bitmask = @@ -1223,6 +1242,7 @@ void ClientProxy::SetRemoteMultiplexSocketBitmask( } bool ClientProxy::IsLocalMultiplexSocketSupported(Medium medium) { + MutexLock lock(&mutex_); int bitmask = GetLocalMultiplexSocketBitmask(); switch (medium) { case Medium::BLUETOOTH: @@ -1238,6 +1258,7 @@ bool ClientProxy::IsLocalMultiplexSocketSupported(Medium medium) { std::optional ClientProxy::GetRemoteMultiplexSocketBitmask( absl::string_view endpoint_id) const { + MutexLock lock(&mutex_); const ConnectionPair* item = LookupConnection(endpoint_id); if (item != nullptr) { return item->first.remote_multiplex_socket_bitmask; @@ -1247,6 +1268,7 @@ std::optional ClientProxy::GetRemoteMultiplexSocketBitmask( bool ClientProxy::IsMultiplexSocketSupported(absl::string_view endpoint_id, Medium medium) { + MutexLock lock(&mutex_); ConnectionPair* item = LookupConnection(endpoint_id); if (item == nullptr) { return false; @@ -1264,20 +1286,31 @@ bool ClientProxy::IsMultiplexSocketSupported(absl::string_view endpoint_id, } } -bool ClientProxy::GetWebRtcNonCellular() { return webrtc_non_cellular_; } +bool ClientProxy::GetWebRtcNonCellular() { + MutexLock lock(&mutex_); + return webrtc_non_cellular_; +} void ClientProxy::SetWebRtcNonCellular(bool webrtc_non_cellular) { + MutexLock lock(&mutex_); VLOG(1) << "ClientProxy: client=" << GetClientId() << (webrtc_non_cellular ? " disallow" : " allow") << " to use mobile data."; webrtc_non_cellular_ = webrtc_non_cellular; } -bool ClientProxy::IsDctEnabled() const { return is_dct_enabled_; } +bool ClientProxy::IsDctEnabled() const { + MutexLock lock(&mutex_); + return is_dct_enabled_; +} -uint8_t ClientProxy::GetDctDedup() const { return dct_dedup_; } +uint8_t ClientProxy::GetDctDedup() const { + MutexLock lock(&mutex_); + return dct_dedup_; +} void ClientProxy::UpdateDctDeviceName(absl::string_view device_name) { + MutexLock lock(&mutex_); if (!dct_device_name_.empty() && dct_device_name_ != device_name) { // Need to update dedup value if device name is changed. absl::BitGen bitgen; @@ -1299,6 +1332,7 @@ void ClientProxy::UpdateDctDeviceName(absl::string_view device_name) { std::optional ClientProxy::GetMediumRole( absl::string_view endpoint_id) const { + MutexLock lock(&mutex_); const ConnectionPair* item = LookupConnection(endpoint_id); if (item != nullptr) { return item->first.connection_options.connection_info.medium_role; @@ -1307,6 +1341,7 @@ std::optional ClientProxy::GetMediumRole( } std::optional ClientProxy::GetEndpointIdForDct() const { + MutexLock lock(&mutex_); if (dct_endpoint_id_.empty()) { return std::nullopt; } diff --git a/connections/implementation/client_proxy.h b/connections/implementation/client_proxy.h index e4929736..e7010739 100644 --- a/connections/implementation/client_proxy.h +++ b/connections/implementation/client_proxy.h @@ -262,7 +262,8 @@ class ClientProxy final { // Adds a CancellationFlag for endpoint id. void AddCancellationFlag(const std::string& endpoint_id); // Returns the CancellationFlag for endpoint id, - CancellationFlag* GetCancellationFlag(const std::string& endpoint_id); + std::shared_ptr GetCancellationFlag( + const std::string& endpoint_id); // Sets the CancellationFlag to true for endpoint id. void CancelEndpoint(const std::string& endpoint_id); // Cancels all CancellationFlags. @@ -517,11 +518,11 @@ class ClientProxy final { // Maps endpoint_id to CancellationFlag. CancellationFlags are passed around // as raw pointers to other classes in Nearby Connections, so it is important // that objects in this map are not cleared, even if they are cancelled. - absl::flat_hash_map> + absl::flat_hash_map> cancellation_flags_; // A default cancellation flag with isCancelled set be true. - std::unique_ptr default_cancellation_flag_ = - std::make_unique(true); + std::shared_ptr default_cancellation_flag_ = + std::make_shared(true); // An app lifecycle monitor for monitoring the app lifecycle state. std::unique_ptr app_lifecycle_monitor_; diff --git a/connections/implementation/client_proxy_test.cc b/connections/implementation/client_proxy_test.cc index 5ea52f45..e0e1f757 100644 --- a/connections/implementation/client_proxy_test.cc +++ b/connections/implementation/client_proxy_test.cc @@ -14,6 +14,7 @@ #include "connections/implementation/client_proxy.h" +#include #include #include #include @@ -24,6 +25,7 @@ #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "absl/base/thread_annotations.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/time/clock.h" @@ -38,6 +40,7 @@ #include "connections/payload.h" #include "connections/status.h" #include "connections/strategy.h" +#include "connections/v3/bandwidth_info.h" #include "connections/v3/connection_listening_options.h" #include "connections/v3/connection_result.h" #include "connections/v3/connections_device_provider.h" @@ -53,6 +56,7 @@ #include "internal/platform/medium_environment.h" #include "internal/platform/mutex.h" #include "internal/platform/mutex_lock.h" +#include "internal/platform/single_thread_executor.h" #include "proto/connections_enums.pb.h" namespace nearby { @@ -114,7 +118,7 @@ class FakeEventLogger : public ::nearby::analytics::MockEventLogger { } Mutex mutex_; - std::vector logs_; + std::vector logs_ ABSL_GUARDED_BY(mutex_); }; class MockDeviceProvider : public nearby::NearbyDeviceProvider { @@ -434,7 +438,7 @@ TEST_P(ClientProxyTest, CanCancelEndpoint) { // `CancellationFlag` pointers are passed to other classes in Nearby // Connections, and by using the pointers directly, we test their // consumption of `CancellationFlag` pointers. - CancellationFlag* cancellation_flag = + std::shared_ptr cancellation_flag = client2()->GetCancellationFlag(advertising_endpoint.id); EXPECT_FALSE( @@ -470,7 +474,7 @@ TEST_P(ClientProxyTest, CanCancelAllEndpoints) { // `CancellationFlag` pointers are passed to other classes in Nearby // Connections, and by using the pointers directly, we test their // consumption of `CancellationFlag` pointers. - CancellationFlag* cancellation_flag = + std::shared_ptr cancellation_flag = client2()->GetCancellationFlag(advertising_endpoint.id); EXPECT_FALSE( @@ -537,6 +541,26 @@ TEST_P(ClientProxyTest, CanCancelAllEndpointsWithDifferentEndpoint) { } } +TEST_P(ClientProxyTest, GetCancellationFlagRace) { + std::string endpoint_id = "test_endpoint"; + client1()->AddCancellationFlag(endpoint_id); + + std::atomic run{true}; + SingleThreadExecutor executor; + executor.Execute([&]() { + while (run) { + client1()->GetCancellationFlag(endpoint_id); + } + }); + + for (int i = 0; i < 10000; ++i) { + client1()->Reset(); + client1()->AddCancellationFlag(endpoint_id); + } + + run = false; +} + INSTANTIATE_TEST_SUITE_P(ParametrisedClientProxyTest, ClientProxyTest, ::testing::ValuesIn(kTestCases)); diff --git a/connections/implementation/mediums/awdl_bwu_handler.cc b/connections/implementation/mediums/awdl_bwu_handler.cc index edff8dda..8f8e5287 100644 --- a/connections/implementation/mediums/awdl_bwu_handler.cc +++ b/connections/implementation/mediums/awdl_bwu_handler.cc @@ -35,6 +35,7 @@ #include "internal/base/masker.h" #include "internal/platform/awdl.h" #include "internal/platform/byte_array.h" +#include "internal/platform/cancellation_flag.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/expected.h" #include "internal/platform/implementation/psk_info.h" @@ -149,9 +150,10 @@ AwdlBwuHandler::CreateUpgradedEndpointChannel( << service_name << ", service_type:" << service_type << ") for endpoint " << endpoint_id; - ErrorOr socket_result = - awdl_medium_.Connect(upgrade_service_id, nsd_service_info, psk_info, - client->GetCancellationFlag(endpoint_id)); + std::shared_ptr cancellation_flag = + client->GetCancellationFlag(endpoint_id); + ErrorOr socket_result = awdl_medium_.Connect( + upgrade_service_id, nsd_service_info, psk_info, cancellation_flag.get()); if (socket_result.has_error()) { LOG(ERROR) << "Failed to connect to the AWDL service (service_name:" << service_name << ", service_type:" << service_type diff --git a/connections/implementation/mediums/ble/BUILD b/connections/implementation/mediums/ble/BUILD index 619672c2..a4f1a0a4 100644 --- a/connections/implementation/mediums/ble/BUILD +++ b/connections/implementation/mediums/ble/BUILD @@ -70,7 +70,6 @@ cc_library( "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:string_view", - "@com_google_absl//absl/synchronization", ], ) diff --git a/connections/implementation/mediums/ble/ble_socket.cc b/connections/implementation/mediums/ble/ble_socket.cc index 97c29e32..dc068c9c 100644 --- a/connections/implementation/mediums/ble/ble_socket.cc +++ b/connections/implementation/mediums/ble/ble_socket.cc @@ -207,22 +207,28 @@ Medium BleSocket::GetMediumLocked() const { } ExceptionOr BleSocket::DispatchPacket() { - MutexLock lock(&mutex_); - if (!ble_input_stream_) { - return Exception::kFailed; + std::shared_ptr input_stream; + { + MutexLock lock(&mutex_); + if (!ble_input_stream_) { + return Exception::kFailed; + } + input_stream = ble_input_stream_; } ExceptionOr read_bytes = - ble_input_stream_->Read(BlePacket::kServiceIdHashLength); + input_stream->Read(BlePacket::kServiceIdHashLength); while (read_bytes.ok()) { ByteArray read_bytes_result = read_bytes.result(); if (BlePacket::IsControlPacketBytes(read_bytes_result)) { - ExceptionOr handle_result = ProcessBleControlPacketLocked(); + ExceptionOr handle_result = + ProcessBleControlPacket(input_stream); if (!handle_result.ok()) { return handle_result; } - read_bytes = ble_input_stream_->Read(BlePacket::kServiceIdHashLength); + read_bytes = input_stream->Read(BlePacket::kServiceIdHashLength); } else { + MutexLock lock(&mutex_); if (read_bytes_result != service_id_hash_) { LOG(WARNING) << "Received data packet with incorrect service ID hash. Expected: " @@ -239,20 +245,22 @@ ExceptionOr BleSocket::DispatchPacket() { ExceptionOr BleSocket::ReadPayloadLength() { int payload_length = 0; + std::shared_ptr input_stream; { MutexLock lock(&mutex_); if (!ble_input_stream_) { return {Exception::kIo}; } - - ExceptionOr read_bytes = - ble_input_stream_->Read(sizeof(std::int32_t)); - if (!read_bytes.ok()) { - return read_bytes.exception(); - } - - payload_length = byte_utils::BytesToInt(std::move(read_bytes.result())); + input_stream = ble_input_stream_; } + + ExceptionOr read_bytes = input_stream->Read(sizeof(std::int32_t)); + if (!read_bytes.ok()) { + return read_bytes.exception(); + } + + payload_length = byte_utils::BytesToInt(std::move(read_bytes.result())); + Exception send_ack_result = SendPacketAcknowledgement(payload_length); if (!send_ack_result.Ok()) { LOG(WARNING) << "Failed to send packet acknowledgement."; @@ -268,9 +276,10 @@ Exception BleSocket::WritePayloadLength(int payload_length) { return ble_output_stream_->WritePayloadLength(payload_length); } -ExceptionOr BleSocket::ProcessBleControlPacketLocked() { +ExceptionOr BleSocket::ProcessBleControlPacket( + std::shared_ptr input_stream) { // Read the first 4 bytes (packet block 1). - ExceptionOr read_bytes = ble_input_stream_->Read(4); + ExceptionOr read_bytes = input_stream->Read(4); if (!read_bytes.ok()) { return read_bytes; } @@ -282,7 +291,7 @@ ExceptionOr BleSocket::ProcessBleControlPacketLocked() { // Read the length from the 3rd byte of the packet block (0-indexed). int packet_block_2_size = packet_block_1.data()[3]; // Read the left bytes for the packet block 2). - read_bytes = ble_input_stream_->Read(packet_block_2_size); + read_bytes = input_stream->Read(packet_block_2_size); if (!read_bytes.ok()) { return read_bytes; } diff --git a/connections/implementation/mediums/ble/ble_socket.h b/connections/implementation/mediums/ble/ble_socket.h index 4aba0ca1..85aa9fb0 100644 --- a/connections/implementation/mediums/ble/ble_socket.h +++ b/connections/implementation/mediums/ble/ble_socket.h @@ -375,8 +375,8 @@ class BleSocket final { * payload, the `ByteArray` may be empty. Returns an `Exception` if a * protocol error occurs or the read operation fails. */ - ExceptionOr ProcessBleControlPacketLocked() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + ExceptionOr ProcessBleControlPacket( + std::shared_ptr input_stream); /** * Sends a raw L2CAP packet over the socket. @@ -407,9 +407,9 @@ class BleSocket final { SingleThreadExecutor serial_executor_; const ByteArray service_id_hash_; - std::unique_ptr ble_input_stream_ + std::shared_ptr ble_input_stream_ ABSL_GUARDED_BY(mutex_) = nullptr; - std::unique_ptr ble_output_stream_ + std::shared_ptr ble_output_stream_ ABSL_GUARDED_BY(mutex_) = nullptr; nearby::BleSocket ble_socket_ ABSL_GUARDED_BY(mutex_) = nearby::BleSocket(); nearby::BleL2capSocket l2cap_socket_ ABSL_GUARDED_BY(mutex_) = diff --git a/connections/implementation/mediums/bluetooth_bwu_handler.cc b/connections/implementation/mediums/bluetooth_bwu_handler.cc index 2a7e9075..0edaae99 100644 --- a/connections/implementation/mediums/bluetooth_bwu_handler.cc +++ b/connections/implementation/mediums/bluetooth_bwu_handler.cc @@ -18,17 +18,18 @@ #include #include +#include "absl/base/nullability.h" #include "absl/functional/bind_front.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "connections/implementation/mediums/bluetooth_classic.h" #include "connections/implementation/mediums/bluetooth_endpoint_channel.h" -#include "absl/base/nullability.h" #include "connections/implementation/mediums/bluetooth_radio.h" #include "connections/implementation/offline_frames.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_classic.h" +#include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" #include "internal/platform/logging.h" #include "internal/platform/mac_address.h" @@ -89,8 +90,10 @@ BluetoothBwuHandler::CreateUpgradedEndpointChannel( OperationResultCode::CONNECTIVITY_BLUETOOTH_DEVICE_OBTAIN_FAILURE)}; } - ErrorOr socket_result = bluetooth_medium_.Connect( - device, service_id, client->GetCancellationFlag(endpoint_id)); + std::shared_ptr cancellation_flag = + client->GetCancellationFlag(endpoint_id); + ErrorOr socket_result = + bluetooth_medium_.Connect(device, service_name, cancellation_flag.get()); if (socket_result.has_error()) { LOG(ERROR) << "BluetoothBwuHandler failed to connect to the Bluetooth device (" diff --git a/connections/implementation/mediums/bluetooth_bwu_handler_test.cc b/connections/implementation/mediums/bluetooth_bwu_handler_test.cc index 4a5bac2c..55c6c021 100644 --- a/connections/implementation/mediums/bluetooth_bwu_handler_test.cc +++ b/connections/implementation/mediums/bluetooth_bwu_handler_test.cc @@ -44,10 +44,19 @@ constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); class BluetoothBwuTest : public testing::Test { protected: - BluetoothBwuTest() { env_.Start(); } - ~BluetoothBwuTest() override { env_.Stop(); } + BluetoothBwuTest() { + original_flags_ = FeatureFlags::GetInstance().GetFlags(); + env_.Start(); + } + ~BluetoothBwuTest() override { + FeatureFlags::GetMutableInstanceForTesting().SetFlags(original_flags_); + env_.Stop(); + } + + void RunSTACreateEndpointChannelTest(bool enable_cancellation); MediumEnvironment& env_{MediumEnvironment::Instance()}; + FeatureFlags::Flags original_flags_; }; TEST_F(BluetoothBwuTest, CanCreateBwuHandler) { @@ -64,7 +73,12 @@ TEST_F(BluetoothBwuTest, CanCreateBwuHandler) { handler.reset(); } -TEST_F(BluetoothBwuTest, SoftAPBWUInit_STACreateEndpointChannel) { +void BluetoothBwuTest::RunSTACreateEndpointChannelTest( + bool enable_cancellation) { + FeatureFlags::Flags flags = original_flags_; + flags.enable_cancellation_flag = enable_cancellation; + FeatureFlags::GetMutableInstanceForTesting().SetFlags(flags); + CountDownLatch start_latch(1); CountDownLatch accept_latch(1); CountDownLatch end_latch(1); @@ -73,6 +87,9 @@ TEST_F(BluetoothBwuTest, SoftAPBWUInit_STACreateEndpointChannel) { Mediums mediums_1, mediums_2; ExceptionOr upgrade_frame; + EXPECT_TRUE(mediums_1.GetBluetoothRadio().Enable()); + EXPECT_TRUE(mediums_2.GetBluetoothRadio().Enable()); + auto handler_1 = std::make_unique( &mediums_1.GetBluetoothRadio(), &mediums_1.GetBluetoothClassic(), [&](ClientProxy* client, @@ -113,7 +130,7 @@ TEST_F(BluetoothBwuTest, SoftAPBWUInit_STACreateEndpointChannel) { handler_2->CreateUpgradedEndpointChannel(&client_2, /*service_id=*/"A", /*endpoint_id=*/"1", bwu_frame.upgrade_path_info()); - if (!FeatureFlags::GetInstance().GetFlags().enable_cancellation_flag) { + if (!enable_cancellation) { ASSERT_TRUE(result.has_value()); std::unique_ptr new_channel = std::move(result.value()); EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); @@ -122,9 +139,9 @@ TEST_F(BluetoothBwuTest, SoftAPBWUInit_STACreateEndpointChannel) { } else { EXPECT_FALSE(result.has_value()); EXPECT_TRUE(result.has_error()); - EXPECT_EQ( - result.error().operation_result_code(), - OperationResultCode::CONNECTIVITY_BLUETOOTH_DEVICE_OBTAIN_FAILURE); + EXPECT_EQ(result.error().operation_result_code(), + OperationResultCode:: + CLIENT_CANCELLATION_CANCEL_BT_OUTGOING_CONNECTION); accept_latch.CountDown(); } EXPECT_TRUE(mediums_2.GetBluetoothClassic().GetAddress().IsSet()); @@ -136,5 +153,15 @@ TEST_F(BluetoothBwuTest, SoftAPBWUInit_STACreateEndpointChannel) { EXPECT_TRUE(end_latch.Await(kWaitDuration).result()); } +TEST_F(BluetoothBwuTest, + SoftAPBWUInit_STACreateEndpointChannel_WithCancellation) { + RunSTACreateEndpointChannelTest(true); +} + +TEST_F(BluetoothBwuTest, + SoftAPBWUInit_STACreateEndpointChannel_NoCancellation) { + RunSTACreateEndpointChannelTest(false); +} + } // namespace connections } // namespace nearby diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index c4305093..5b4f0b5b 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -208,6 +208,7 @@ cc_test( srcs = [ "connection_flow_test.cc", "signaling_frames_test.cc", + "webrtc_bwu_handler_test.cc", "webrtc_impl_test.cc", "webrtc_socket_impl_test.cc", ], @@ -223,11 +224,16 @@ cc_test( ":webrtc_impl", ":webrtc_medium", ":webrtc_socket_impl", + "//connections/implementation:bwu_handler", + "//connections/implementation:client_proxy", + "//connections/implementation:endpoint_channel", + "//connections/implementation:offline_frames", "//connections/implementation/mediums:webrtc", "//connections/implementation/mediums:webrtc_peer_id", "//connections/implementation/mediums:webrtc_socket", "//internal/platform:base", "//internal/platform:cancellation_flag", + "//internal/platform:logging", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation:platform_impl", diff --git a/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc index 6c6c1dc0..1b2dac5d 100644 --- a/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc +++ b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc @@ -29,6 +29,7 @@ #include "connections/implementation/mediums/webrtc_socket.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" +#include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" #include "internal/platform/implementation/webrtc_platform.h" #include "internal/platform/logging.h" @@ -94,10 +95,11 @@ WebrtcBwuHandler::CreateUpgradedEndpointChannel( << peer_id.GetId() << ", location hint " << location_hint.location(); + std::shared_ptr cancellation_flag = + client->GetCancellationFlag(endpoint_id); ErrorOr> socket_result = webrtc_.Connect(service_id, peer_id, location_hint, - client->GetCancellationFlag(endpoint_id), - client->GetWebRtcNonCellular()); + cancellation_flag.get(), client->GetWebRtcNonCellular()); if (socket_result.has_error()) { LOG(ERROR) << "WebRtcBwuHandler failed to connect to remote peer (" << peer_id.GetId() << ") on endpoint " << endpoint_id diff --git a/connections/implementation/mediums/webrtc/webrtc_bwu_handler_test.cc b/connections/implementation/mediums/webrtc/webrtc_bwu_handler_test.cc new file mode 100644 index 00000000..fc407a65 --- /dev/null +++ b/connections/implementation/mediums/webrtc/webrtc_bwu_handler_test.cc @@ -0,0 +1,139 @@ + +// Copyright 2026 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. +#include "connections/implementation/mediums/webrtc/webrtc_bwu_handler.h" + +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/time/time.h" +#include "connections/implementation/bwu_handler.h" +#include "connections/implementation/client_proxy.h" +#include "connections/implementation/endpoint_channel.h" +#include "connections/implementation/mediums/webrtc/webrtc_impl.h" +#include "connections/implementation/offline_frames.h" +#include "internal/platform/count_down_latch.h" +#include "internal/platform/exception.h" +#include "internal/platform/expected.h" +#include "internal/platform/feature_flags.h" +#include "internal/platform/logging.h" +#include "internal/platform/medium_environment.h" +#include "internal/platform/single_thread_executor.h" +namespace nearby { +namespace connections { +namespace { +using ::location::nearby::connections::OfflineFrame; +using ::location::nearby::proto::connections::OperationResultCode; +constexpr absl::Duration kWaitDuration = absl::Milliseconds(5000); +class WebrtcBwuTest : public ::testing::Test { + protected: + WebrtcBwuTest() { + original_flags_ = FeatureFlags::GetInstance().GetFlags(); + env_.Start({.webrtc_enabled = true}); + } + ~WebrtcBwuTest() override { + FeatureFlags::GetMutableInstanceForTesting().SetFlags(original_flags_); + env_.Stop(); + } + void RunCreateEndpointChannelTest(bool enable_cancellation); + MediumEnvironment& env_{MediumEnvironment::Instance()}; + FeatureFlags::Flags original_flags_; +}; +void WebrtcBwuTest::RunCreateEndpointChannelTest(bool enable_cancellation) { + FeatureFlags::Flags flags = original_flags_; + flags.enable_cancellation_flag = enable_cancellation; + FeatureFlags::GetMutableInstanceForTesting().SetFlags(flags); + CountDownLatch start_latch(1); + CountDownLatch accept_latch(1); + CountDownLatch end_latch(1); + ClientProxy client_1, client_2; + auto webrtc_1 = std::make_unique(); + auto webrtc_2 = std::make_unique(); + ExceptionOr upgrade_frame; + std::unique_ptr handler_1 = std::make_unique( + webrtc_1.get(), + [&](ClientProxy* client, + std::unique_ptr connection) { + LOG(INFO) << "Handler 1 callback triggered"; + accept_latch.CountDown(); + }); + std::unique_ptr handler_2 = std::make_unique( + webrtc_2.get(), + [&](ClientProxy* client, + std::unique_ptr connection) { + LOG(INFO) << "Handler 2 callback triggered"; + }); + // Server starts advertising. + SingleThreadExecutor server_executor; + server_executor.Execute([&]() { + std::string upgrade_frame_bytes = + handler_1->InitializeUpgradedMediumForEndpoint( + &client_1, /*upgrade_service_id=*/"A", /*endpoint_id=*/"1"); + EXPECT_FALSE(upgrade_frame_bytes.empty()); + upgrade_frame = parser::FromBytes(upgrade_frame_bytes); + start_latch.CountDown(); + }); + // Client connects. + EXPECT_TRUE(start_latch.Await(kWaitDuration).result()); + if (enable_cancellation) { + client_2.AddCancellationFlag(/*endpoint_id=*/"1"); + client_2.GetCancellationFlag(/*endpoint_id=*/"1")->Cancel(); + } + SingleThreadExecutor client_executor; + client_executor.Execute([&]() { + auto bwu_frame = + upgrade_frame.result().v1().bandwidth_upgrade_negotiation(); + auto result = handler_2->CreateUpgradedEndpointChannel( + &client_2, /*service_id=*/"A", + /*endpoint_id=*/"1", bwu_frame.upgrade_path_info()); + if (!enable_cancellation) { + ASSERT_TRUE(result.has_value()); + std::unique_ptr new_channel = std::move(result.value()); + EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); + EXPECT_EQ(new_channel->GetMedium(), + location::nearby::proto::connections::Medium::WEB_RTC); + } else { + EXPECT_FALSE(result.has_value()); + EXPECT_TRUE(result.has_error()); + EXPECT_EQ(result.error().operation_result_code(), + OperationResultCode:: + CLIENT_CANCELLATION_CANCEL_WEB_RTC_OUTGOING_CONNECTION); + accept_latch.CountDown(); + } + handler_1->RevertResponderState(/*service_id=*/"A"); + end_latch.CountDown(); + }); + EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(end_latch.Await(kWaitDuration).result()); +} +TEST_F(WebrtcBwuTest, CanCreateBwuHandler) { + auto webrtc = std::make_unique(); + std::unique_ptr handler = std::make_unique( + webrtc.get(), + [](ClientProxy* client, + std::unique_ptr connection) {}); + EXPECT_EQ(handler->GetUpgradeMedium(), + location::nearby::proto::connections::Medium::WEB_RTC); +} +TEST_F(WebrtcBwuTest, CreateEndpointChannel_WithCancellation) { + RunCreateEndpointChannelTest(true); +} +TEST_F(WebrtcBwuTest, CreateEndpointChannel_NoCancellation) { + RunCreateEndpointChannelTest(false); +} +} // namespace +} // namespace connections +} // namespace nearby diff --git a/connections/implementation/mediums/wifi_direct_bwu_handler.cc b/connections/implementation/mediums/wifi_direct_bwu_handler.cc index 5072e922..b9925b84 100644 --- a/connections/implementation/mediums/wifi_direct_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_direct_bwu_handler.cc @@ -19,16 +19,17 @@ #include #include +#include "absl/base/nullability.h" #include "absl/functional/bind_front.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "absl/base/nullability.h" #include "connections/implementation/mediums/wifi_direct.h" #include "connections/implementation/mediums/wifi_direct_endpoint_channel.h" #include "connections/implementation/offline_frames.h" #include "connections/strategy.h" #include "internal/base/masker.h" +#include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" #include "internal/platform/logging.h" #include "internal/platform/wifi_credential.h" @@ -173,8 +174,10 @@ WifiDirectBwuHandler::CreateUpgradedEndpointChannel( OperationResultCode::CONNECTIVITY_WIFI_DIRECT_INVALID_CREDENTIAL)}; } + std::shared_ptr cancellation_flag = + client->GetCancellationFlag(endpoint_id); ErrorOr socket_result = wifi_direct_medium_.Connect( - service_id, gateway, port, client->GetCancellationFlag(endpoint_id)); + service_id, gateway, port, cancellation_flag.get()); if (socket_result.has_error()) { LOG(ERROR) << "WifiDirectBwuHandler failed to connect to the WifiDirect service(" diff --git a/connections/implementation/mediums/wifi_hotspot_bwu_handler.cc b/connections/implementation/mediums/wifi_hotspot_bwu_handler.cc index 77d14c0d..d31b8a15 100644 --- a/connections/implementation/mediums/wifi_hotspot_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_hotspot_bwu_handler.cc @@ -38,6 +38,7 @@ #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "connections/strategy.h" #include "internal/base/masker.h" +#include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" #include "internal/platform/implementation/wifi_utils.h" #include "internal/platform/logging.h" @@ -220,9 +221,11 @@ WifiHotspotBwuHandler::CreateUpgradedEndpointChannel( CONNECTIVITY_WIFI_HOTSPOT_LEGACY_STA_CONNECTION_FAILURE)}; } + std::shared_ptr cancellation_flag = + client->GetCancellationFlag(endpoint_id); ErrorOr socket_result = wifi_hotspot_medium_.Connect( service_id, hotspot_credentials.GetAddressCandidates(), - client->GetCancellationFlag(endpoint_id)); + cancellation_flag.get()); if (socket_result.has_error()) { LOG(ERROR) << "WifiHotspotBwuHandler failed to connect to the WifiHotspot " "service for endpoint " diff --git a/connections/implementation/mediums/wifi_lan_bwu_handler.cc b/connections/implementation/mediums/wifi_lan_bwu_handler.cc index e29e2f99..fca9ecef 100644 --- a/connections/implementation/mediums/wifi_lan_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_lan_bwu_handler.cc @@ -20,14 +20,15 @@ #include #include +#include "absl/base/nullability.h" #include "absl/functional/bind_front.h" #include "connections/implementation/base_bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" -#include "absl/base/nullability.h" #include "connections/implementation/mediums/wifi_lan.h" #include "connections/implementation/mediums/wifi_lan_endpoint_channel.h" #include "connections/implementation/offline_frames.h" +#include "internal/platform/cancellation_flag.h" #include "internal/platform/expected.h" #include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/logging.h" @@ -93,9 +94,10 @@ WifiLanBwuHandler::CreateUpgradedEndpointChannel( VLOG(1) << "WifiLanBwuHandler is attempting to connect to available " "WifiLan service (" << address_candidate << ") for endpoint " << endpoint_id; - ErrorOr socket_result = - wifi_lan_medium_.Connect(service_id, address_candidate, - client->GetCancellationFlag(endpoint_id)); + std::shared_ptr cancellation_flag = + client->GetCancellationFlag(endpoint_id); + ErrorOr socket_result = wifi_lan_medium_.Connect( + service_id, address_candidate, cancellation_flag.get()); if (socket_result.has_error()) { LOG(ERROR) << "WifiLanBwuHandler failed to connect to the WifiLan service (" diff --git a/connections/implementation/p2p_cluster_pcp_handler.cc b/connections/implementation/p2p_cluster_pcp_handler.cc index 76bbe1bc..9f530d60 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.cc +++ b/connections/implementation/p2p_cluster_pcp_handler.cc @@ -67,6 +67,7 @@ #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/expected.h" #include "internal/platform/implementation/platform.h" #include "internal/platform/logging.h" @@ -2015,9 +2016,10 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BluetoothConnectImpl( << endpoint->endpoint_id << ") over Bluetooth Classic."; BluetoothDevice& device = endpoint->bluetooth_device; + std::shared_ptr cancellation_flag = + client->GetCancellationFlag(endpoint->endpoint_id); ErrorOr bluetooth_socket_result = bluetooth_medium_.Connect( - device, endpoint->service_id, - client->GetCancellationFlag(endpoint->endpoint_id)); + device, endpoint->service_id, cancellation_flag.get()); if (bluetooth_socket_result.has_error()) { LOG(ERROR) << "In BluetoothConnectImpl(), failed to connect to Bluetooth device " @@ -2386,15 +2388,17 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BleConnectImpl( << " is attempting to connect to (" << peripheral.ToReadableString() << ") over BLE."; + std::shared_ptr cancellation_flag = + client->GetCancellationFlag(endpoint->endpoint_id); + if (NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature::kEnableBleL2cap) && peripheral.GetPsm() != mediums::BleAdvertisementHeader::kDefaultPsmValue) { if (refactor_ble_l2cap) { ErrorOr> ble_l2cap_socket_result = - ble_medium_.ConnectOverL2cap2( - endpoint->service_id, peripheral, - client->GetCancellationFlag(endpoint->endpoint_id)); + ble_medium_.ConnectOverL2cap2(endpoint->service_id, peripheral, + cancellation_flag.get()); if (!ble_l2cap_socket_result.has_error()) { LOG(INFO) << "In BleV2ConnectImpl(), connected to Ble L2CAP device " << absl::BytesToHexString(peripheral.GetId().data()) @@ -2416,9 +2420,8 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BleConnectImpl( } } else { ErrorOr ble_l2cap_socket_result = - ble_medium_.ConnectOverL2cap( - endpoint->service_id, peripheral, - client->GetCancellationFlag(endpoint->endpoint_id)); + ble_medium_.ConnectOverL2cap(endpoint->service_id, peripheral, + cancellation_flag.get()); if (!ble_l2cap_socket_result.has_error()) { LOG(INFO) << "In BleConnectImpl(), connected to Ble L2CAP device " << absl::BytesToHexString(peripheral.GetId().data()) @@ -2444,9 +2447,8 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BleConnectImpl( std::unique_ptr channel = nullptr; if (refactor_ble_l2cap) { ErrorOr> ble_socket_result = - ble_medium_.Connect2( - endpoint->service_id, peripheral, - client->GetCancellationFlag(endpoint->endpoint_id)); + ble_medium_.Connect2(endpoint->service_id, peripheral, + cancellation_flag.get()); if (ble_socket_result.has_error()) { LOG(ERROR) << "In BleConnectImpl(), failed to connect to BLE device " << absl::BytesToHexString(peripheral.GetId().data()) @@ -2461,9 +2463,8 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BleConnectImpl( endpoint->service_id, /*channel_name=*/endpoint->endpoint_id, std::move(ble_socket_result.value())); } else { - ErrorOr ble_socket_result = - ble_medium_.Connect(endpoint->service_id, peripheral, - client->GetCancellationFlag(endpoint->endpoint_id)); + ErrorOr ble_socket_result = ble_medium_.Connect( + endpoint->service_id, peripheral, cancellation_flag.get()); if (ble_socket_result.has_error()) { LOG(ERROR) << "In BleConnectImpl(), failed to connect to BLE device " << absl::BytesToHexString(peripheral.GetId().data()) @@ -2737,9 +2738,10 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::AwdlConnectImpl( LOG(INFO) << "Client " << client->GetClientId() << " is attempting to connect to endpoint(id=" << endpoint->endpoint_id << ") over Awdl."; - ErrorOr socket_result = - awdl_medium_.Connect(endpoint->service_id, endpoint->service_info, - client->GetCancellationFlag(endpoint->endpoint_id)); + std::shared_ptr cancellation_flag = + client->GetCancellationFlag(endpoint->endpoint_id); + ErrorOr socket_result = awdl_medium_.Connect( + endpoint->service_id, endpoint->service_info, cancellation_flag.get()); if (socket_result.has_error()) { LOG(ERROR) << "In AwdlConnectImpl(), failed to connect to service " << endpoint->service_info.GetServiceName() @@ -2773,9 +2775,10 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::WifiLanConnectImpl( LOG(INFO) << "Client " << client->GetClientId() << " is attempting to connect to endpoint(id=" << endpoint->endpoint_id << ") over WifiLan."; + std::shared_ptr cancellation_flag = + client->GetCancellationFlag(endpoint->endpoint_id); ErrorOr socket_result = wifi_lan_medium_.Connect( - endpoint->service_id, endpoint->service_info, - client->GetCancellationFlag(endpoint->endpoint_id)); + endpoint->service_id, endpoint->service_info, cancellation_flag.get()); if (socket_result.has_error()) { LOG(ERROR) << "In WifiLanConnectImpl(), failed to connect to service " << endpoint->service_info.GetServiceName() diff --git a/connections/implementation/p2p_cluster_pcp_handler_test.cc b/connections/implementation/p2p_cluster_pcp_handler_test.cc index 956856a7..5f6c813e 100644 --- a/connections/implementation/p2p_cluster_pcp_handler_test.cc +++ b/connections/implementation/p2p_cluster_pcp_handler_test.cc @@ -88,11 +88,15 @@ class P2pClusterPcpHandlerTest : public testing::Test { LOG(INFO) << "SetUp: begin"; NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature::kEnableAwdl, true); - SetBleExtendedAdvertisementsAvailable(true); + SetBleExtendedAdvertisementsAvailable(false); + } + + void TearDown() override { + NearbyFlags::GetInstance().ResetOverridedValues(); } void SetBleExtendedAdvertisementsAvailable(bool available) { - env_.SetBleExtendedAdvertisementsAvailable(false); + env_.SetBleExtendedAdvertisementsAvailable(available); } AdvertisingOptions GetBluetoothOnlyAdvertisingOptions() { @@ -141,6 +145,8 @@ class P2pClusterPcpHandlerTest : public testing::Test { return ByteArray(reinterpret_cast(bytes), 6); } + void RunCanConnectHelper(BooleanMediumSelector selector); + ClientProxy client_a_; ClientProxy client_b_; ClientProxy client_c_; @@ -148,6 +154,130 @@ class P2pClusterPcpHandlerTest : public testing::Test { MediumEnvironment& env_{MediumEnvironment::Instance()}; }; +void P2pClusterPcpHandlerTest::RunCanConnectHelper( + BooleanMediumSelector selector) { + env_.Start(); + std::string endpoint_name_a{"endpoint_name"}; + Mediums mediums_a; + Mediums mediums_b; + BluetoothRadio& radio_a = mediums_a.GetBluetoothRadio(); + BluetoothRadio& radio_b = mediums_b.GetBluetoothRadio(); + radio_a.GetBluetoothAdapter().SetName("BT Device A"); + radio_b.GetBluetoothAdapter().SetName("BT Device B"); + EndpointChannelManager ecm_a; + EndpointChannelManager ecm_b; + EndpointManager em_a(&ecm_a); + EndpointManager em_b(&ecm_b); + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, + {.allow_upgrade_to = {.bluetooth = true}}); + BwuManager bwu_b(mediums_b, em_b, ecm_b, {}, + {.allow_upgrade_to = {.bluetooth = true}}); + InjectedBluetoothDeviceStore ibds_a; + InjectedBluetoothDeviceStore ibds_b; + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a, ibds_a); + P2pClusterPcpHandler handler_b(&mediums_b, &em_b, &ecm_b, &bwu_b, ibds_b); + CountDownLatch discover_latch(1); + CountDownLatch connect_latch(2); + struct DiscoveredInfo { + std::string endpoint_id; + ByteArray endpoint_info; + std::string service_id; + } discovered; + + // Build options locally using passed selector! + AdvertisingOptions advertising_options = {{Strategy::kP2pCluster, selector}}; + DiscoveryOptions discovery_options = {{Strategy::kP2pCluster, selector}}; + ConnectionOptions connection_options = {{Strategy::kP2pCluster, selector}}; + + EXPECT_EQ( + handler_a.StartAdvertising( + &client_a_, service_id_, advertising_options, + { + .endpoint_info = ByteArray{endpoint_name_a}, + .listener = + { + .initiated_cb = + [&connect_latch](const std::string& endpoint_id, + const ConnectionResponseInfo& info) { + LOG(INFO) + << "StartAdvertising: initiated_cb called"; + connect_latch.CountDown(); + }, + }, + }), + Status{Status::kSuccess}); + EXPECT_EQ(handler_b.StartDiscovery( + &client_b_, service_id_, discovery_options, + { + .endpoint_found_cb = + [&discover_latch, &discovered]( + const std::string& endpoint_id, + const ByteArray& endpoint_info, + const std::string& service_id) { + LOG(INFO) << "Device discovered: id=" << endpoint_id + << ", endpoint_info=" + << std::string{endpoint_info}; + discovered = { + .endpoint_id = endpoint_id, + .endpoint_info = endpoint_info, + .service_id = service_id, + }; + discover_latch.CountDown(); + }, + }), + Status{Status::kSuccess}); + + EXPECT_TRUE(discover_latch.Await(absl::Milliseconds(1000)).result()); + EXPECT_EQ(endpoint_name_a, std::string{discovered.endpoint_info}); + + const std::string kBssid = "34:36:3B:C7:8C:71"; + const std::int32_t kFreq = 5200; + + connection_options.connection_info.supports_5_ghz = true; + connection_options.connection_info.bssid = kBssid; + connection_options.connection_info.ap_frequency = kFreq; + + client_b_.AddCancellationFlag(discovered.endpoint_id); + handler_b.RequestConnection( + &client_b_, discovered.endpoint_id, + {.endpoint_info = discovered.endpoint_info, + .listener = + { + .initiated_cb = + [&connect_latch](const std::string& endpoint_id, + const ConnectionResponseInfo& info) { + LOG(INFO) << "RequestConnection: initiated_cb called"; + connect_latch.CountDown(); + }, + }}, + connection_options); + std::string client_b_local_endpoint = client_b_.GetLocalEndpointId(); + + EXPECT_TRUE(connect_latch.Await(absl::Milliseconds(1000)).result()); + EXPECT_TRUE(client_b_.Is5GHzSupported(discovered.endpoint_id)); + EXPECT_EQ(client_b_.GetBssid(discovered.endpoint_id), kBssid); + EXPECT_EQ(client_b_.GetApFrequency(discovered.endpoint_id), kFreq); + // When connection is established, EndpointManager will setup KeepAliveManager + // loop. When it fails, the connection will be dismantled. Since this a unit + // test, KeepAliveManager won't be really up. The disconnection may happen + // before the following check, which cause the check fail. So we check the + // connection status first. + if (client_b_.IsConnectedToEndpoint(discovered.endpoint_id)) { + EXPECT_EQ(client_a_.Is5GHzSupported(client_b_local_endpoint), + mediums_b.GetWifi().GetCapability().supports_5_ghz); + EXPECT_EQ(client_a_.GetBssid(client_b_local_endpoint), + mediums_b.GetWifi().GetInformation().bssid); + EXPECT_EQ(client_a_.GetApFrequency(client_b_local_endpoint), + mediums_b.GetWifi().GetInformation().ap_frequency); + } + + handler_a.StopAdvertising(&client_a_); + handler_b.StopDiscovery(&client_b_); + bwu_a.Shutdown(); + bwu_b.Shutdown(); + env_.Stop(); +} + TEST_F(P2pClusterPcpHandlerTest, NoBluetoothDiscoveryWhenRadioIsOff) { env_.Start(); Mediums mediums; @@ -231,7 +361,8 @@ TEST_F(P2pClusterPcpHandlerTest, } class P2pClusterPcpHandlerTestWithParam - : public testing::TestWithParam { + : public P2pClusterPcpHandlerTest, + public ::testing::WithParamInterface { protected: void SetUp() override { LOG(INFO) << "SetUp: begin"; @@ -264,9 +395,6 @@ class P2pClusterPcpHandlerTestWithParam LOG(INFO) << "SetUp: end"; } - ClientProxy client_a_; - ClientProxy client_b_; - std::string service_id_{"service"}; ConnectionOptions connection_options_{ { Strategy::kP2pCluster, @@ -285,7 +413,6 @@ class P2pClusterPcpHandlerTestWithParam GetParam(), }, }; - MediumEnvironment& env_{MediumEnvironment::Instance()}; }; TEST_P(P2pClusterPcpHandlerTestWithParam, CanConstructOne) { @@ -900,128 +1027,21 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, } TEST_P(P2pClusterPcpHandlerTestWithParam, CanConnect) { - env_.Start(); - std::string endpoint_name_a{"endpoint_name"}; - Mediums mediums_a; - Mediums mediums_b; - BluetoothRadio& radio_a = mediums_a.GetBluetoothRadio(); - BluetoothRadio& radio_b = mediums_b.GetBluetoothRadio(); - radio_a.GetBluetoothAdapter().SetName("BT Device A"); - radio_b.GetBluetoothAdapter().SetName("BT Device B"); - EndpointChannelManager ecm_a; - EndpointChannelManager ecm_b; - EndpointManager em_a(&ecm_a); - EndpointManager em_b(&ecm_b); - BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, - {.allow_upgrade_to = {.bluetooth = true}}); - BwuManager bwu_b(mediums_b, em_b, ecm_b, {}, - {.allow_upgrade_to = {.bluetooth = true}}); - InjectedBluetoothDeviceStore ibds_a; - InjectedBluetoothDeviceStore ibds_b; - P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a, ibds_a); - P2pClusterPcpHandler handler_b(&mediums_b, &em_b, &ecm_b, &bwu_b, ibds_b); - CountDownLatch discover_latch(1); - CountDownLatch connect_latch(2); - struct DiscoveredInfo { - std::string endpoint_id; - ByteArray endpoint_info; - std::string service_id; - } discovered; - EXPECT_EQ( - handler_a.StartAdvertising( - &client_a_, service_id_, advertising_options_, - { - .endpoint_info = ByteArray{endpoint_name_a}, - .listener = - { - .initiated_cb = - [&connect_latch](const std::string& endpoint_id, - const ConnectionResponseInfo& info) { - LOG(INFO) - << "StartAdvertising: initiated_cb called"; - connect_latch.CountDown(); - }, - }, - }), - Status{Status::kSuccess}); - EXPECT_EQ(handler_b.StartDiscovery( - &client_b_, service_id_, discovery_options_, - { - .endpoint_found_cb = - [&discover_latch, &discovered]( - const std::string& endpoint_id, - const ByteArray& endpoint_info, - const std::string& service_id) { - LOG(INFO) << "Device discovered: id=" << endpoint_id - << ", endpoint_info=" - << std::string{endpoint_info}; - discovered = { - .endpoint_id = endpoint_id, - .endpoint_info = endpoint_info, - .service_id = service_id, - }; - discover_latch.CountDown(); - }, - }), - Status{Status::kSuccess}); - - EXPECT_TRUE(discover_latch.Await(absl::Milliseconds(1000)).result()); - EXPECT_EQ(endpoint_name_a, std::string{discovered.endpoint_info}); - - const std::string kBssid = "34:36:3B:C7:8C:71"; - const std::int32_t kFreq = 5200; - - connection_options_.connection_info.supports_5_ghz = true; - connection_options_.connection_info.bssid = kBssid; - connection_options_.connection_info.ap_frequency = kFreq; - - client_b_.AddCancellationFlag(discovered.endpoint_id); - handler_b.RequestConnection( - &client_b_, discovered.endpoint_id, - {.endpoint_info = discovered.endpoint_info, - .listener = - { - .initiated_cb = - [&connect_latch](const std::string& endpoint_id, - const ConnectionResponseInfo& info) { - LOG(INFO) << "RequestConnection: initiated_cb called"; - connect_latch.CountDown(); - }, - }}, - connection_options_); - std::string client_b_local_endpoint = client_b_.GetLocalEndpointId(); - - EXPECT_TRUE(connect_latch.Await(absl::Milliseconds(1000)).result()); - EXPECT_TRUE(client_b_.Is5GHzSupported(discovered.endpoint_id)); - EXPECT_EQ(client_b_.GetBssid(discovered.endpoint_id), kBssid); - EXPECT_EQ(client_b_.GetApFrequency(discovered.endpoint_id), kFreq); - // When connection is established, EndpointManager will setup KeepAliveManager - // loop. When it fails, the connection will be dismantled. Since this a unit - // test, KeepAliveManager won't be really up. The disconnection may happen - // before the following check, which cause the check fail. So we check the - // connection status first. - if (client_b_.IsConnectedToEndpoint(discovered.endpoint_id)) { - EXPECT_EQ(client_a_.Is5GHzSupported(client_b_local_endpoint), - mediums_b.GetWifi().GetCapability().supports_5_ghz); - EXPECT_EQ(client_a_.GetBssid(client_b_local_endpoint), - mediums_b.GetWifi().GetInformation().bssid); - EXPECT_EQ(client_a_.GetApFrequency(client_b_local_endpoint), - mediums_b.GetWifi().GetInformation().ap_frequency); - } - - handler_a.StopAdvertising(&client_a_); - handler_b.StopDiscovery(&client_b_); - bwu_a.Shutdown(); - bwu_b.Shutdown(); - env_.Stop(); + RunCanConnectHelper(GetParam()); } TEST_P(P2pClusterPcpHandlerTestWithParam, CanConnectWithDctEnabled) { env_.Start(); + // DCT advertisement truncates the device name to 7 bytes. + // "Test device" (11 bytes) -> "Test de" (7 bytes). + // The endpoint info is constructed by advertisements::BuildEndpointInfo which + // adds some overhead. + // For DCT, it seems to be 18 bytes prefix + truncated device name. + // 18 + 7 = 25 bytes. ByteArray endpoint_info_a{ - "\x22\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b" - "\x54\x65\x73\x74\x20\x64\x65\x76\x69\x63\x65", - 29}; + "\x22\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x07" + "Test de", + 25}; ClientProxy client_a; ClientProxy client_b; @@ -1783,5 +1803,47 @@ INSTANTIATE_TEST_SUITE_P(ParametrisedPcpHandlerTest, P2pClusterPcpHandlerTestWithParam, ::testing::ValuesIn(kTestCases)); +TEST_F(P2pClusterPcpHandlerTest, BleConnect_L2cap_Refactor) { + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_connections_feature::kEnableBleL2cap, true); + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_connections_feature::kRefactorBleL2cap, + true); + + RunCanConnectHelper({.ble = true}); +} + +TEST_F(P2pClusterPcpHandlerTest, BleConnect_NoL2cap_Refactor) { + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_connections_feature::kEnableBleL2cap, + false); + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_connections_feature::kRefactorBleL2cap, + true); + + RunCanConnectHelper({.ble = true}); +} + +TEST_F(P2pClusterPcpHandlerTest, BleConnect_NoL2cap_NoRefactor) { + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_connections_feature::kEnableBleL2cap, + false); + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_connections_feature::kRefactorBleL2cap, + false); + + RunCanConnectHelper({.ble = true}); +} + +TEST_F(P2pClusterPcpHandlerTest, BleConnect_L2cap_NoRefactor) { + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_connections_feature::kEnableBleL2cap, true); + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_connections_feature::kRefactorBleL2cap, + false); + + RunCanConnectHelper({.ble = true}); +} + } // namespace } // namespace nearby::connections From 54c155389c955afc93f13a90ec753f3f09ecb1d2 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Fri, 29 May 2026 06:03:03 -0700 Subject: [PATCH 127/151] Fix critical security vulnerability and state-machine wedge in BwuManager. PiperOrigin-RevId: 923367474 --- connections/implementation/bwu_manager.cc | 28 +++++- .../implementation/bwu_manager_test.cc | 85 +++++++++++++++++++ 2 files changed, 110 insertions(+), 3 deletions(-) diff --git a/connections/implementation/bwu_manager.cc b/connections/implementation/bwu_manager.cc index 76b93cc6..0cbafc7a 100644 --- a/connections/implementation/bwu_manager.cc +++ b/connections/implementation/bwu_manager.cc @@ -572,9 +572,19 @@ void BwuManager::OnBwuNegotiationFrame( OperationResultCode::NEARBY_GENERIC_REMOTE_UPGRADE_FAILURE); break; case BandwidthUpgradeNegotiationFrame::LAST_WRITE_TO_PRIOR_CHANNEL: + if (!in_progress_upgrades_.contains(endpoint_id)) { + LOG(ERROR) << "Received LAST_WRITE_TO_PRIOR_CHANNEL for endpoint " + << endpoint_id << " but no upgrade is in progress."; + return; + } ProcessLastWriteToPriorChannelEvent(client, endpoint_id); break; case BandwidthUpgradeNegotiationFrame::SAFE_TO_CLOSE_PRIOR_CHANNEL: + if (!in_progress_upgrades_.contains(endpoint_id)) { + LOG(ERROR) << "Received SAFE_TO_CLOSE_PRIOR_CHANNEL for endpoint " + << endpoint_id << " but no upgrade is in progress."; + return; + } ProcessSafeToClosePriorChannelEvent(client, endpoint_id); break; default: @@ -1205,9 +1215,8 @@ void BwuManager::ProcessLastWriteToPriorChannelEvent( // loss). But now that we've received this definitive final write over that // prior EndpointChannel, we can let the remote device that they can safely // close their end of this now-dormant EndpointChannel. - EndpointChannel* previous_endpoint_channel = - previous_endpoint_channels_[endpoint_id].get(); - if (!previous_endpoint_channel) { + auto it = previous_endpoint_channels_.find(endpoint_id); + if (it == previous_endpoint_channels_.end()) { LOG(ERROR) << "BwuManager received a BWU_NEGOTIATION.LAST_WRITE_TO_PRIOR_CHANNEL " "OfflineFrame for unknown endpoint " @@ -1215,6 +1224,12 @@ void BwuManager::ProcessLastWriteToPriorChannelEvent( successfully_upgraded_endpoints_.emplace(endpoint_id); return; } + EndpointChannel* previous_endpoint_channel = it->second.get(); + if (!previous_endpoint_channel) { + LOG(ERROR) << "previous_endpoint_channel is null for endpoint " + << endpoint_id; + return; + } LOG(INFO) << "ProcessLastWriteToPriorChannelEvent: service_id=" << previous_endpoint_channel->GetServiceId() @@ -1267,6 +1282,13 @@ void BwuManager::ProcessSafeToClosePriorChannelEvent( // or not (as is the case with Android's Bluetooth sockets, where closing // instantly throws an IOException on the remote device). auto item = previous_endpoint_channels_.extract(endpoint_id); + if (item.empty()) { + LOG(ERROR) + << "BwuManager received a BWU_NEGOTIATION.SAFE_TO_CLOSE_PRIOR_CHANNEL " + "OfflineFrame for unknown endpoint " + << endpoint_id << ", can't complete the upgrade protocol."; + return; + } auto& previous_endpoint_channel = item.mapped(); if (previous_endpoint_channel == nullptr) { LOG(ERROR) diff --git a/connections/implementation/bwu_manager_test.cc b/connections/implementation/bwu_manager_test.cc index dd858901..e817ad7c 100644 --- a/connections/implementation/bwu_manager_test.cc +++ b/connections/implementation/bwu_manager_test.cc @@ -1089,6 +1089,91 @@ TEST_F(BwuManagerTest, BlockBwuFrameFromAdvertiser) { UnRegisterChannelForEndpoint(kEndpointId2); } +TEST_F(BwuManagerTest, ReceiveUnexpectedSafeToClose_NoCrash) { + ExceptionOr safe_to_close_frame = + parser::FromBytes(parser::ForBwuSafeToClose()); + bwu_manager_->OnIncomingFrame(safe_to_close_frame.result(), + std::string(kEndpointId1), &client_, + Medium::BLUETOOTH); +} + +TEST_F(BwuManagerTest, ReceiveUnexpectedLastWrite_NoCrashOrWedge) { + ExceptionOr last_write_frame = + parser::FromBytes(parser::ForBwuLastWrite()); + bwu_manager_->OnIncomingFrame(last_write_frame.result(), + std::string(kEndpointId1), &client_, + Medium::BLUETOOTH); +} + +TEST_F(BwuManagerTest, ReceiveEarlyLastWrite_Success) { + CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH); + std::shared_ptr shared_initial_channel = + ecm_.GetChannelForEndpoint(std::string(kEndpointId1)); + + bwu_manager_->InitiateBwuForEndpoint(&client_, std::string(kEndpointId1), + Medium::WEB_RTC); + ASSERT_TRUE(bwu_manager_->IsUpgradeOngoing(std::string(kEndpointId1))); + + ExceptionOr last_write_frame = + parser::FromBytes(parser::ForBwuLastWrite()); + bwu_manager_->OnIncomingFrame(last_write_frame.result(), + std::string(kEndpointId1), &client_, + Medium::BLUETOOTH); + + FakeEndpointChannel* upgraded_channel = + fake_web_rtc_bwu_handler_->NotifyBwuManagerOfIncomingConnection( + /*initialize_call_index=*/0u, bwu_manager_.get()); + + ExceptionOr safe_to_close_frame = + parser::FromBytes(parser::ForBwuSafeToClose()); + bwu_manager_->OnIncomingFrame(safe_to_close_frame.result(), + std::string(kEndpointId1), &client_, + Medium::BLUETOOTH); + + auto old_channel = + dynamic_cast(shared_initial_channel.get()); + EXPECT_FALSE(upgraded_channel->IsPaused()); + EXPECT_TRUE(old_channel->is_closed()); + EXPECT_EQ(location::nearby::proto::connections::DisconnectionReason::UPGRADED, + old_channel->disconnection_reason()); + UnRegisterChannelForEndpoint(kEndpointId1); +} + +TEST_F(BwuManagerTest, ReceiveUnexpectedLastWriteBeforeUpgrade_NoWedge) { + ExceptionOr last_write_frame = + parser::FromBytes(parser::ForBwuLastWrite()); + bwu_manager_->OnIncomingFrame(last_write_frame.result(), + std::string(kEndpointId1), &client_, + Medium::BLUETOOTH); + + CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH); + std::shared_ptr shared_initial_channel = + ecm_.GetChannelForEndpoint(std::string(kEndpointId1)); + + bwu_manager_->InitiateBwuForEndpoint(&client_, std::string(kEndpointId1), + Medium::WEB_RTC); + + FakeEndpointChannel* upgraded_channel = + fake_web_rtc_bwu_handler_->NotifyBwuManagerOfIncomingConnection( + /*initialize_call_index=*/0u, bwu_manager_.get()); + + bwu_manager_->OnIncomingFrame(last_write_frame.result(), + std::string(kEndpointId1), &client_, + Medium::BLUETOOTH); + + ExceptionOr safe_to_close_frame = + parser::FromBytes(parser::ForBwuSafeToClose()); + bwu_manager_->OnIncomingFrame(safe_to_close_frame.result(), + std::string(kEndpointId1), &client_, + Medium::BLUETOOTH); + + auto old_channel = + dynamic_cast(shared_initial_channel.get()); + EXPECT_FALSE(upgraded_channel->IsPaused()); + EXPECT_TRUE(old_channel->is_closed()); + UnRegisterChannelForEndpoint(kEndpointId1); +} + INSTANTIATE_TEST_SUITE_P(BwuManagerTestParam, BwuManagerTestParam, testing::Bool()); From ab1183e2b44729e5132945a196cb7a75280ffec3 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Fri, 29 May 2026 22:07:16 -0700 Subject: [PATCH 128/151] [Nearby Connections] Fix ServerSocket resource leak in WiFi LAN BWU Handler. PiperOrigin-RevId: 923759039 --- .../mediums/wifi_lan_bwu_handler.cc | 5 ++ .../mediums/wifi_lan_bwu_handler_test.cc | 66 +++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/connections/implementation/mediums/wifi_lan_bwu_handler.cc b/connections/implementation/mediums/wifi_lan_bwu_handler.cc index fca9ecef..a25cd81c 100644 --- a/connections/implementation/mediums/wifi_lan_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_lan_bwu_handler.cc @@ -124,6 +124,7 @@ WifiLanBwuHandler::CreateUpgradedEndpointChannel( std::string WifiLanBwuHandler::HandleInitializeUpgradedMediumForEndpoint( ClientProxy* client, const std::string& upgrade_service_id, const std::string& endpoint_id) { + bool started_accepting = false; if (!wifi_lan_medium_.IsAcceptingConnections(upgrade_service_id)) { if (!wifi_lan_medium_.StartAcceptingConnections( upgrade_service_id, @@ -140,6 +141,7 @@ std::string WifiLanBwuHandler::HandleInitializeUpgradedMediumForEndpoint( << "WifiLanBwuHandler successfully started listening for incoming " "WifiLan connections while upgrading endpoint " << endpoint_id; + started_accepting = true; } // Address candidates are not populated until StartAcceptingConnections() is @@ -151,6 +153,9 @@ std::string WifiLanBwuHandler::HandleInitializeUpgradedMediumForEndpoint( 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."; + if (started_accepting) { + wifi_lan_medium_.StopAcceptingConnections(upgrade_service_id); + } return {}; } client->GetAnalyticsRecorder().UpdateBwUpgradeNetworkInfo( diff --git a/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc b/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc index 24074701..600c8474 100644 --- a/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc +++ b/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc @@ -39,6 +39,7 @@ #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/platform/wifi_lan.h" #include "internal/proto/analytics/connections_log.pb.h" namespace nearby { @@ -344,6 +345,71 @@ TEST_F(WifiLanBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { client.GetAnalyticsRecorder().LogSession(); } +TEST_F(WifiLanBwuHandlerTest, + InitializeUpgradedMediumForEndpoint_EmptyCandidates_StopsAccepting) { + MediumEnvironment::Instance().Start({.use_simulated_clock = true}); + ClientProxy client(&mock_event_logger_); + client.AddCancellationFlag(std::string(kEndpointId)); + + auto mock_server_socket = std::make_unique(); + MockWifiLanServerSocket* raw_server_socket = mock_server_socket.get(); + + EXPECT_CALL(*raw_server_socket, GetPort()).WillRepeatedly(Return(8080)); + EXPECT_CALL(*wifi_lan_medium, IsNetworkConnected()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*wifi_lan_medium, ListenForService(_)) + .WillOnce(Return(ByMove(std::move(mock_server_socket)))); + + EXPECT_CALL(*wifi_lan_medium, GetUpgradeAddressCandidates(_)) + .WillOnce(Return(api::UpgradeAddressInfo{.num_interfaces = 0, + .num_ipv6_only_interfaces = 0, + .address_candidates = {}})); + + std::string result = handler_.InitializeUpgradedMediumForEndpoint( + &client, std::string(kServiceId), std::string(kEndpointId)); + + EXPECT_TRUE(result.empty()); + EXPECT_FALSE( + mediums_.GetWifiLan().IsAcceptingConnections("service_id_UPGRADE")); +} + +TEST_F( + WifiLanBwuHandlerTest, + InitializeUpgradedMediumForEndpoint_AlreadyAccepting_KeepAccepting) { + MediumEnvironment::Instance().Start({.use_simulated_clock = true}); + ClientProxy client(&mock_event_logger_); + client.AddCancellationFlag(std::string(kEndpointId)); + + auto mock_server_socket = std::make_unique(); + MockWifiLanServerSocket* raw_server_socket = mock_server_socket.get(); + + EXPECT_CALL(*raw_server_socket, GetPort()).WillRepeatedly(Return(8080)); + EXPECT_CALL(*wifi_lan_medium, IsNetworkConnected()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*wifi_lan_medium, ListenForService(_)) + .WillOnce(Return(ByMove(std::move(mock_server_socket)))); + + EXPECT_TRUE( + mediums_.GetWifiLan() + .StartAcceptingConnections("service_id_UPGRADE", + [](const std::string&, WifiLanSocket) {}) + .has_value()); + EXPECT_TRUE( + mediums_.GetWifiLan().IsAcceptingConnections("service_id_UPGRADE")); + + EXPECT_CALL(*wifi_lan_medium, GetUpgradeAddressCandidates(_)) + .WillOnce(Return(api::UpgradeAddressInfo{.num_interfaces = 0, + .num_ipv6_only_interfaces = 0, + .address_candidates = {}})); + + std::string result = handler_.InitializeUpgradedMediumForEndpoint( + &client, std::string(kServiceId), std::string(kEndpointId)); + + EXPECT_TRUE(result.empty()); + EXPECT_TRUE( + mediums_.GetWifiLan().IsAcceptingConnections("service_id_UPGRADE")); +} + } // namespace } // namespace connections namespace api { From 736cbb280e87ce7ac3ee8054aad9452073e2461e Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Sun, 31 May 2026 18:51:58 -0700 Subject: [PATCH 129/151] Internal PiperOrigin-RevId: 924405158 --- Package.swift | 1 + connections/BUILD | 2 +- connections/c/BUILD | 2 + connections/c/nc.cc | 21 +- connections/c/nc.h | 2 + connections/core.h | 6 +- connections/implementation/BUILD | 7 +- connections/implementation/analytics/BUILD | 23 +- .../analytics/mock_analytics_recorder.h | 196 +++++++++++ .../implementation/base_pcp_handler.cc | 47 +-- connections/implementation/base_pcp_handler.h | 7 +- .../implementation/base_pcp_handler_test.cc | 136 ++------ connections/implementation/client_proxy.cc | 155 ++++++++- connections/implementation/client_proxy.h | 5 +- .../implementation/client_proxy_test.cc | 137 ++++---- connections/implementation/mediums/BUILD | 3 - .../mediums/awdl_bwu_handler_test.cc | 97 +----- .../mediums/wifi_lan_bwu_handler_test.cc | 98 +----- .../implementation/p2p_cluster_pcp_handler.cc | 309 +++++++----------- .../implementation/p2p_cluster_pcp_handler.h | 5 +- connections/implementation/payload_manager.cc | 2 - sharing/BUILD | 1 + sharing/nearby_connections_service_impl.cc | 5 +- 23 files changed, 655 insertions(+), 612 deletions(-) create mode 100644 connections/implementation/analytics/mock_analytics_recorder.h diff --git a/Package.swift b/Package.swift index 50e2600f..81150eaa 100644 --- a/Package.swift +++ b/Package.swift @@ -562,6 +562,7 @@ let package = Package( .headerSearchPath("./"), .headerSearchPath("compiled_proto/"), .define("NO_WEBRTC"), + .define("NC_OSS_BUILD"), ] ), .target( diff --git a/connections/BUILD b/connections/BUILD index 78928b9e..f850f505 100644 --- a/connections/BUILD +++ b/connections/BUILD @@ -46,8 +46,8 @@ cc_library( "//connections/implementation:client_proxy", "//connections/implementation:internal", "//connections/implementation:service_id_constants", + "//connections/implementation/analytics", "//connections/v3:v3_types", - "//internal/analytics:event_logger", "//internal/interop:device", "//internal/platform:base", "//internal/platform:logging", diff --git a/connections/c/BUILD b/connections/c/BUILD index 7d74e9bd..b747460e 100644 --- a/connections/c/BUILD +++ b/connections/c/BUILD @@ -51,6 +51,7 @@ cc_library( ":nc_types", "//connections:core", "//connections:core_types", + "//connections/implementation/analytics:analytics_recorder_impl", "//connections/implementation/flags:connections_flags", "//internal/analytics:event_logger", "//internal/flags:flag_reader", @@ -74,6 +75,7 @@ cc_library( ], "//conditions:default": [], }), + alwayslink = True, ) # iOS only. diff --git a/connections/c/nc.cc b/connections/c/nc.cc index e251f77c..5d631859 100644 --- a/connections/c/nc.cc +++ b/connections/c/nc.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,9 @@ #include "connections/connection_options.h" #include "connections/core.h" #include "connections/discovery_options.h" +#if !defined(NC_OSS_BUILD) +#include "connections/implementation/analytics/analytics_recorder_impl.h" +#endif // !defined(NC_OSS_BUILD) #include "connections/listeners.h" #include "connections/medium_selector.h" #include "connections/out_of_band_connection_metadata.h" @@ -244,6 +248,7 @@ NcContext* GetContext(NC_INSTANCE instance) { return cpp_connection_request_info; } +#if !defined(NC_OSS_BUILD) NC_INSTANCE NcCreateService() { return NcCreateServiceWithEventLogger(nullptr); } @@ -259,12 +264,24 @@ NcCreateServiceWithEventLogger(const NC_EVENT_LOGGER* event_logger) { nc_context.router = new ::nearby::connections::ServiceControllerRouter(); nc_context.event_logger = event_logger == nullptr ? nullptr : new NcEventLogger(event_logger); - nc_context.core = new ::nearby::connections::Core(nc_context.event_logger, - nc_context.router); + nc_context.core = new ::nearby::connections::Core( + std::make_unique<::nearby::analytics::AnalyticsRecorderImpl>( + nc_context.event_logger), + nc_context.router); kNcContextMap->insert({nc_context.core, nc_context}); return nc_context.core; } +#else // !defined(NC_OSS_BUILD) +NC_INSTANCE NcCreateService() { + NcContext nc_context; + nc_context.router = new ::nearby::connections::ServiceControllerRouter(); + nc_context.core = new ::nearby::connections::Core(nc_context.router); + + kNcContextMap->insert({nc_context.core, nc_context}); + return nc_context.core; +} +#endif // !defined(NC_OSS_BUILD) void NcCloseService(NC_INSTANCE instance) { NcContext* nc_context = GetContext(instance); diff --git a/connections/c/nc.h b/connections/c/nc.h index b3dd2505..cc00735f 100644 --- a/connections/c/nc.h +++ b/connections/c/nc.h @@ -27,11 +27,13 @@ extern "C" { // Creates a new Nearby Connections service. NC_API NC_INSTANCE NcCreateService(); +#if !defined(NC_OSS_BUILD) // Creates a new Nearby Connections service with an event logger. // The passed-in |event_logger| must remain valid until NcCloseService() is // called. NC_API NC_INSTANCE NcCreateServiceWithEventLogger(const NC_EVENT_LOGGER* event_logger); +#endif // !defined(NC_OSS_BUILD) // Closes a Nearby Connections service. NC_API void NcCloseService(NC_INSTANCE instance); diff --git a/connections/core.h b/connections/core.h index 69edb815..b72ebc6d 100644 --- a/connections/core.h +++ b/connections/core.h @@ -25,6 +25,7 @@ #include "connections/advertising_options.h" #include "connections/connection_options.h" #include "connections/discovery_options.h" +#include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/service_controller_router.h" #include "connections/listeners.h" @@ -37,7 +38,6 @@ #include "connections/v3/discovery_options.h" #include "connections/v3/listeners.h" #include "connections/v3/listening_result.h" -#include "internal/analytics/event_logger.h" #include "internal/interop/device.h" #include "internal/interop/device_provider.h" @@ -49,9 +49,9 @@ class Core { public: explicit Core(ServiceControllerRouter* router); // Client needs to call this constructor if analytics logger is needed. - Core(::nearby::analytics::EventLogger* event_logger, + Core(std::unique_ptr analytics_recorder, ServiceControllerRouter* router) - : client_(event_logger), router_(router) {} + : client_(std::move(analytics_recorder)), router_(router) {} ~Core(); Core(Core&&); Core& operator=(Core&&); diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 1dd42abe..4f026fbb 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -112,12 +112,10 @@ cc_library( deps = [ "//connections:core_types", "//connections/implementation/analytics", - "//connections/implementation/analytics:analytics_recorder_impl", "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums/advertisements:dct_advertisement", "//connections/implementation/proto:offline_wire_formats_cc_proto", "//connections/v3:v3_types", - "//internal/analytics:event_logger", "//internal/base:file_path", "//internal/base:files", "//internal/flags:nearby_flags", @@ -392,12 +390,13 @@ cc_test( ":offline_frames", ":types", "//connections:core_types", + "//connections/implementation/analytics", + "//connections/implementation/analytics:mock_analytics_recorder", "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums", "//connections/implementation/mediums:webrtc_peer_id", "//connections/implementation/proto:offline_wire_formats_cc_proto", "//connections/v3:v3_types", - "//internal/analytics:mock_event_logger", "//internal/flags:nearby_flags", "//internal/interop:authentication_status", "//internal/interop:authentication_transport_interface", @@ -408,7 +407,6 @@ cc_test( "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/proto/analytics:connections_log_cc_proto", "//proto:connections_enums_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/base:core_headers", @@ -467,6 +465,7 @@ cc_test( deps = [ ":client_proxy", "//connections:core_types", + "//connections/implementation/analytics:mock_analytics_recorder", "//connections/implementation/flags:connections_flags", "//connections/v3:v3_types", "//internal/analytics:mock_event_logger", diff --git a/connections/implementation/analytics/BUILD b/connections/implementation/analytics/BUILD index 0e47a452..006a2292 100644 --- a/connections/implementation/analytics/BUILD +++ b/connections/implementation/analytics/BUILD @@ -47,7 +47,10 @@ cc_library( "analytics_recorder_impl.h", ], copts = ["-DCORE_ADAPTER_DLL"], - visibility = ["//connections/implementation:__pkg__"], + visibility = [ + "//connections/c:__pkg__", + "//sharing:__pkg__", + ], deps = [ ":analytics", "//connections:core_types", @@ -67,6 +70,24 @@ cc_library( ], ) +cc_library( + name = "mock_analytics_recorder", + testonly = True, + hdrs = [ + "mock_analytics_recorder.h", + ], + compatible_with = ["//buildenv/target:non_prod"], + visibility = ["//connections:__subpackages__"], + deps = [ + ":analytics", + "//connections:core_types", + "//internal/platform:error_code_recorder", + "//proto:connections_enums_cc_proto", + "@com_google_absl//absl/time", + "@com_google_googletest//:gtest_for_library_testonly", + ], +) + cc_test( name = "analytics_test", size = "small", diff --git a/connections/implementation/analytics/mock_analytics_recorder.h b/connections/implementation/analytics/mock_analytics_recorder.h new file mode 100644 index 00000000..d407d98b --- /dev/null +++ b/connections/implementation/analytics/mock_analytics_recorder.h @@ -0,0 +1,196 @@ +// Copyright 2026 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 ANALYTICS_MOCK_ANALYTICS_RECORDER_H_ +#define ANALYTICS_MOCK_ANALYTICS_RECORDER_H_ + +#include +#include +#include + +#include "gmock/gmock.h" +#include "absl/time/time.h" +#include "connections/implementation/analytics/advertising_metadata_params.h" +#include "connections/implementation/analytics/analytics_recorder.h" +#include "connections/implementation/analytics/connection_attempt_metadata_params.h" +#include "connections/implementation/analytics/discovery_metadata_params.h" +#include "connections/payload_type.h" +#include "connections/strategy.h" +#include "internal/platform/error_code_params.h" +#include "proto/connections_enums.pb.h" + +namespace nearby::analytics { + +class MockAnalyticsRecorder : public AnalyticsRecorder { + public: + MockAnalyticsRecorder() = default; + ~MockAnalyticsRecorder() override = default; + + // Advertising phase + MOCK_METHOD(void, OnStartAdvertising, + (connections::Strategy strategy, + const std::vector& + mediums, + AdvertisingMetadataParams* advertising_metadata_params), + (override)); + MOCK_METHOD(void, OnStopAdvertising, (), (override)); + + MOCK_METHOD(int, GetNextAdvertisingUpdateIndex, (), (override)); + + // Connection listening + MOCK_METHOD(void, OnStartedIncomingConnectionListening, + (connections::Strategy strategy), (override)); + MOCK_METHOD(void, OnStoppedIncomingConnectionListening, (), (override)); + + // Discovery phase + MOCK_METHOD(void, OnStartDiscovery, + (connections::Strategy strategy, + const std::vector& + mediums, + DiscoveryMetadataParams* discovery_metadata_params), + (override)); + MOCK_METHOD(void, OnStopDiscovery, (), (override)); + + MOCK_METHOD(int, GetNextDiscoveryUpdateIndex, (), (override)); + MOCK_METHOD(void, OnEndpointFound, + (location::nearby::proto::connections::Medium medium), + (override)); + + // Connection request + MOCK_METHOD(void, OnRequestConnection, + (const connections::Strategy& strategy, + const std::string& endpoint_id), + (override)); + + MOCK_METHOD(void, OnConnectionRequestReceived, + (const std::string& remote_endpoint_id), (override)); + MOCK_METHOD(void, OnConnectionRequestSent, + (const std::string& remote_endpoint_id), (override)); + MOCK_METHOD(void, OnRemoteEndpointAccepted, + (const std::string& remote_endpoint_id), (override)); + MOCK_METHOD(void, OnLocalEndpointAccepted, + (const std::string& remote_endpoint_id), (override)); + MOCK_METHOD(void, OnRemoteEndpointRejected, + (const std::string& remote_endpoint_id), (override)); + MOCK_METHOD(void, OnLocalEndpointRejected, + (const std::string& remote_endpoint_id), (override)); + + // Connection attempt + MOCK_METHOD( + void, OnIncomingConnectionAttempt, + (location::nearby::proto::connections::ConnectionAttemptType type, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::ConnectionAttemptResult result, + absl::Duration duration, const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params), + (override)); + MOCK_METHOD( + void, OnOutgoingConnectionAttempt, + (const std::string& remote_endpoint_id, + location::nearby::proto::connections::ConnectionAttemptType type, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::ConnectionAttemptResult result, + absl::Duration duration, const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params), + (override)); + + // Connection established + MOCK_METHOD(void, OnConnectionEstablished, + (const std::string& endpoint_id, + location::nearby::proto::connections::Medium medium, + const std::string& connection_token), + (override)); + MOCK_METHOD(void, OnConnectionClosed, + (const std::string& endpoint_id, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::DisconnectionReason reason, + SafeDisconnectionResult result), + (override)); + + // Payload + MOCK_METHOD(void, OnIncomingPayloadStarted, + (const std::string& endpoint_id, std::int64_t payload_id, + connections::PayloadType type, std::int64_t total_size_bytes), + (override)); + MOCK_METHOD(void, OnPayloadChunkReceived, + (const std::string& endpoint_id, std::int64_t payload_id, + std::int64_t chunk_size_bytes), + (override)); + MOCK_METHOD(void, OnIncomingPayloadDone, + (const std::string& endpoint_id, std::int64_t payload_id, + location::nearby::proto::connections::PayloadStatus status, + location::nearby::proto::connections::OperationResultCode + operation_result_code), + (override)); + MOCK_METHOD(void, OnOutgoingPayloadStarted, + (const std::vector& endpoint_ids, + std::int64_t payload_id, connections::PayloadType type, + std::int64_t total_size_bytes), + (override)); + MOCK_METHOD(void, OnPayloadChunkSent, + (const std::string& endpoint_id, std::int64_t payload_id, + std::int64_t chunk_size_bytes), + (override)); + MOCK_METHOD(void, OnOutgoingPayloadDone, + (const std::string& endpoint_id, std::int64_t payload_id, + location::nearby::proto::connections::PayloadStatus status, + location::nearby::proto::connections::OperationResultCode + operation_result_code), + (override)); + + // BandwidthUpgrade + MOCK_METHOD(void, OnBandwidthUpgradeStarted, + (const std::string& endpoint_id, + location::nearby::proto::connections::Medium from_medium, + location::nearby::proto::connections::Medium to_medium, + location::nearby::proto::connections::ConnectionAttemptDirection + direction, + const std::string& connection_token), + (override)); + MOCK_METHOD(void, UpdateBwUpgradeNetworkInfo, + (const std::string& endpoint_id, int num_interfaces, + int num_ipv6_only_interfaces), + (override)); + MOCK_METHOD(void, OnBandwidthUpgradeError, + (const std::string& endpoint_id, + location::nearby::proto::connections::BandwidthUpgradeResult + result, + location::nearby::proto::connections::BandwidthUpgradeErrorStage + error_stage, + location::nearby::proto::connections::OperationResultCode + operation_result_code), + (override)); + MOCK_METHOD(void, OnBandwidthUpgradeSuccess, (const std::string& endpoint_id), + (override)); + + // Error Code + MOCK_METHOD(void, OnErrorCode, (const ErrorCodeParams& params), (override)); + + MOCK_METHOD(void, LogStartSession, (), (override)); + MOCK_METHOD(void, LogSession, (), (override)); + + MOCK_METHOD(bool, IsSessionLogged, (), (override)); + + MOCK_METHOD( + location::nearby::proto::connections::OperationResultCategory, + GetOperationResultCategory, + (location::nearby::proto::connections::OperationResultCode result_code), + (override)); + + MOCK_METHOD(void, Sync, (), (override)); +}; + +} // namespace nearby::analytics + +#endif // ANALYTICS_MOCK_ANALYTICS_RECORDER_H_ diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 85a82eae..07f033ed 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -53,7 +53,6 @@ #include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/pcp.h" -#include "connections/implementation/proto/offline_wire_formats.pb.h" #include "connections/implementation/webrtc_state.h" #include "connections/listeners.h" #include "connections/medium_selector.h" @@ -86,12 +85,10 @@ #include "internal/platform/runnable.h" #include "internal/platform/wifi.h" #include "internal/platform/wifi_lan_connection_info.h" -#include "proto/connections_enums.pb.h" namespace nearby::connections { namespace { -using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::connections::ConnectionRequestFrame; using ::location::nearby::connections::ConnectionResponseFrame; using ::location::nearby::connections::ConnectionsDevice; @@ -103,6 +100,7 @@ using ::location::nearby::connections::V1Frame; using ::location::nearby::proto::connections::OperationResultCode; using ::location::nearby::proto::connections::WifiDirectAuthType; using ::nearby::analytics::AnalyticsRecorder; +using ::nearby::analytics::OperationResultWithMedium; using ::securegcm::UKey2Handshake; constexpr int kEndpointCancelAlarmTimeout = 10; @@ -118,28 +116,6 @@ std::string AuthenticationStatusToString(nearby::AuthenticationStatus status) { } } -std::vector -ConvertToCppOperationResultWithMediums( - const std::vector& - proto_results) { - std::vector cpp_results; - cpp_results.reserve(proto_results.size()); - for (const auto& proto_result : proto_results) { - analytics::OperationResultWithMedium cpp_result; - cpp_result.medium = proto_result.medium(); - if (proto_result.has_update_index()) { - cpp_result.update_index = proto_result.update_index(); - } - cpp_result.result_category = proto_result.result_category(); - cpp_result.result_code = proto_result.result_code(); - if (proto_result.has_connection_mode()) { - cpp_result.connection_mode = proto_result.connection_mode(); - } - cpp_results.push_back(cpp_result); - } - return cpp_results; -} - } // namespace BasePcpHandler::BasePcpHandler(Mediums* mediums, @@ -306,8 +282,7 @@ Status BasePcpHandler::StartAdvertising( advertising_listener_ = info.listener; client->StartedAdvertising(service_id, GetStrategy(), info.listener, absl::MakeSpan(result.mediums), - ConvertToCppOperationResultWithMediums( - result.operation_result_with_mediums), + result.operation_result_with_mediums, compatible_advertising_options); client->UpdateLocalEndpointInfo(info.endpoint_info.string_data()); response.Set({Status::kSuccess}); @@ -538,8 +513,7 @@ Status BasePcpHandler::StartDiscovery(ClientProxy* client, client->StartedDiscovery(service_id, GetStrategy(), std::move(listener), absl::MakeSpan(result.mediums), - ConvertToCppOperationResultWithMediums( - result.operation_result_with_mediums), + result.operation_result_with_mediums, stripped_discovery_options); response.Set({Status::kSuccess}); }); @@ -1324,22 +1298,21 @@ void BasePcpHandler::StripOutUnavailableMediums( } } -std::unique_ptr +OperationResultWithMedium BasePcpHandler::GetOperationResultWithMediumByResultCode( ClientProxy* client, location::nearby::proto::connections::Medium medium, int update_index, location::nearby::proto::connections::OperationResultCode operation_result_code, location::nearby::proto::connections::ConnectionMode connection_mode) { - auto operation_result_with_medium = - std::make_unique(); - operation_result_with_medium->set_medium(medium); - operation_result_with_medium->set_result_code(operation_result_code); - operation_result_with_medium->set_result_category( + OperationResultWithMedium operation_result_with_medium; + operation_result_with_medium.set_medium(medium); + operation_result_with_medium.set_result_code(operation_result_code); + operation_result_with_medium.set_result_category( client->GetAnalyticsRecorder().GetOperationResultCategory( operation_result_code)); - operation_result_with_medium->set_connection_mode(connection_mode); - operation_result_with_medium->set_update_index(update_index); + operation_result_with_medium.set_connection_mode(connection_mode); + operation_result_with_medium.set_update_index(update_index); return operation_result_with_medium; } diff --git a/connections/implementation/base_pcp_handler.h b/connections/implementation/base_pcp_handler.h index 4dda6590..49cf0b70 100644 --- a/connections/implementation/base_pcp_handler.h +++ b/connections/implementation/base_pcp_handler.h @@ -31,6 +31,7 @@ #include "connections/advertising_options.h" #include "connections/connection_options.h" #include "connections/discovery_options.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" #include "connections/implementation/bwu_manager.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/encryption_runner.h" @@ -189,8 +190,7 @@ class BasePcpHandler : public PcpHandler, // If success, the mediums on which we are now advertising/discovering, for // analytics. std::vector mediums; - std::vector + std::vector operation_result_with_mediums; }; @@ -412,8 +412,7 @@ class BasePcpHandler : public PcpHandler, void StripOutWifiHotspotMedium(ConnectionInfo& connection_info); - std::unique_ptr + nearby::analytics::OperationResultWithMedium GetOperationResultWithMediumByResultCode( ClientProxy* client, location::nearby::proto::connections::Medium medium, int update_index, diff --git a/connections/implementation/base_pcp_handler_test.cc b/connections/implementation/base_pcp_handler_test.cc index 4313a5e3..b8cef7e5 100644 --- a/connections/implementation/base_pcp_handler_test.cc +++ b/connections/implementation/base_pcp_handler_test.cc @@ -32,6 +32,8 @@ #include "connections/advertising_options.h" #include "connections/connection_options.h" #include "connections/discovery_options.h" +#include "connections/implementation/analytics/analytics_recorder.h" +#include "connections/implementation/analytics/mock_analytics_recorder.h" #include "connections/implementation/base_endpoint_channel.h" #include "connections/implementation/bwu_manager.h" #include "connections/implementation/client_proxy.h" @@ -54,8 +56,6 @@ #include "connections/status.h" #include "connections/strategy.h" #include "connections/v3/connection_listening_options.h" -#include "internal/analytics/mock_event_logger.h" -#include "internal/analytics/sharing_log_matchers.h" #include "internal/flags/nearby_flags.h" #include "internal/interop/authentication_status.h" #include "internal/interop/authentication_transport.h" @@ -71,28 +71,21 @@ #include "internal/platform/medium_environment.h" #include "internal/platform/output_stream.h" #include "internal/platform/pipe.h" -#include "internal/proto/analytics/connections_log.pb.h" #include "proto/connections_enums.pb.h" #include "proto/connections_enums.proto.h" -namespace nearby { -namespace connections { +namespace nearby::connections { namespace { -using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::connections::OsInfo; -using ::location::nearby::proto::connections::EventType; using ::location::nearby::proto::connections::Medium; -using ::nearby::analytics::HasEventType; using ::testing::_; using ::testing::AtLeast; -using ::protobuf_matchers::EqualsProto; using ::testing::Matcher; using ::testing::MockFunction; using ::testing::NiceMock; using ::testing::Return; using ::testing::StrictMock; -using ::testing::proto::Partially; constexpr absl::string_view kTestEndpointId = "REMOTETEST"; @@ -452,7 +445,7 @@ class BasePcpHandlerTest }; BasePcpHandlerTest() { - client_ = std::make_unique(&mock_event_logger_); + client_ = std::make_unique(CreateAnalyticsRecorder()); } void SetUp() override { @@ -461,6 +454,13 @@ class BasePcpHandlerTest void TearDown() override { env_.Stop(); } + std::unique_ptr CreateAnalyticsRecorder() { + auto recorder = + std::make_unique(); + mock_analytics_recorder_ptr_ = recorder.get(); + return recorder; + } + void StartAdvertising(ClientProxy* client, MockPcpHandler* pcp_handler, BooleanMediumSelector allowed = GetParam()) { AdvertisingOptions advertising_options{ @@ -896,7 +896,7 @@ class BasePcpHandlerTest MediumEnvironment& env_ = MediumEnvironment::Instance(); NiceMock mock_device_; MacAddress remote_mac_address_; - nearby::analytics::MockEventLogger mock_event_logger_; + nearby::analytics::MockAnalyticsRecorder* mock_analytics_recorder_ptr_; std::unique_ptr client_; }; @@ -2555,7 +2555,7 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForConnectionsWithPresence) { TEST_F(BasePcpHandlerTest, IncomingConnectionFailsWithEmptyEndpointId) { env_.Start({.use_simulated_clock = true}); - client_ = std::make_unique(&mock_event_logger_); + client_ = std::make_unique(CreateAnalyticsRecorder()); Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); @@ -2572,6 +2572,8 @@ TEST_F(BasePcpHandlerTest, IncomingConnectionFailsWithEmptyEndpointId) { MockPcpHandler::StartOperationResult{.status = {Status::kSuccess}})); EXPECT_CALL(pcp_handler, CanReceiveIncomingConnection) .WillRepeatedly(Return(true)); + EXPECT_CALL(*mock_analytics_recorder_ptr_, + OnStartedIncomingConnectionListening(_)); EXPECT_TRUE(pcp_handler .StartListeningForIncomingConnections(client_.get(), "service", options, {}) @@ -2593,45 +2595,13 @@ TEST_F(BasePcpHandlerTest, IncomingConnectionFailsWithEmptyEndpointId) { // do a dummy write to get to the actual write. channel_pair.first->Write(""); channel_pair.first->Write(frame.SerializeAsString()); - absl::string_view expected_log = R"pb( - event_type: CLIENT_SESSION - client_session { - strategy_session { - connection_attempt { - type: INITIAL - direction: INCOMING - medium: BLUETOOTH - attempt_result: RESULT_ERROR - operation_result { - result_category: CATEGORY_CONNECTIVITY_ERROR - result_code: CONNECTIVITY_CHANNEL_IO_ERROR_ON_BT - } - } - } - } - )pb"; - absl::string_view client_session_log = R"pb( - event_type: CLIENT_SESSION - 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(Partially( - EqualsProto(client_session_log))))) - .Times(2); - EXPECT_CALL(mock_event_logger_, Log(Matcher( - Partially(EqualsProto(expected_log))))); - + EXPECT_CALL(*mock_analytics_recorder_ptr_, LogSession()).Times(3); + EXPECT_CALL(*mock_analytics_recorder_ptr_, LogStartSession()).Times(3); + EXPECT_CALL( + *mock_analytics_recorder_ptr_, + OnIncomingConnectionAttempt( + location::nearby::proto::connections::INITIAL, Medium::BLUETOOTH, + location::nearby::proto::connections::RESULT_ERROR, _, _, _)); EXPECT_EQ(pcp_handler .OnIncomingConnection( client_.get(), ByteArray("remote endpoint"), @@ -2645,7 +2615,7 @@ TEST_F(BasePcpHandlerTest, IncomingConnectionFailsWithEmptyEndpointId) { TEST_F(BasePcpHandlerTest, IncomingConnectionWithNoDataFailsWithoutLogging) { env_.Start({.use_simulated_clock = true}); // Recreate ClientProxy so that AnalyticRecorder uses simulated clock. - client_ = std::make_unique(&mock_event_logger_); + client_ = std::make_unique(CreateAnalyticsRecorder()); Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); @@ -2662,6 +2632,8 @@ TEST_F(BasePcpHandlerTest, IncomingConnectionWithNoDataFailsWithoutLogging) { MockPcpHandler::StartOperationResult{.status = {Status::kSuccess}})); EXPECT_CALL(pcp_handler, CanReceiveIncomingConnection) .WillRepeatedly(Return(true)); + EXPECT_CALL(*mock_analytics_recorder_ptr_, + OnStartedIncomingConnectionListening(_)); EXPECT_TRUE(pcp_handler .StartListeningForIncomingConnections(client_.get(), "service", options, {}) @@ -2673,59 +2645,8 @@ TEST_F(BasePcpHandlerTest, IncomingConnectionWithNoDataFailsWithoutLogging) { std::move(input_a), std::move(output_a)); EXPECT_CALL(*input_channel, Read()) .WillRepeatedly(Return(ExceptionOr(Exception::kNoData))); - absl::string_view expected_log = R"pb( - event_type: CLIENT_SESSION - client_session { - strategy_session { - connection_attempt { - type: INITIAL - direction: INCOMING - attempt_result: RESULT_ERROR - } - } - } - )pb"; - absl::string_view client_session_log = R"pb( - event_type: CLIENT_SESSION - client_session { duration_millis: 0 } - version: "v1.5.0" - )pb"; - absl::string_view client_session_log2 = R"pb( - event_type: CLIENT_SESSION - client_session { - duration_millis: 0 - strategy_session { - duration_millis: 0 - strategy: UNKNOWN_STRATEGY - role: ADVERTISER - } - } - 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(client_session_log)))) - .Times(2); - EXPECT_CALL( - mock_event_logger_, - Log(Matcher(EqualsProto(client_session_log2)))); - EXPECT_CALL( - mock_event_logger_, - Log(Matcher(Partially(EqualsProto(expected_log))))) - .Times(0); - + EXPECT_CALL(*mock_analytics_recorder_ptr_, LogSession()).Times(3); + EXPECT_CALL(*mock_analytics_recorder_ptr_, LogStartSession()).Times(3); EXPECT_EQ( pcp_handler .OnIncomingConnection(client_.get(), ByteArray("remote endpoint"), @@ -3029,5 +2950,4 @@ TEST_F(BasePcpHandlerTest, TestForceUpdateEndpointIdAdvertisingOption) { } } // namespace -} // namespace connections -} // namespace nearby +} // namespace nearby::connections diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index 31bfc12b..f9890267 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -38,7 +38,7 @@ #include "connections/discovery_options.h" #include "connections/implementation/analytics/advertising_metadata_params.h" #include "connections/implementation/analytics/analytics_recorder.h" -#include "connections/implementation/analytics/analytics_recorder_impl.h" +#include "connections/implementation/analytics/connection_attempt_metadata_params.h" #include "connections/implementation/analytics/discovery_metadata_params.h" #include "connections/implementation/analytics/operation_result_with_medium.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" @@ -46,6 +46,7 @@ #include "connections/listeners.h" #include "connections/medium_selector.h" #include "connections/payload.h" +#include "connections/payload_type.h" #include "connections/status.h" #include "connections/strategy.h" #include "connections/v3/bandwidth_info.h" @@ -54,7 +55,6 @@ #include "connections/v3/connections_device.h" #include "connections/v3/connections_device_provider.h" #include "connections/v3/listeners.h" -#include "internal/analytics/event_logger.h" #include "internal/base/file_path.h" #include "internal/base/files.h" #include "internal/flags/nearby_flags.h" @@ -99,11 +99,154 @@ constexpr absl::string_view kAdvertisingTimestamp = "nc.advertising.timestamp"; constexpr absl::Duration kAdvertisingKeepAliveDuration = absl::Seconds(30); +class NoOpAnalyticsRecorder : public AnalyticsRecorder { + public: + NoOpAnalyticsRecorder() = default; + ~NoOpAnalyticsRecorder() override = default; + + // Advertising phase + void OnStartAdvertising( + connections::Strategy strategy, + const std::vector& mediums, + AdvertisingMetadataParams* advertising_metadata_params) override {} + void OnStopAdvertising() override {} + + int GetNextAdvertisingUpdateIndex() override { return 0; } + + // Connection listening + void OnStartedIncomingConnectionListening( + connections::Strategy strategy) override {} + void OnStoppedIncomingConnectionListening() override {} + + // Discovery phase + void OnStartDiscovery( + connections::Strategy strategy, + const std::vector& mediums, + DiscoveryMetadataParams* discovery_metadata_params) override {} + void OnStopDiscovery() override {} + + int GetNextDiscoveryUpdateIndex() override { return 0; } + void OnEndpointFound( + location::nearby::proto::connections::Medium medium) override {} + + // Connection request + void OnRequestConnection(const connections::Strategy& strategy, + const std::string& endpoint_id) override {} + + void OnConnectionRequestReceived( + const std::string& remote_endpoint_id) override {} + void OnConnectionRequestSent( + const std::string& remote_endpoint_id) override {} + void OnRemoteEndpointAccepted( + const std::string& remote_endpoint_id) override {} + void OnLocalEndpointAccepted( + const std::string& remote_endpoint_id) override {} + void OnRemoteEndpointRejected( + const std::string& remote_endpoint_id) override {} + void OnLocalEndpointRejected( + const std::string& remote_endpoint_id) override {} + + // Connection attempt + void OnIncomingConnectionAttempt( + location::nearby::proto::connections::ConnectionAttemptType type, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::ConnectionAttemptResult result, + absl::Duration duration, const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) + override {} + void OnOutgoingConnectionAttempt( + const std::string& remote_endpoint_id, + location::nearby::proto::connections::ConnectionAttemptType type, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::ConnectionAttemptResult result, + absl::Duration duration, const std::string& connection_token, + ConnectionAttemptMetadataParams* connection_attempt_metadata_params) + override {} + + // Connection established + void OnConnectionEstablished( + const std::string& endpoint_id, + location::nearby::proto::connections::Medium medium, + const std::string& connection_token) override {} + void OnConnectionClosed( + const std::string& endpoint_id, + location::nearby::proto::connections::Medium medium, + location::nearby::proto::connections::DisconnectionReason reason, + nearby::analytics::SafeDisconnectionResult result) override {} + + // Payload + void OnIncomingPayloadStarted(const std::string& endpoint_id, + std::int64_t payload_id, + connections::PayloadType type, + std::int64_t total_size_bytes) override {} + void OnPayloadChunkReceived(const std::string& endpoint_id, + std::int64_t payload_id, + std::int64_t chunk_size_bytes) override {} + void OnIncomingPayloadDone( + const std::string& endpoint_id, std::int64_t payload_id, + location::nearby::proto::connections::PayloadStatus status, + location::nearby::proto::connections::OperationResultCode + operation_result_code) override {} + void OnOutgoingPayloadStarted( + const std::vector& endpoint_ids, std::int64_t payload_id, + connections::PayloadType type, std::int64_t total_size_bytes) override {} + void OnPayloadChunkSent(const std::string& endpoint_id, + std::int64_t payload_id, + std::int64_t chunk_size_bytes) override {} + void OnOutgoingPayloadDone( + const std::string& endpoint_id, std::int64_t payload_id, + location::nearby::proto::connections::PayloadStatus status, + location::nearby::proto::connections::OperationResultCode + operation_result_code) override {} + + // BandwidthUpgrade + void OnBandwidthUpgradeStarted( + const std::string& endpoint_id, + location::nearby::proto::connections::Medium from_medium, + location::nearby::proto::connections::Medium to_medium, + location::nearby::proto::connections::ConnectionAttemptDirection + direction, + const std::string& connection_token) override {} + void UpdateBwUpgradeNetworkInfo(const std::string& endpoint_id, + int num_interfaces, + int num_ipv6_only_interfaces) override {} + void OnBandwidthUpgradeError( + const std::string& endpoint_id, + location::nearby::proto::connections::BandwidthUpgradeResult result, + location::nearby::proto::connections::BandwidthUpgradeErrorStage + error_stage, + location::nearby::proto::connections::OperationResultCode + operation_result_code) override {} + void OnBandwidthUpgradeSuccess(const std::string& endpoint_id) override {} + + // Error Code + void OnErrorCode(const ErrorCodeParams& params) override {} + + void LogStartSession() override {} + void LogSession() override {} + + bool IsSessionLogged() override { return false; } + + location::nearby::proto::connections::OperationResultCategory + GetOperationResultCategory( + location::nearby::proto::connections::OperationResultCode result_code) + override { + return location::nearby::proto::connections::OperationResultCategory:: + CATEGORY_UNKNOWN; + } + + void Sync() override {} +}; + } // namespace -ClientProxy::ClientProxy(::nearby::analytics::EventLogger* event_logger) - : client_id_(Prng().NextInt64()) { - VLOG(1) << "ClientProxy ctor event_logger=" << event_logger; +ClientProxy::ClientProxy(std::unique_ptr analytics_recorder) + : client_id_(Prng().NextInt64()), + analytics_recorder_(std::move(analytics_recorder)) { + if (analytics_recorder_ == nullptr) { + analytics_recorder_ = std::make_unique(); + } + if (NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature:: kEnableNearbyConnectionsPreferences)) { @@ -112,8 +255,6 @@ ClientProxy::ClientProxy(::nearby::analytics::EventLogger* event_logger) is_dct_enabled_ = NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature::kEnableDct); - analytics_recorder_ = - std::make_unique(event_logger); error_code_recorder_ = std::make_unique( [this](const ErrorCodeParams& params) { analytics_recorder_->OnErrorCode(params); diff --git a/connections/implementation/client_proxy.h b/connections/implementation/client_proxy.h index e7010739..c5400fe5 100644 --- a/connections/implementation/client_proxy.h +++ b/connections/implementation/client_proxy.h @@ -42,7 +42,6 @@ #include "connections/v3/connection_listening_options.h" #include "connections/v3/connections_device_provider.h" #include "connections/v3/listeners.h" -#include "internal/analytics/event_logger.h" #include "internal/interop/device.h" #include "internal/interop/device_provider.h" #include "internal/platform/byte_array.h" @@ -66,8 +65,8 @@ class ClientProxy final { static constexpr absl::Duration kHighPowerAdvertisementEndpointIdCacheTimeout = absl::Seconds(30); - explicit ClientProxy( - ::nearby::analytics::EventLogger* event_logger = nullptr); + explicit ClientProxy(std::unique_ptr + analytics_recorder = nullptr); ~ClientProxy(); ClientProxy(ClientProxy&&) = default; ClientProxy& operator=(ClientProxy&&) = default; diff --git a/connections/implementation/client_proxy_test.cc b/connections/implementation/client_proxy_test.cc index e0e1f757..d54a236b 100644 --- a/connections/implementation/client_proxy_test.cc +++ b/connections/implementation/client_proxy_test.cc @@ -25,7 +25,6 @@ #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" -#include "absl/base/thread_annotations.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/time/clock.h" @@ -34,6 +33,7 @@ #include "connections/advertising_options.h" #include "connections/connection_options.h" #include "connections/discovery_options.h" +#include "connections/implementation/analytics/mock_analytics_recorder.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/listeners.h" #include "connections/medium_selector.h" @@ -45,7 +45,6 @@ #include "connections/v3/connection_result.h" #include "connections/v3/connections_device_provider.h" #include "connections/v3/listeners.h" -#include "internal/analytics/mock_event_logger.h" #include "internal/flags/nearby_flags.h" #include "internal/interop/device.h" #include "internal/interop/device_provider.h" @@ -54,8 +53,6 @@ #include "internal/platform/count_down_latch.h" #include "internal/platform/feature_flags.h" #include "internal/platform/medium_environment.h" -#include "internal/platform/mutex.h" -#include "internal/platform/mutex_lock.h" #include "internal/platform/single_thread_executor.h" #include "proto/connections_enums.pb.h" @@ -63,11 +60,11 @@ namespace nearby { namespace connections { namespace { -using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::connections::OsInfo; using ::location::nearby::proto::connections::CLIENT_SESSION; using ::location::nearby::proto::connections::START_CLIENT_SESSION; using ::location::nearby::proto::connections::STOP_CLIENT_SESSION; +using ::testing::_; using ::testing::IsEmpty; using ::testing::MockFunction; using ::testing::StrictMock; @@ -81,46 +78,6 @@ constexpr FeatureFlags::Flags kTestCases[] = { }, }; -class FakeEventLogger : public ::nearby::analytics::MockEventLogger { - public: - explicit FakeEventLogger() = default; - - void Log(const ConnectionsLog& message) override { - MutexLock lock(&mutex_); - logs_.push_back(message); - } - - int GetCompleteClientSessionCount() { - MutexLock lock(&mutex_); - bool has_start_client_session = false; - bool has_client_session = false; - int session_count = 0; - // We expect series of START_CLIENT_SESSION, CLIENT_SESSION and - // STOP_CLIENT_SESSION events, possibly interleaved with other events. - for (const auto& log : logs_) { - if (log.event_type() == START_CLIENT_SESSION) { - EXPECT_FALSE(has_start_client_session); - EXPECT_FALSE(has_client_session); - has_start_client_session = true; - } else if (log.event_type() == CLIENT_SESSION) { - EXPECT_TRUE(has_start_client_session); - EXPECT_FALSE(has_client_session); - has_client_session = true; - } else if (log.event_type() == STOP_CLIENT_SESSION) { - EXPECT_TRUE(has_start_client_session); - EXPECT_TRUE(has_client_session); - has_start_client_session = false; - has_client_session = false; - ++session_count; - } - } - return session_count; - } - - Mutex mutex_; - std::vector logs_ ABSL_GUARDED_BY(mutex_); -}; - class MockDeviceProvider : public nearby::NearbyDeviceProvider { public: MOCK_METHOD((const NearbyDevice*), GetLocalDevice, (), (override)); @@ -169,8 +126,14 @@ class ClientProxyTest : public ::testing::TestWithParam { /*use_simulated_clock=*/true, /*use_temporary_directory_for_app_path=*/true}; env_.Start(config); - client1_ = std::make_unique(&event_logger1_); - client2_ = std::make_unique(&event_logger2_); + auto analytics_recorder1 = + std::make_unique(); + mock_analytics_recorder1_ptr_ = analytics_recorder1.get(); + client1_ = std::make_unique(std::move(analytics_recorder1)); + auto analytics_recorder2 = + std::make_unique(); + mock_analytics_recorder2_ptr_ = analytics_recorder2.get(); + client2_ = std::make_unique(std::move(analytics_recorder2)); } void TearDown() override { @@ -384,8 +347,8 @@ class ClientProxyTest : public ::testing::TestWithParam { MediumEnvironment& env_ = MediumEnvironment::Instance(); Strategy strategy_{Strategy::kP2pPointToPoint}; const std::string service_id_{"service"}; - FakeEventLogger event_logger1_; - FakeEventLogger event_logger2_; + analytics::MockAnalyticsRecorder* mock_analytics_recorder1_ptr_; + analytics::MockAnalyticsRecorder* mock_analytics_recorder2_ptr_; std::unique_ptr client1_; std::unique_ptr client2_; std::string auth_token_ = "auth_token"; @@ -1182,11 +1145,13 @@ TEST_F(ClientProxyTest, NotLogSessionForStoppedAdvertisingWithConnection) { // After StopAdvertising(client1()); // No Advertising - EXPECT_EQ(event_logger1_.GetCompleteClientSessionCount(), 0); + EXPECT_CALL(*mock_analytics_recorder1_ptr_, LogSession()).Times(1); } TEST_F(ClientProxyTest, LogSessionForStoppedAdvertisingWhenNoConnectionsAndNoDiscovering) { + EXPECT_CALL(*mock_analytics_recorder1_ptr_, + OnStartAdvertising(strategy_, mediums_, _)); Endpoint advertising_endpoint = StartAdvertising(client1(), advertising_connection_listener_); @@ -1195,36 +1160,47 @@ TEST_F(ClientProxyTest, advertising_endpoint.id)); // No Connections EXPECT_FALSE(client1()->IsDiscovering()); // No Discovery EXPECT_TRUE(client1()->IsAdvertising()); // Advertising - EXPECT_EQ(event_logger1_.GetCompleteClientSessionCount(), 0); // After + EXPECT_CALL(*mock_analytics_recorder1_ptr_, OnStopAdvertising()); StopAdvertising(client1()); - EXPECT_GT(event_logger1_.GetCompleteClientSessionCount(), 0); } TEST_F(ClientProxyTest, NotLogSessionForStoppedDiscoveryWithConnection) { + EXPECT_CALL(*mock_analytics_recorder1_ptr_, + OnStartAdvertising(strategy_, mediums_, _)); Endpoint advertising_endpoint = StartAdvertising(client1(), advertising_connection_listener_); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnStartDiscovery(strategy_, mediums_, _)); StartDiscovery(client2(), GetDiscoveryListener()); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnEndpointFound(Medium::BLUETOOTH)); OnDiscoveryEndpointFound(client2(), advertising_endpoint); // Before + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnConnectionRequestReceived(advertising_endpoint.id)); OnDiscoveryConnectionInitiated( client2(), advertising_endpoint); // Connections are available EXPECT_FALSE(client2()->IsAdvertising()); // No Advertising EXPECT_TRUE(client2()->IsDiscovering()); // Discovering // After + EXPECT_CALL(*mock_analytics_recorder2_ptr_, OnStopDiscovery()); StopDiscovery(client2()); - EXPECT_EQ(event_logger2_.GetCompleteClientSessionCount(), 0); } TEST_F(ClientProxyTest, NotLogSessionForStoppedDiscoveryWithoutConnectionsAndAdvertising) { + EXPECT_CALL(*mock_analytics_recorder1_ptr_, + OnStartAdvertising(strategy_, mediums_, _)); Endpoint advertising_endpoint = StartAdvertising(client1(), advertising_connection_listener_); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnStartDiscovery(strategy_, mediums_, _)); StartDiscovery(client2(), GetDiscoveryListener()); // Before @@ -1234,30 +1210,40 @@ TEST_F(ClientProxyTest, advertising_endpoint.id)); // No Connections // After + EXPECT_CALL(*mock_analytics_recorder2_ptr_, OnStopDiscovery()); StopDiscovery(client2()); - EXPECT_GT(event_logger2_.GetCompleteClientSessionCount(), 0); } TEST_F(ClientProxyTest, LogSessionOnDisconnectedWithOneConnection) { + EXPECT_CALL(*mock_analytics_recorder1_ptr_, + OnStartAdvertising(strategy_, mediums_, _)); Endpoint advertising_endpoint = StartAdvertising(client1(), advertising_connection_listener_); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnStartDiscovery(strategy_, mediums_, _)); StartDiscovery(client2(), GetDiscoveryListener()); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnEndpointFound(Medium::BLUETOOTH)); OnDiscoveryEndpointFound(client2(), advertising_endpoint); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnConnectionRequestReceived(advertising_endpoint.id)); OnDiscoveryConnectionInitiated(client2(), advertising_endpoint); // Before EXPECT_FALSE(client2()->IsAdvertising()); // No Advertising + EXPECT_CALL(*mock_analytics_recorder2_ptr_, OnStopDiscovery()); StopDiscovery(client2()); // No Discovery EXPECT_TRUE(client2()->HasPendingConnectionToEndpoint( advertising_endpoint.id)); // One Connection // After OnDiscoveryConnectionDisconnected(client2(), advertising_endpoint); - EXPECT_GT(event_logger2_.GetCompleteClientSessionCount(), 0); } TEST_F(ClientProxyTest, NotLogSessionOnDisconnectedWithoutConnectionsDiscoveringAdvertising) { + EXPECT_CALL(*mock_analytics_recorder1_ptr_, + OnStartAdvertising(strategy_, mediums_, _)); Endpoint advertising_endpoint = StartAdvertising(client1(), advertising_connection_listener_); @@ -1269,13 +1255,16 @@ TEST_F(ClientProxyTest, // After client2()->OnDisconnected(advertising_endpoint.id, /*notify=*/false); - EXPECT_EQ(event_logger2_.GetCompleteClientSessionCount(), 0); } TEST_F(ClientProxyTest, NotLogSessionOnDisconnectedWhenMoreThanOneConnection) { ClientProxy client3; + EXPECT_CALL(*mock_analytics_recorder1_ptr_, + OnStartAdvertising(strategy_, mediums_, _)); Endpoint advertising_endpoint_1 = StartAdvertising(client1(), advertising_connection_listener_); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnStartAdvertising(strategy_, mediums_, _)); Endpoint advertising_endpoint_2 = StartAdvertising(client2(), advertising_connection_listener_); StartDiscovery(&client3, GetDiscoveryListener()); @@ -1296,15 +1285,22 @@ TEST_F(ClientProxyTest, NotLogSessionOnDisconnectedWhenMoreThanOneConnection) { // After client2()->OnDisconnected(advertising_endpoint_1.id, /*notify=*/false); - EXPECT_EQ(event_logger2_.GetCompleteClientSessionCount(), 0); } TEST_F(ClientProxyTest, NotLogSessionOnDisconnectedForDiscoveringWithOnlyOneConnection) { + EXPECT_CALL(*mock_analytics_recorder1_ptr_, + OnStartAdvertising(strategy_, mediums_, _)); Endpoint advertising_endpoint = StartAdvertising(client1(), advertising_connection_listener_); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnStartDiscovery(strategy_, mediums_, _)); StartDiscovery(client2(), GetDiscoveryListener()); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnEndpointFound(Medium::BLUETOOTH)); OnDiscoveryEndpointFound(client2(), advertising_endpoint); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnConnectionRequestReceived(advertising_endpoint.id)); OnDiscoveryConnectionInitiated(client2(), advertising_endpoint); // Before @@ -1315,26 +1311,27 @@ TEST_F(ClientProxyTest, // After OnDiscoveryConnectionDisconnected(client2(), advertising_endpoint); - // Since we are no longer checking IsDiscovering(), we complete sessions now - // solely based on advertising. - EXPECT_EQ(event_logger2_.GetCompleteClientSessionCount(), 1); } TEST_F(ClientProxyTest, LogSessionForResetClientProxy) { + EXPECT_CALL(*mock_analytics_recorder1_ptr_, + OnStartAdvertising(strategy_, mediums_, _)); Endpoint advertising_endpoint = StartAdvertising(client1(), advertising_connection_listener_); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnStartDiscovery(strategy_, mediums_, _)); StartDiscovery(client2(), GetDiscoveryListener()); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnEndpointFound(Medium::BLUETOOTH)); OnDiscoveryEndpointFound(client2(), advertising_endpoint); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, + OnConnectionRequestReceived(advertising_endpoint.id)); OnDiscoveryConnectionInitiated(client2(), advertising_endpoint); - EXPECT_EQ(event_logger1_.GetCompleteClientSessionCount(), 0); + EXPECT_CALL(*mock_analytics_recorder1_ptr_, OnStopAdvertising()); client1()->Reset(); - // TODO(b/290936886): Why are there more than one complete sessions? - EXPECT_GT(event_logger1_.GetCompleteClientSessionCount(), 0); - - EXPECT_EQ(event_logger2_.GetCompleteClientSessionCount(), 0); + EXPECT_CALL(*mock_analytics_recorder2_ptr_, OnStopDiscovery()); client2()->Reset(); - EXPECT_GT(event_logger2_.GetCompleteClientSessionCount(), 0); } TEST_F(ClientProxyTest, GetLocalInfoCorrect) { @@ -1536,7 +1533,7 @@ TEST_F(ClientProxyTest, SaveClientInfoFromPreferences) { config_package_nearby::nearby_connections_feature:: kEnableNearbyConnectionsPreferences, true); - client1_ = std::make_unique(&event_logger1_); + client1_ = std::make_unique(); Endpoint advertising_endpoint = StartAdvertising(client1(), advertising_connection_listener_); std::string endpoint_id = advertising_endpoint.id; @@ -1544,7 +1541,7 @@ TEST_F(ClientProxyTest, SaveClientInfoFromPreferences) { // Destroy the client and create a new one. client1_.reset(); - client1_ = std::make_unique(&event_logger1_); + client1_ = std::make_unique(); // The new client should load the same endpoint ID. EXPECT_EQ(client1()->GetLocalEndpointId(), endpoint_id); @@ -1559,7 +1556,7 @@ TEST_F(ClientProxyTest, NotLoadClientInfoFromPreferencesOnExpired) { config_package_nearby::nearby_connections_feature:: kEnableNearbyConnectionsPreferences, true); - client1_ = std::make_unique(&event_logger1_); + client1_ = std::make_unique(); Endpoint advertising_endpoint = StartAdvertising(client1(), advertising_connection_listener_); std::string endpoint_id = advertising_endpoint.id; @@ -1569,7 +1566,7 @@ TEST_F(ClientProxyTest, NotLoadClientInfoFromPreferencesOnExpired) { client1_.reset(); FastForward(absl::Hours(25)); - client1_ = std::make_unique(&event_logger1_); + client1_ = std::make_unique(); // The new client should load the same endpoint ID. EXPECT_NE(client1()->GetLocalEndpointId(), endpoint_id); diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index 29007461..d533c0ae 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -244,13 +244,11 @@ cc_test( ], deps = [ ":mediums", - "//connections:core_types", "//connections/implementation:bwu_handler", "//connections/implementation:client_proxy", "//connections/implementation:endpoint_channel", "//connections/implementation:offline_frames", "//connections/implementation/flags:connections_flags", - "//internal/analytics:mock_event_logger", "//internal/flags:nearby_flags", "//internal/platform:base", "//internal/platform:cancellation_flag", @@ -263,7 +261,6 @@ cc_test( "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/proto/analytics:connections_log_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/time", diff --git a/connections/implementation/mediums/awdl_bwu_handler_test.cc b/connections/implementation/mediums/awdl_bwu_handler_test.cc index 317f7b2c..0080fec0 100644 --- a/connections/implementation/mediums/awdl_bwu_handler_test.cc +++ b/connections/implementation/mediums/awdl_bwu_handler_test.cc @@ -31,9 +31,6 @@ #include "connections/implementation/mediums/awdl.h" #include "connections/implementation/mediums/awdl_endpoint_channel.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/awdl.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/count_down_latch.h" @@ -47,7 +44,6 @@ #include "internal/platform/mock_output_stream.h" #include "internal/platform/nsd_service_info.h" #include "internal/platform/output_stream.h" -#include "internal/proto/analytics/connections_log.pb.h" namespace nearby { @@ -101,17 +97,13 @@ MockAwdlMedium* awdl_medium_mock = 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::Matcher; using ::testing::MockFunction; using ::testing::Return; using ::testing::ReturnRef; @@ -141,14 +133,13 @@ class AwdlBwuHandlerTest : public ::testing::Test { std::unique_ptr)> incoming_connection_callback_; AwdlBwuHandler handler_; - nearby::analytics::MockEventLogger mock_event_logger_; MockInputStream mock_input_stream_; MockOutputStream mock_output_stream_; }; TEST_F(AwdlBwuHandlerTest, CreateUpgradedEndpointChannel_InvalidCredentials_Fails) { - ClientProxy client(&mock_event_logger_); + ClientProxy client; BandwidthUpgradeNegotiationFrame::UpgradePathInfo path_info; path_info.mutable_awdl_credentials(); // Empty credentials @@ -162,7 +153,7 @@ TEST_F(AwdlBwuHandlerTest, } TEST_F(AwdlBwuHandlerTest, CreateUpgradedEndpointChannel_Success) { - ClientProxy client(&mock_event_logger_); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); MockInputStream input_stream; MockOutputStream output_stream; @@ -205,7 +196,7 @@ TEST_F(AwdlBwuHandlerTest, CreateUpgradedEndpointChannel_Success) { TEST_F(AwdlBwuHandlerTest, InitializeUpgradedMediumForEndpoint_StartAcceptingConnectionsFails) { MediumEnvironment::Instance().Start({.use_simulated_clock = true}); - ClientProxy client(&mock_event_logger_); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); EXPECT_CALL(*awdl_medium_mock, ListenForService(_, 0)) @@ -227,18 +218,7 @@ TEST_F(AwdlBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { // real-world milliseconds elapsed between the test start and test end, this // duration evaluated to something > 0. { - 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::AWDL, - location::nearby::proto::connections::ConnectionAttemptDirection:: - OUTGOING, - /*connection_token=*/""); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); auto awdl_server_socket = std::make_unique(); @@ -299,67 +279,6 @@ TEST_F(AwdlBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { 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: AWDL - 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 - } - } - } - } - 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(); handler_.RevertInitiatorState(); } MediumEnvironment::Instance().Stop(); @@ -367,7 +286,7 @@ TEST_F(AwdlBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { TEST_F(AwdlBwuHandlerTest, OnIncomingAwdlConnection_Success) { MediumEnvironment::Instance().Start({.use_simulated_clock = true}); - ClientProxy client(&mock_event_logger_); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); auto awdl_server_socket = std::make_unique(); @@ -411,7 +330,7 @@ TEST_F(AwdlBwuHandlerTest, OnIncomingAwdlConnection_Success) { TEST_F(AwdlBwuHandlerTest, AwdlIncomingSocket_ToStringAndClose) { MediumEnvironment::Instance().Start({.use_simulated_clock = true}); - ClientProxy client(&mock_event_logger_); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); auto awdl_server_socket = std::make_unique(); @@ -461,7 +380,7 @@ TEST_F(AwdlBwuHandlerTest, AwdlIncomingSocket_ToStringAndClose) { TEST_F(AwdlBwuHandlerTest, HandleRevertInitiatorStateForService_Success) { MediumEnvironment::Instance().Start({.use_simulated_clock = true}); - ClientProxy client(&mock_event_logger_); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); auto awdl_server_socket = std::make_unique(); @@ -492,7 +411,7 @@ TEST_F(AwdlBwuHandlerTest, GetUpgradeMedium_ReturnsAwdl) { } TEST_F(AwdlBwuHandlerTest, OnEndpointDisconnect_DoesNotCrash) { - ClientProxy client(&mock_event_logger_); + ClientProxy client; auto* bwu_handler = static_cast(&handler_); // This method is a no-op, just verifying it doesn't crash. bwu_handler->OnEndpointDisconnect(&client, std::string(kEndpointId)); diff --git a/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc b/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc index 600c8474..1cf09752 100644 --- a/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc +++ b/connections/implementation/mediums/wifi_lan_bwu_handler_test.cc @@ -26,9 +26,6 @@ #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/implementation/platform.h" #include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi_lan.h" @@ -40,7 +37,6 @@ #include "internal/platform/mock_wifi_lan_socket.h" #include "internal/platform/service_address.h" #include "internal/platform/wifi_lan.h" -#include "internal/proto/analytics/connections_log.pb.h" namespace nearby { @@ -48,18 +44,14 @@ 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; @@ -81,12 +73,11 @@ 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(&mock_event_logger_); + ClientProxy client; BandwidthUpgradeNegotiationFrame::UpgradePathInfo path_info; // Create an empty wifi_lan_socket. path_info.mutable_wifi_lan_socket(); @@ -100,7 +91,7 @@ TEST_F(WifiLanBwuHandlerTest, }; TEST_F(WifiLanBwuHandlerTest, CreateUpgradedEndpointChannel_IpAddress_Success) { - ClientProxy client(&mock_event_logger_); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); MockInputStream input_stream; MockOutputStream output_stream; @@ -133,7 +124,7 @@ TEST_F(WifiLanBwuHandlerTest, CreateUpgradedEndpointChannel_IpAddress_Success) { TEST_F(WifiLanBwuHandlerTest, CreateUpgradedEndpointChannel_AddressCandidates_FirstCandidate_Success) { - ClientProxy client(&mock_event_logger_); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); MockInputStream input_stream; MockOutputStream output_stream; @@ -172,7 +163,7 @@ TEST_F(WifiLanBwuHandlerTest, TEST_F(WifiLanBwuHandlerTest, CreateUpgradedEndpointChannel_AddressCandidates_FirstCandidate_Fails) { - ClientProxy client(&mock_event_logger_); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); MockInputStream input_stream; MockOutputStream output_stream; @@ -220,18 +211,7 @@ TEST_F(WifiLanBwuHandlerTest, TEST_F(WifiLanBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { 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=*/""); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); auto wifi_lan_server_socket = std::make_unique(); EXPECT_CALL(*wifi_lan_server_socket, GetPort()).WillRepeatedly(Return(8080)); @@ -279,76 +259,12 @@ TEST_F(WifiLanBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { OfflineFrame result_frame; EXPECT_TRUE(result_frame.ParseFromString(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(); } TEST_F(WifiLanBwuHandlerTest, InitializeUpgradedMediumForEndpoint_EmptyCandidates_StopsAccepting) { MediumEnvironment::Instance().Start({.use_simulated_clock = true}); - ClientProxy client(&mock_event_logger_); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); auto mock_server_socket = std::make_unique(); @@ -377,7 +293,7 @@ TEST_F( WifiLanBwuHandlerTest, InitializeUpgradedMediumForEndpoint_AlreadyAccepting_KeepAccepting) { MediumEnvironment::Instance().Start({.use_simulated_clock = true}); - ClientProxy client(&mock_event_logger_); + ClientProxy client; client.AddCancellationFlag(std::string(kEndpointId)); auto mock_server_socket = std::make_unique(); diff --git a/connections/implementation/p2p_cluster_pcp_handler.cc b/connections/implementation/p2p_cluster_pcp_handler.cc index 9f530d60..c207e91b 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.cc +++ b/connections/implementation/p2p_cluster_pcp_handler.cc @@ -29,6 +29,7 @@ #include "absl/strings/string_view.h" #include "connections/advertising_options.h" #include "connections/discovery_options.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" #include "connections/implementation/base_pcp_handler.h" #include "connections/implementation/ble_advertisement.h" #include "connections/implementation/bluetooth_device_name.h" @@ -82,7 +83,6 @@ namespace nearby { namespace connections { namespace { -using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::proto::connections::OperationResultCode; using ::location::nearby::proto::connections::Medium::AWDL; using ::location::nearby::proto::connections::Medium::BLE; @@ -90,6 +90,7 @@ using ::location::nearby::proto::connections::Medium::BLUETOOTH; using ::location::nearby::proto::connections::Medium::UNKNOWN_MEDIUM; using ::location::nearby::proto::connections::Medium::WEB_RTC; using ::location::nearby::proto::connections::Medium::WIFI_LAN; +using ::nearby::analytics::OperationResultWithMedium; } // namespace @@ -157,8 +158,7 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl( const std::string& local_endpoint_id, const ByteArray& local_endpoint_info, const AdvertisingOptions& advertising_options) { std::vector mediums_started_successfully; - std::vector - operation_result_with_mediums; + std::vector operation_result_with_mediums; WebRtcState web_rtc_state{WebRtcState::kUnconnectable}; @@ -178,13 +178,12 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl( VLOG(1) << "P2pClusterPcpHandler::StartAdvertisingImpl: Awdl added"; mediums_started_successfully.push_back(awdl_medium); } - std::unique_ptr - operation_result_with_medium = GetOperationResultWithMediumByResultCode( + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( client, AWDL, /*update_index=*/0, awdl_result.has_error() ? awdl_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + : OperationResultCode::DETAIL_SUCCESS)); } // WifiLan @@ -200,13 +199,12 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl( VLOG(1) << "P2pClusterPcpHandler::StartAdvertisingImpl: WifiLan added"; mediums_started_successfully.push_back(wifi_lan_medium); } - std::unique_ptr - operation_result_with_medium = GetOperationResultWithMediumByResultCode( + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( client, WIFI_LAN, /*update_index=*/0, wifi_lan_result.has_error() ? wifi_lan_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + : OperationResultCode::DETAIL_SUCCESS)); } if (advertising_options.allowed.bluetooth) { @@ -244,14 +242,13 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl( bluetooth_classic_advertiser_client_id_ = client->GetClientId(); } } - std::unique_ptr - operation_result_with_medium = GetOperationResultWithMediumByResultCode( + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( client, BLUETOOTH, /*update_index=*/0, bluetooth_result.has_error() ? bluetooth_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + : OperationResultCode::DETAIL_SUCCESS)); } if (advertising_options.allowed.ble) { @@ -264,12 +261,12 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl( mediums_started_successfully.push_back(ble_result.value()); } - std::unique_ptr - operation_result_with_medium = GetOperationResultWithMediumByResultCode( + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( client, BLE, /*update_index=*/0, ble_result.has_error() ? ble_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); + : OperationResultCode::DETAIL_SUCCESS)); } if (mediums_started_successfully.empty()) { @@ -1043,8 +1040,7 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( } std::vector mediums_started_successfully; - std::vector - operation_result_with_mediums; + std::vector operation_result_with_mediums; // Due to singleton, apple only allow start discovery once. So need to keep // the start discovery order of awdl before the wifi_lan. @@ -1060,14 +1056,13 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( LOG(INFO) << "P2pClusterPcpHandler::StartDiscoveryImpl: AWDL added"; mediums_started_successfully.push_back(awdl_medium); } - std::unique_ptr - operation_result_with_medium = GetOperationResultWithMediumByResultCode( + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( client, AWDL, /*update_index=*/0, awdl_result.has_error() ? awdl_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + : OperationResultCode::DETAIL_SUCCESS)); } // WifiLan @@ -1081,14 +1076,13 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( LOG(INFO) << "P2pClusterPcpHandler::StartDiscoveryImpl: WifiLan added"; mediums_started_successfully.push_back(wifi_lan_medium); } - std::unique_ptr - operation_result_with_medium = GetOperationResultWithMediumByResultCode( + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( client, WIFI_LAN, /*update_index=*/0, wifi_lan_result.has_error() ? wifi_lan_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + : OperationResultCode::DETAIL_SUCCESS)); } if (discovery_options.allowed.ble) { @@ -1103,14 +1097,13 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( mediums_started_successfully.push_back(ble_medium); } - std::unique_ptr - operation_result_with_medium = GetOperationResultWithMediumByResultCode( + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( client, BLE, /*update_index=*/0, ble_result.has_error() ? ble_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + : OperationResultCode::DETAIL_SUCCESS)); } if (discovery_options.allowed.bluetooth) { @@ -1159,8 +1152,7 @@ Status P2pClusterPcpHandler::StopDiscoveryImpl(ClientProxy* client) { ble_medium_.StopScanning(client->GetDiscoveryServiceId()); - paused_bluetooth_clients_discoveries_.erase( - client->GetDiscoveryServiceId()); + paused_bluetooth_clients_discoveries_.erase(client->GetDiscoveryServiceId()); return {Status::kSuccess}; } @@ -1236,8 +1228,7 @@ P2pClusterPcpHandler::StartListeningForIncomingConnectionsImpl( bool refactor_ble_l2cap = NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature::kRefactorBleL2cap); std::vector started_mediums; - std::vector - operation_result_with_mediums; + std::vector operation_result_with_mediums; int update_index = client_proxy->GetAnalyticsRecorder().GetNextAdvertisingUpdateIndex(); if (options.enable_bluetooth_listening && @@ -1255,13 +1246,12 @@ P2pClusterPcpHandler::StartListeningForIncomingConnectionsImpl( } else { started_mediums.push_back(BLUETOOTH); } - std::unique_ptr - operation_result_with_medium = GetOperationResultWithMediumByResultCode( + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( client_proxy, Medium::BLUETOOTH, update_index, bluetooth_result.has_error() ? bluetooth_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + : OperationResultCode::DETAIL_SUCCESS)); } // ble @@ -1345,13 +1335,12 @@ P2pClusterPcpHandler::StartListeningForIncomingConnectionsImpl( } else { started_mediums.push_back(WIFI_LAN); } - std::unique_ptr - operation_result_with_medium = GetOperationResultWithMediumByResultCode( + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( client_proxy, Medium::BLUETOOTH, update_index, wifi_lan_result.has_error() ? wifi_lan_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + : OperationResultCode::DETAIL_SUCCESS)); } if (started_mediums.empty()) { LOG(WARNING) << absl::StrFormat( @@ -1444,8 +1433,7 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( // restart std::vector restarted_mediums; - std::vector - operation_result_with_mediums; + std::vector operation_result_with_mediums; int update_index = client->GetAnalyticsRecorder().GetNextAdvertisingUpdateIndex(); Status status = {Status::kSuccess}; @@ -1458,12 +1446,9 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( if (new_mediums.ble) { if (old_mediums.ble && !needs_restart) { restarted_mediums.push_back(BLE); - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, BLE, update_index, - OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, BLE, update_index, OperationResultCode::DETAIL_SUCCESS)); } else { ErrorOr ble_result = {Error(OperationResultCode::DETAIL_UNKNOWN)}; ble_result = StartBleAdvertising( @@ -1476,14 +1461,12 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( status = {Status::kBleError}; } - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, BLE, update_index, - ble_result.has_error() - ? ble_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, BLE, update_index, + ble_result.has_error() + ? ble_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS)); } } // awdl @@ -1492,12 +1475,9 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( new_mediums.awdl && !advertising_options.low_power) { if (old_mediums.awdl && !needs_restart) { restarted_mediums.push_back(AWDL); - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, AWDL, update_index, - OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, AWDL, update_index, OperationResultCode::DETAIL_SUCCESS)); } else { ErrorOr awdl_result = StartAwdlAdvertising( client, std::string(service_id), std::string(local_endpoint_id), @@ -1507,26 +1487,22 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( } else { status = {Status::kWifiLanError}; } - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, AWDL, update_index, - awdl_result.has_error() - ? awdl_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, AWDL, update_index, + awdl_result.has_error() + ? awdl_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS)); } } // wifi lan if (new_mediums.wifi_lan && !advertising_options.low_power) { if (old_mediums.wifi_lan && !needs_restart) { restarted_mediums.push_back(WIFI_LAN); - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, WIFI_LAN, update_index, - OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, WIFI_LAN, update_index, + OperationResultCode::DETAIL_SUCCESS)); } else { ErrorOr wifi_lan_result = StartWifiLanAdvertising( client, std::string(service_id), std::string(local_endpoint_id), @@ -1537,26 +1513,22 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( } else { status = {Status::kWifiLanError}; } - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, WIFI_LAN, update_index, - wifi_lan_result.has_error() - ? wifi_lan_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, WIFI_LAN, update_index, + wifi_lan_result.has_error() + ? wifi_lan_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS)); } } // bluetooth classic if (new_mediums.bluetooth && !advertising_options.low_power) { if (old_mediums.bluetooth && !needs_restart) { restarted_mediums.push_back(BLUETOOTH); - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, BLUETOOTH, update_index, - OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, BLUETOOTH, update_index, + OperationResultCode::DETAIL_SUCCESS)); } else { const ByteArray bluetooth_hash = GenerateHash( std::string(service_id), BluetoothDeviceName::kServiceIdHashLength); @@ -1590,27 +1562,19 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( restarted_mediums.push_back(BLUETOOTH); } - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, BLUETOOTH, update_index, - bluetooth_result.has_error() - ? bluetooth_result.error() - .operation_result_code() - .value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, BLUETOOTH, update_index, + bluetooth_result.has_error() + ? bluetooth_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS)); } else { - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, BLUETOOTH, update_index, - bluetooth_result.has_error() - ? bluetooth_result.error() - .operation_result_code() - .value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, BLUETOOTH, update_index, + bluetooth_result.has_error() + ? bluetooth_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS)); return StartOperationResult{.status = {Status::kBluetoothError}, .mediums = restarted_mediums, .operation_result_with_mediums = std::move( @@ -1662,8 +1626,7 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( bool should_start_discovery = false; auto new_mediums = discovery_options.allowed; auto old_mediums = old_options.allowed; - std::vector - operation_result_with_mediums; + std::vector operation_result_with_mediums; int update_index = client->GetAnalyticsRecorder().GetNextDiscoveryUpdateIndex(); // ble @@ -1671,12 +1634,9 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( should_start_discovery = true; if (old_mediums.ble) { restarted_mediums.push_back(BLE); - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, BLE, update_index, - OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, BLE, update_index, OperationResultCode::DETAIL_SUCCESS)); } else { ErrorOr ble_result = {Error(OperationResultCode::DETAIL_UNKNOWN)}; ble_result = @@ -1688,14 +1648,12 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( "restart ble scanning"; } - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, BLE, update_index, - ble_result.has_error() - ? ble_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, BLE, update_index, + ble_result.has_error() + ? ble_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS)); } } // bt classic @@ -1703,12 +1661,10 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( should_start_discovery = true; if (!needs_restart && old_mediums.bluetooth) { restarted_mediums.push_back(BLUETOOTH); - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, BLUETOOTH, update_index, - OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, BLUETOOTH, update_index, + OperationResultCode::DETAIL_SUCCESS)); } else { StartBluetoothDiscoveryWithPause( client, std::string(service_id), discovery_options, restarted_mediums, @@ -1722,12 +1678,10 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( should_start_discovery = true; if (!needs_restart && old_mediums.awdl) { restarted_mediums.push_back(AWDL); - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, AWDL, update_index, - OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, AWDL, update_index, + OperationResultCode::DETAIL_SUCCESS)); } else { ErrorOr awdl_result = StartAwdlDiscovery(client, std::string(service_id)); @@ -1737,14 +1691,12 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( LOG(WARNING) << "UpdateDiscoveryOptionsImpl: unable to restart " "awdl scanning"; } - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, AWDL, update_index, - awdl_result.has_error() - ? awdl_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, AWDL, update_index, + awdl_result.has_error() + ? awdl_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS)); } } // wifi lan @@ -1752,12 +1704,10 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( should_start_discovery = true; if (!needs_restart && old_mediums.wifi_lan) { restarted_mediums.push_back(WIFI_LAN); - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, WIFI_LAN, update_index, - OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, WIFI_LAN, update_index, + OperationResultCode::DETAIL_SUCCESS)); } else { ErrorOr wifi_lan_result = StartWifiLanDiscovery(client, std::string(service_id)); @@ -1767,14 +1717,12 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( LOG(WARNING) << "UpdateDiscoveryOptionsImpl: unable to restart " "wifi lan scanning"; } - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, WIFI_LAN, update_index, - wifi_lan_result.has_error() - ? wifi_lan_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, WIFI_LAN, update_index, + wifi_lan_result.has_error() + ? wifi_lan_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS)); } } if (restarted_mediums.empty() && should_start_discovery) { @@ -1947,8 +1895,7 @@ void P2pClusterPcpHandler::StartBluetoothDiscoveryWithPause( ClientProxy* client, const std::string& service_id, const DiscoveryOptions& discovery_options, std::vector& mediums_started_successfully, - std::vector& - operation_result_with_mediums, + std::vector& operation_result_with_mediums, int update_index) { if (bluetooth_radio_.IsEnabled()) { if (ble_medium_.IsExtendedAdvertisementsAvailable() && @@ -1966,16 +1913,12 @@ void P2pClusterPcpHandler::StartBluetoothDiscoveryWithPause( bluetooth_classic_client_id_to_service_id_map_.insert( {client->GetClientId(), service_id}); } - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, BLUETOOTH, update_index, - bluetooth_result.has_error() - ? bluetooth_result.error() - .operation_result_code() - .value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, BLUETOOTH, update_index, + bluetooth_result.has_error() + ? bluetooth_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS)); } else { LOG(INFO) << "Pause bluetooth discovery for service id : " << service_id; @@ -1993,14 +1936,12 @@ void P2pClusterPcpHandler::StartBluetoothDiscoveryWithPause( bluetooth_classic_client_id_to_service_id_map_.insert( {client->GetClientId(), service_id}); } - std::unique_ptr - operation_result_with_medium = - GetOperationResultWithMediumByResultCode( - client, BLUETOOTH, update_index, - bluetooth_result.has_error() - ? bluetooth_result.error().operation_result_code().value() - : OperationResultCode::DETAIL_SUCCESS); - operation_result_with_mediums.push_back(*operation_result_with_medium); + operation_result_with_mediums.push_back( + GetOperationResultWithMediumByResultCode( + client, BLUETOOTH, update_index, + bluetooth_result.has_error() + ? bluetooth_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS)); } } else { LOG(WARNING) << "Ignore to discover on bluetooth for service id: " diff --git a/connections/implementation/p2p_cluster_pcp_handler.h b/connections/implementation/p2p_cluster_pcp_handler.h index 712f362f..d5d2c345 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.h +++ b/connections/implementation/p2p_cluster_pcp_handler.h @@ -25,6 +25,7 @@ #include "absl/strings/string_view.h" #include "connections/advertising_options.h" #include "connections/discovery_options.h" +#include "connections/implementation/analytics/operation_result_with_medium.h" #include "connections/implementation/base_pcp_handler.h" #include "connections/implementation/ble_advertisement.h" #include "connections/implementation/bluetooth_device_name.h" @@ -207,8 +208,8 @@ class P2pClusterPcpHandler : public BasePcpHandler { ClientProxy* client, const std::string& service_id, const DiscoveryOptions& discovery_options, std::vector& mediums_started_successfully, - std::vector& operation_result_with_mediums, + std::vector& + operation_result_with_mediums, int update_index); BasePcpHandler::ConnectImplResult BluetoothConnectImpl( ClientProxy* client, BluetoothEndpoint* endpoint); diff --git a/connections/implementation/payload_manager.cc b/connections/implementation/payload_manager.cc index 6529b211..9fdd392d 100644 --- a/connections/implementation/payload_manager.cc +++ b/connections/implementation/payload_manager.cc @@ -36,7 +36,6 @@ #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/internal_payload.h" #include "connections/implementation/internal_payload_factory.h" -#include "connections/implementation/proto/offline_wire_formats.pb.h" #include "connections/listeners.h" #include "connections/medium_selector.h" #include "connections/payload.h" @@ -52,7 +51,6 @@ #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" #include "internal/platform/single_thread_executor.h" -#include "proto/connections_enums.pb.h" namespace nearby { namespace connections { diff --git a/sharing/BUILD b/sharing/BUILD index 063a477a..5020ce68 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -389,6 +389,7 @@ cc_library( "//connections:core", "//connections:core_types", "//connections/implementation:internal", + "//connections/implementation/analytics:analytics_recorder_impl", "//internal/analytics:event_logger", "//internal/base", "//internal/base:file_path", diff --git a/sharing/nearby_connections_service_impl.cc b/sharing/nearby_connections_service_impl.cc index b0d3a89d..51d235fc 100644 --- a/sharing/nearby_connections_service_impl.cc +++ b/sharing/nearby_connections_service_impl.cc @@ -31,6 +31,7 @@ #include "connections/connection_options.h" #include "connections/core.h" #include "connections/discovery_options.h" +#include "connections/implementation/analytics/analytics_recorder_impl.h" #include "connections/implementation/service_controller_router.h" #include "connections/listeners.h" #include "connections/medium_selector.h" @@ -51,6 +52,7 @@ namespace nearby { namespace sharing { namespace { +using ::nearby::analytics::AnalyticsRecorderImpl; using ::nearby::connections::ConnectionRequestInfo; using ::nearby::connections::ConnectionResponseInfo; using ::nearby::connections::Core; @@ -85,7 +87,8 @@ NearbyConnectionsServiceImpl::NearbyConnectionsServiceImpl( // at an invalid instance. return connectivity_manager_.IsHPRealtekDevice(); }); - static Core* core = new Core(event_logger, router); + static Core* core = + new Core(std::make_unique(event_logger), router); service_handle_ = core; } From 1e9af15efb7b54f7de469c527c959aaa7cf380e0 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 1 Jun 2026 18:03:46 -0700 Subject: [PATCH 130/151] Disconnect session when binding is successful. PiperOrigin-RevId: 925016908 --- sharing/nearby_sharing_service_impl.cc | 5 +++++ sharing/nearby_sharing_service_impl_test.cc | 14 ++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index ef4f3f83..49f16308 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -2669,6 +2669,11 @@ void NearbySharingServiceImpl::OnPeerSyncBindingComplete( session->Abort(TransferMetadata::Status::kFailed); return; } + LOG(INFO) << __func__ << ": Sync binding response succeeded, disconnecting."; + // Binding receiver side will wait for connection disconnect after sending the + // BindingResponse message. + session->Disconnect(); + sync::SyncBinding binding; binding.set_binding_id(binding_id); binding.set_source_name(session->share_target().device_name); diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index fb503628..20bd479d 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -5053,13 +5053,9 @@ TEST_F(NearbySharingServiceImplTest, InitiatePairingSuccess) { FlushTesting(); // Verify data sent to the remote device so far. - if (!ExpectPairedKeyEncryptionFrame()) { - return; - } + EXPECT_TRUE(ExpectPairedKeyEncryptionFrame()); + EXPECT_TRUE(ExpectPairedKeyResultFrame()); - if (!ExpectPairedKeyResultFrame()) { - return; - } // Check BindingRequest frame sent to the remote device. std::unique_ptr frame = GetWrittenFrame(); ASSERT_TRUE(frame->has_v1()); @@ -5082,8 +5078,10 @@ TEST_F(NearbySharingServiceImplTest, InitiatePairingSuccess) { result_bytes.size()); ReceiveMessageFromConnection(std::move(result_bytes)); - // Wait for the transfer updates. - EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout)); + // Verify that connection is closed. + EXPECT_FALSE( + fake_nearby_connections_manager_->connection_endpoint_info(kEndpointId) + .has_value()); std::optional binding = preference_manager_.GetSyncBindingValue(); From 0e96ed9795d2d26f514096979c4da58b40a3a6b7 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 1 Jun 2026 18:44:22 -0700 Subject: [PATCH 131/151] Remove EventLogger. PiperOrigin-RevId: 925032163 --- connections/c/BUILD | 4 +- connections/c/nc.cc | 11 +- connections/implementation/BUILD | 2 - connections/implementation/analytics/BUILD | 10 +- .../analytics/analytics_recorder_impl.cc | 1643 ----------- .../analytics/analytics_recorder_impl.h | 459 --- .../analytics/analytics_recorder_impl_test.cc | 2579 ----------------- internal/analytics/BUILD | 50 - internal/analytics/event_logger.h | 41 - internal/analytics/mock_event_logger.h | 38 - internal/analytics/sharing_log_matchers.h | 64 - internal/platform/implementation/BUILD | 2 + internal/platform/implementation/g3/BUILD | 1 - internal/proto/analytics/BUILD | 16 + sharing/BUILD | 10 +- sharing/incoming_share_session_test.cc | 4 +- sharing/nearby_connections_manager_factory.cc | 2 +- sharing/nearby_connections_manager_factory.h | 2 +- sharing/nearby_connections_service_impl.cc | 2 +- sharing/nearby_connections_service_impl.h | 2 +- sharing/nearby_sharing_service_factory.cc | 2 +- sharing/nearby_sharing_service_factory.h | 2 +- sharing/nearby_sharing_service_impl_test.cc | 2 +- sharing/outgoing_share_session_test.cc | 4 +- sharing/share_session_test.cc | 2 +- 25 files changed, 50 insertions(+), 4904 deletions(-) delete mode 100644 connections/implementation/analytics/analytics_recorder_impl.cc delete mode 100644 connections/implementation/analytics/analytics_recorder_impl.h delete mode 100644 connections/implementation/analytics/analytics_recorder_impl_test.cc delete mode 100644 internal/analytics/BUILD delete mode 100644 internal/analytics/event_logger.h delete mode 100644 internal/analytics/mock_event_logger.h delete mode 100644 internal/analytics/sharing_log_matchers.h diff --git a/connections/c/BUILD b/connections/c/BUILD index b747460e..930b191c 100644 --- a/connections/c/BUILD +++ b/connections/c/BUILD @@ -53,7 +53,6 @@ cc_library( "//connections:core_types", "//connections/implementation/analytics:analytics_recorder_impl", "//connections/implementation/flags:connections_flags", - "//internal/analytics:event_logger", "//internal/flags:flag_reader", "//internal/flags:nearby_flags", "//internal/platform:base", @@ -61,7 +60,8 @@ cc_library( "//internal/platform:logging", "//internal/platform:mac_address", "//internal/platform:types", - "//internal/proto/analytics:connections_log_cc_proto", + "//location/nearby/analytics/cpp/logging:event_logger", + "//location/nearby/analytics/cpp/proto:connections_log_cc_proto", "//sharing/proto/analytics:sharing_log_cc_proto", "@com_google_absl//absl/base:no_destructor", "@com_google_absl//absl/container:flat_hash_map", diff --git a/connections/c/nc.cc b/connections/c/nc.cc index 5d631859..f31d1c8f 100644 --- a/connections/c/nc.cc +++ b/connections/c/nc.cc @@ -25,6 +25,10 @@ #include #include +#if !defined(NC_OSS_BUILD) +#include "location/nearby/analytics/cpp/logging/event_logger.h" +#include "location/nearby/analytics/cpp/proto/connections_log.pb.h" +#endif // !defined(NC_OSS_BUILD) #include "absl/base/no_destructor.h" #include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" @@ -45,7 +49,6 @@ #include "connections/payload.h" #include "connections/status.h" #include "connections/strategy.h" -#include "internal/analytics/event_logger.h" #include "internal/flags/flag.h" #include "internal/flags/flag_reader.h" #include "internal/flags/nearby_flags.h" @@ -53,7 +56,6 @@ #include "internal/platform/file.h" #include "internal/platform/logging.h" #include "internal/platform/mac_address.h" -#include "internal/proto/analytics/connections_log.pb.h" #include "sharing/proto/analytics/nearby_sharing_log.pb.h" #if TARGET_OS_IOS #include "internal/platform/implementation/apple/nearby_logger.h" @@ -122,6 +124,7 @@ class FlagReaderWrapper : public nearby::flags::FlagReader { NC_PHENOTYPE_FLAG_READER phenotype_flag_reader_; }; +#if !defined(NC_OSS_BUILD) // This is a bridging class between the C API and the C++ EventLogger interface. class NcEventLogger : public ::nearby::analytics::EventLogger { public: @@ -149,6 +152,10 @@ class NcEventLogger : public ::nearby::analytics::EventLogger { private: const NC_EVENT_LOGGER* event_logger_; }; +#else // !defined(NC_OSS_BUILD) +class NcEventLogger; +#endif // !defined(NC_OSS_BUILD) + } // namespace typedef struct NcContext { diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 4f026fbb..334a3149 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -468,7 +468,6 @@ cc_test( "//connections/implementation/analytics:mock_analytics_recorder", "//connections/implementation/flags:connections_flags", "//connections/v3:v3_types", - "//internal/analytics:mock_event_logger", "//internal/flags:nearby_flags", "//internal/interop:device", "//internal/platform:base", @@ -478,7 +477,6 @@ cc_test( "//internal/platform/implementation/g3", # build_cleaner: keep "//proto:connections_enums_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/time", diff --git a/connections/implementation/analytics/BUILD b/connections/implementation/analytics/BUILD index 006a2292..d893305c 100644 --- a/connections/implementation/analytics/BUILD +++ b/connections/implementation/analytics/BUILD @@ -54,12 +54,12 @@ cc_library( deps = [ ":analytics", "//connections:core_types", - "//internal/analytics:event_logger", "//internal/platform:error_code_recorder", "//internal/platform:logging", "//internal/platform:types", "//internal/platform/implementation:types", - "//internal/proto/analytics:connections_log_cc_proto", + "//location/nearby/analytics/cpp/logging:event_logger", + "//location/nearby/analytics/cpp/proto:connections_log_cc_proto", "//proto:connections_enums_cc_proto", "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/base:core_headers", @@ -99,15 +99,13 @@ cc_test( ":analytics", ":analytics_recorder_impl", "//connections:core_types", - "//internal/analytics:mock_event_logger", "//internal/platform:base", "//internal/platform:error_code_recorder", - "//internal/platform:logging", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/proto/analytics:connections_log_cc_proto", - "//internal/test", + "//location/nearby/analytics/cpp/logging:mock_event_logger", + "//location/nearby/analytics/cpp/proto:connections_log_cc_proto", "//net/proto2/contrib/parse_proto:parse_text_proto", "//proto:connections_enums_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", diff --git a/connections/implementation/analytics/analytics_recorder_impl.cc b/connections/implementation/analytics/analytics_recorder_impl.cc deleted file mode 100644 index 211cc2dd..00000000 --- a/connections/implementation/analytics/analytics_recorder_impl.cc +++ /dev/null @@ -1,1643 +0,0 @@ -// Copyright 2022-2023 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. - -#include "connections/implementation/analytics/analytics_recorder_impl.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "absl/algorithm/container.h" -#include "absl/container/btree_map.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "connections/implementation/analytics/advertising_metadata_params.h" -#include "connections/implementation/analytics/analytics_recorder.h" -#include "connections/implementation/analytics/connection_attempt_metadata_params.h" -#include "connections/implementation/analytics/discovery_metadata_params.h" -#include "connections/implementation/analytics/operation_result_with_medium.h" -#include "connections/payload_type.h" -#include "connections/strategy.h" -#include "internal/analytics/event_logger.h" -#include "internal/platform/error_code_params.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex_lock.h" -#include "internal/proto/analytics/connections_log.pb.h" -#include "proto/connections_enums.pb.h" -#include "google/protobuf/repeated_ptr_field.h" - -namespace nearby::analytics { - -namespace { -// const char kVersion_1_0_0[] = "v1.0.0"; -const char kVersion[] = "v1.5.0"; -constexpr absl::string_view kOnStartClientSession = "OnStartClientSession"; -const absl::Duration kConnectionTokenMaxLife = absl::Hours(24); - -using ::location::nearby::analytics::proto::ConnectionsLog; -using ::location::nearby::proto::connections::ACCEPTED; -using ::location::nearby::proto::connections::ADVERTISER; -using ::location::nearby::proto::connections::BandwidthUpgradeErrorStage; -using ::location::nearby::proto::connections::BandwidthUpgradeResult; -using ::location::nearby::proto::connections::BYTES; -using ::location::nearby::proto::connections::CLIENT_SESSION; -using ::location::nearby::proto::connections::CONNECTION_CLOSED; -using ::location::nearby::proto::connections::ConnectionAttemptDirection; -using ::location::nearby::proto::connections::ConnectionAttemptResult; -using ::location::nearby::proto::connections::ConnectionAttemptType; -using ::location::nearby::proto::connections::ConnectionRequestResponse; -using ::location::nearby::proto::connections::ConnectionsStrategy; -using ::location::nearby::proto::connections::DisconnectionReason; -using ::location::nearby::proto::connections::DISCOVERER; -using ::location::nearby::proto::connections::ERROR_CODE; -using ::location::nearby::proto::connections::EventType; -using ::location::nearby::proto::connections::FILE; -using ::location::nearby::proto::connections::IGNORED; -using ::location::nearby::proto::connections::INCOMING; -using ::location::nearby::proto::connections::INITIAL; -using ::location::nearby::proto::connections::Medium; -using ::location::nearby::proto::connections::MOVED_TO_NEW_MEDIUM; -using ::location::nearby::proto::connections::NOT_SENT; -using ::location::nearby::proto::connections::OperationResultCategory; -using ::location::nearby::proto::connections::OperationResultCode; -using ::location::nearby::proto::connections::OUTGOING; -using ::location::nearby::proto::connections::P2P_CLUSTER; -using ::location::nearby::proto::connections::P2P_POINT_TO_POINT; -using ::location::nearby::proto::connections::P2P_STAR; -using ::location::nearby::proto::connections::PayloadStatus; -using ::location::nearby::proto::connections::PayloadType; -using ::location::nearby::proto::connections::REJECTED; -using ::location::nearby::proto::connections::RESULT_SUCCESS; -using ::location::nearby::proto::connections::SessionRole; -using ::location::nearby::proto::connections::START_CLIENT_SESSION; -using ::location::nearby::proto::connections::START_STRATEGY_SESSION; -using ::location::nearby::proto::connections::STOP_CLIENT_SESSION; -using ::location::nearby::proto::connections::STOP_STRATEGY_SESSION; -using ::location::nearby::proto::connections::StopAdvertisingReason; -using ::location::nearby::proto::connections::StopDiscoveringReason; -using ::location::nearby::proto::connections::STREAM; -using ::location::nearby::proto::connections::UNFINISHED; -using ::location::nearby::proto::connections::UNFINISHED_ERROR; -using ::location::nearby::proto::connections::UNKNOWN_MEDIUM; -using ::location::nearby::proto::connections::UNKNOWN_PAYLOAD_TYPE; -using ::location::nearby::proto::connections::UNKNOWN_STRATEGY; -using ::location::nearby::proto::connections::UPGRADE_RESULT_SUCCESS; -using ::location::nearby::proto::connections::UPGRADE_SUCCESS; -using ::location::nearby::proto::connections::UPGRADE_UNFINISHED; -using ::location::nearby::proto::connections::UPGRADED; -using ::nearby::analytics::EventLogger; -using ProtoSafeDisconnectionResult = ::location::nearby::analytics::proto:: - ConnectionsLog::EstablishedConnection::SafeDisconnectionResult; - -OperationResultCategory ConvertToOperationResultCategory( - OperationResultCode result_code) { - if (result_code == OperationResultCode::DETAIL_SUCCESS) { - return OperationResultCategory::CATEGORY_SUCCESS; - } - // TODO(b/409865630): check later if we need to add back the dct error. - // Section of CATEGORY_DCT_ERROR, from 5000 to 5499 if (result_code - // >= OperationResultCode::DCT_ERROR_BLE_DISABLED) { - // return OperationResultCategory::CATEGORY_DCT_ERROR; - //} - - // Section of CATEGORY_NEARBY_ERROR, starting from 4500 to 4999 - if (result_code >= - OperationResultCode::NEARBY_BLE_ADVERTISEMENT_MAPPING_TO_MAC_ERROR) { - return OperationResultCategory::CATEGORY_NEARBY_ERROR; - } - // Section of CATEGORY_CONNECTIVITY_ERROR, starting from 3500 to 4499 - if (result_code >= - OperationResultCode::CONNECTIVITY_WIFI_AWARE_ATTACH_FAILURE) { - return OperationResultCategory::CATEGORY_CONNECTIVITY_ERROR; - } - // Section of CATEGORY_IO_ERROR, from 3000 to 3499 - if (result_code >= OperationResultCode::IO_FILE_OPENING_ERROR) { - return OperationResultCategory::CATEGORY_IO_ERROR; - } - // Section of CATEGORY_MISCELLANEOUS, from 2500 to 2999 - if (result_code >= - OperationResultCode::MISCELLEANEOUS_BLUETOOTH_MAC_ADDRESS_NULL) { - return OperationResultCategory::CATEGORY_MISCELLANEOUS; - } - // Section of CATEGORY_CLIENT_ERROR, from 2000 to 2499 - if (result_code >= - OperationResultCode:: - CLIENT_WIFI_DIRECT_ALREADY_HOSTING_DIRECT_GROUP_FOR_THIS_CLIENT) { - return OperationResultCategory::CATEGORY_CLIENT_ERROR; - } - // Section of CATEGORY_MEDIUM_UNAVAILABLE, from 1500 to 1999 - if (result_code >= OperationResultCode:: - MEDIUM_UNAVAILABLE_WIFI_AWARE_RESOURCE_NOT_AVAILABLE) { - return OperationResultCategory::CATEGORY_MEDIUM_UNAVAILABLE; - } - // Section of CATEGORY_DEVICE_STATE_ERROR, from 1000 to 1499 - if (result_code >= - OperationResultCode::DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS) { - return OperationResultCategory::CATEGORY_DEVICE_STATE_ERROR; - } - // Section of CATEGORY_CLIENT_CANCELLATION, from 500 to 999 - if (result_code >= - OperationResultCode::CLIENT_CANCELLATION_REMOTE_IN_CANCELED_STATE) { - return OperationResultCategory::CATEGORY_CLIENT_CANCELLATION; - } - // Clarify other non success cases as unknown - return OperationResultCategory::CATEGORY_UNKNOWN; -} - -ProtoSafeDisconnectionResult ConvertToProtoSafeDisconnectionResult( - SafeDisconnectionResult result) { - switch (result) { - case SafeDisconnectionResult::kSafeDisconnection: - return ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION; - case SafeDisconnectionResult::kUnsafeDisconnection: - return ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION; - default: - return ConnectionsLog::EstablishedConnection:: - UNKNOWN_SAFE_DISCONNECTION_RESULT; - } -} - -ConnectionsLog::OperationResultWithMedium -ConvertToProtoOperationResultWithMedium( - const nearby::analytics::OperationResultWithMedium& cpp_result) { - ConnectionsLog::OperationResultWithMedium proto_result; - proto_result.set_medium(cpp_result.medium); - if (cpp_result.update_index.has_value()) { - proto_result.set_update_index(cpp_result.update_index.value()); - } - proto_result.set_result_category(cpp_result.result_category); - proto_result.set_result_code(cpp_result.result_code); - if (cpp_result.connection_mode.has_value()) { - proto_result.set_connection_mode(cpp_result.connection_mode.value()); - } - return proto_result; -} - -} // namespace - -AnalyticsRecorderImpl::AnalyticsRecorderImpl(EventLogger* event_logger) - : event_logger_(event_logger) { - VLOG(1) << "Start AnalyticsRecorderImpl ctor event_logger_=" << event_logger_; - LogStartSession(); -} - -AnalyticsRecorderImpl::~AnalyticsRecorderImpl() = default; - -bool AnalyticsRecorderImpl::IsSessionLogged() { - MutexLock lock(&mutex_); - return session_was_logged_; -} - -int AnalyticsRecorderImpl::GetLatestUpdateIndexLocked( - const std::vector& list) { - int latest_update_index = 0; - for (const auto& operation_result_with_medium : list) { - if (operation_result_with_medium.update_index() > latest_update_index) { - latest_update_index = operation_result_with_medium.update_index(); - } - } - return latest_update_index; -} - -void AnalyticsRecorderImpl::OnStartAdvertising( - connections::Strategy strategy, const std::vector& mediums, - AdvertisingMetadataParams* advertising_metadata_params) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStartAdvertising")) { - return; - } - if (!strategy.IsValid()) { - LOG(INFO) << "AnalyticsRecorderImpl OnStartAdvertising with unknown " - "strategy, bail out."; - return; - } - // Initialize/update a StrategySession. - UpdateStrategySessionLocked(strategy, ADVERTISER); - - // Initialize and set a AdvertisingPhase. - started_advertising_phase_time_ = SystemClock::ElapsedRealtime(); - current_advertising_phase_ = - std::make_unique(); - absl::c_copy(mediums, RepeatedFieldBackInserter( - current_advertising_phase_->mutable_medium())); - // Set a AdvertisingMetadata. - AdvertisingMetadataParams default_params = {}; - if (advertising_metadata_params == nullptr) { - advertising_metadata_params = &default_params; - } - if (!advertising_metadata_params->operation_result_with_mediums.empty()) { - for (const auto& cpp_result : - advertising_metadata_params->operation_result_with_mediums) { - *current_advertising_phase_->add_adv_dis_result() = - ConvertToProtoOperationResultWithMedium(cpp_result); - } - } - auto* advertising_metadata = - current_advertising_phase_->mutable_advertising_metadata(); - advertising_metadata->set_supports_extended_ble_advertisements( - advertising_metadata_params->is_extended_advertisement_supported); - advertising_metadata->set_connected_ap_frequency( - advertising_metadata_params->connected_ap_frequency); - advertising_metadata->set_supports_nfc_technology( - advertising_metadata_params->is_nfc_available); -} - -void AnalyticsRecorderImpl::OnStopAdvertising() { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStopAdvertising")) { - return; - } - RecordAdvertisingPhaseDurationAndReasonLocked(/* on_stop= */ true); -} - -int AnalyticsRecorderImpl::GetNextAdvertisingUpdateIndex() { - MutexLock lock(&mutex_); - - if (current_advertising_phase_ == nullptr) { - return 0; - } - return GetLatestUpdateIndexLocked( - std::vector( - current_advertising_phase_->adv_dis_result().begin(), - current_advertising_phase_->adv_dis_result().end())) + - 1; -} - -void AnalyticsRecorderImpl::OnStartDiscovery( - connections::Strategy strategy, const std::vector& mediums, - DiscoveryMetadataParams* discovery_metadata_params) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStartDiscovery")) { - return; - } - if (!strategy.IsValid()) { - LOG(INFO) << "AnalyticsRecorderImpl OnStartDiscovery unknown " - "strategy enter, bail out."; - return; - } - - // Initialize/update a StrategySession. - UpdateStrategySessionLocked(strategy, DISCOVERER); - - // Initialize and set a DiscoveryPhase. - started_discovery_phase_time_ = SystemClock::ElapsedRealtime(); - current_discovery_phase_ = std::make_unique(); - absl::c_copy(mediums, RepeatedFieldBackInserter( - current_discovery_phase_->mutable_medium())); - // Set a DiscoveryMetadata. - DiscoveryMetadataParams default_params = {}; - if (discovery_metadata_params == nullptr) { - discovery_metadata_params = &default_params; - } - if (!discovery_metadata_params->operation_result_with_mediums.empty()) { - for (const auto& cpp_result : - discovery_metadata_params->operation_result_with_mediums) { - *current_discovery_phase_->add_adv_dis_result() = - ConvertToProtoOperationResultWithMedium(cpp_result); - } - } - auto* discovery_metadata = - current_discovery_phase_->mutable_discovery_metadata(); - discovery_metadata->set_supports_extended_ble_advertisements( - discovery_metadata_params->is_extended_advertisement_supported); - discovery_metadata->set_connected_ap_frequency( - discovery_metadata_params->connected_ap_frequency); - discovery_metadata->set_supports_nfc_technology( - discovery_metadata_params->is_nfc_available); -} - -void AnalyticsRecorderImpl::OnStopDiscovery() { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStopDiscovery")) { - return; - } - RecordDiscoveryPhaseDurationAndReasonLocked(/*on_stop=*/true); -} - -int AnalyticsRecorderImpl::GetNextDiscoveryUpdateIndex() { - MutexLock lock(&mutex_); - if (current_discovery_phase_ == nullptr) { - return 0; - } - return GetLatestUpdateIndexLocked( - std::vector( - current_discovery_phase_->adv_dis_result().begin(), - current_discovery_phase_->adv_dis_result().end())) + - 1; -} - -void AnalyticsRecorderImpl::OnStartedIncomingConnectionListening( - connections::Strategy strategy) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStartedIncomingConnectionListening")) { - return; - } - UpdateStrategySessionLocked(strategy, ADVERTISER); - if (started_advertising_phase_time_ == absl::InfinitePast()) { - started_advertising_phase_time_ = SystemClock::ElapsedRealtime(); - } -} - -void AnalyticsRecorderImpl::OnStoppedIncomingConnectionListening() { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnStoppedIncomingConnectionListening")) { - return; - } - RecordAdvertisingPhaseDurationAndReasonLocked(/* on_stop= */ false); -} - -void AnalyticsRecorderImpl::OnEndpointFound(Medium medium) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnEndpointFound")) { - return; - } - if (current_discovery_phase_ == nullptr) { - LOG(INFO) << "Unable to record discovered endpoint due to null " - "current_discovery_phase_"; - return; - } - ConnectionsLog::DiscoveredEndpoint* discovered_endpoint = - current_discovery_phase_->add_discovered_endpoint(); - discovered_endpoint->set_medium(medium); - discovered_endpoint->set_latency_millis(absl::ToInt64Milliseconds( - SystemClock::ElapsedRealtime() - started_discovery_phase_time_)); -} - -void AnalyticsRecorderImpl::OnRequestConnection( - const connections::Strategy& strategy, const std::string& endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("onRequestConnection")) { - return; - } - - UpdateStrategySessionLocked(strategy, DISCOVERER); - if (started_discovery_phase_time_ == absl::InfinitePast()) { - started_discovery_phase_time_ = SystemClock::ElapsedRealtime(); - } -} - -void AnalyticsRecorderImpl::OnConnectionRequestReceived( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnConnectionRequestReceived")) { - return; - } - absl::Time current_time = SystemClock::ElapsedRealtime(); - auto connection_request = - std::make_unique(); - connection_request->set_duration_millis(absl::ToUnixMillis(current_time)); - connection_request->set_request_delay_millis(absl::ToInt64Milliseconds( - current_time - started_advertising_phase_time_)); - incoming_connection_requests_.insert( - {remote_endpoint_id, std::move(connection_request)}); -} - -void AnalyticsRecorderImpl::OnConnectionRequestSent( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnConnectionRequestSent")) { - return; - } - absl::Time current_time = SystemClock::ElapsedRealtime(); - auto connection_request = - std::make_unique(); - connection_request->set_duration_millis(absl::ToUnixMillis(current_time)); - connection_request->set_request_delay_millis( - absl::ToInt64Milliseconds(current_time - started_discovery_phase_time_)); - outgoing_connection_requests_.insert( - {remote_endpoint_id, std::move(connection_request)}); -} - -void AnalyticsRecorderImpl::OnRemoteEndpointAccepted( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnRemoteEndpointAccepted")) { - return; - } - RemoteEndpointRespondedLocked(remote_endpoint_id, ACCEPTED); -} - -void AnalyticsRecorderImpl::OnLocalEndpointAccepted( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnLocalEndpointAccepted")) { - return; - } - LocalEndpointRespondedLocked(remote_endpoint_id, ACCEPTED); -} - -void AnalyticsRecorderImpl::OnRemoteEndpointRejected( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnRemoteEndpointRejected")) { - return; - } - RemoteEndpointRespondedLocked(remote_endpoint_id, REJECTED); -} - -void AnalyticsRecorderImpl::OnLocalEndpointRejected( - const std::string& remote_endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnLocalEndpointRejected")) { - return; - } - LocalEndpointRespondedLocked(remote_endpoint_id, REJECTED); -} - -void AnalyticsRecorderImpl::OnIncomingConnectionAttempt( - ConnectionAttemptType type, Medium medium, ConnectionAttemptResult result, - absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnIncomingConnectionAttempt")) { - return; - } - if (current_strategy_session_ == nullptr) { - LOG(INFO) << "Unable to record incoming connection attempt due to " - "null current_strategy_session_"; - return; - } - - ConnectionAttemptMetadataParams default_params = {}; - if (connection_attempt_metadata_params == nullptr) { - connection_attempt_metadata_params = &default_params; - } - OnIncomingConnectionAttemptLocked(type, medium, result, duration, - connection_token, - connection_attempt_metadata_params); -} - -void AnalyticsRecorderImpl::OnIncomingConnectionAttemptLocked( - location::nearby::proto::connections::ConnectionAttemptType type, - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::ConnectionAttemptResult result, - absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { - auto* connection_attempt = - current_strategy_session_->add_connection_attempt(); - connection_attempt->set_duration_millis(absl::ToInt64Milliseconds(duration)); - connection_attempt->set_type(type); - connection_attempt->set_direction(INCOMING); - connection_attempt->set_medium(medium); - connection_attempt->set_attempt_result(result); - connection_attempt->set_connection_token(connection_token); - - auto* connection_attempt_metadata = - connection_attempt->mutable_connection_attempt_metadata(); - connection_attempt_metadata->set_technology( - connection_attempt_metadata_params->technology); - connection_attempt_metadata->set_band( - connection_attempt_metadata_params->band); - connection_attempt_metadata->set_frequency( - connection_attempt_metadata_params->frequency); - connection_attempt_metadata->set_network_operator( - connection_attempt_metadata_params->network_operator); - connection_attempt_metadata->set_country_code( - connection_attempt_metadata_params->country_code); - connection_attempt_metadata->set_frequency( - connection_attempt_metadata_params->frequency); - connection_attempt_metadata->set_is_tdls_used( - connection_attempt_metadata_params->is_tdls_used); - connection_attempt_metadata->set_wifi_hotspot_status( - connection_attempt_metadata_params->wifi_hotspot_enabled); - connection_attempt_metadata->set_try_counts( - connection_attempt_metadata_params->try_count); - connection_attempt_metadata->set_max_tx_speed( - connection_attempt_metadata_params->max_wifi_tx_speed); - connection_attempt_metadata->set_max_rx_speed( - connection_attempt_metadata_params->max_wifi_rx_speed); - connection_attempt_metadata->set_wifi_channel_width( - connection_attempt_metadata_params->channel_width); - - auto operation_result_proto = - std::make_unique(); - operation_result_proto->set_result_code( - connection_attempt_metadata_params->operation_result_code); - operation_result_proto->set_result_category(ConvertToOperationResultCategory( - connection_attempt_metadata_params->operation_result_code)); - connection_attempt->set_allocated_operation_result( - operation_result_proto.release()); -} - -void AnalyticsRecorderImpl::OnOutgoingConnectionAttempt( - const std::string& remote_endpoint_id, ConnectionAttemptType type, - Medium medium, ConnectionAttemptResult result, absl::Duration duration, - const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnOutgoingConnectionAttempt")) { - return; - } - if (current_strategy_session_ == nullptr) { - LOG(INFO) << "Unable to record outgoing connection attempt due to " - "null current_strategy_session_"; - return; - } - - ConnectionAttemptMetadataParams default_params = {}; - if (connection_attempt_metadata_params == nullptr) { - connection_attempt_metadata_params = &default_params; - } - - // For the case of transfer a big file and the upgrades always failure, then - // there will have repeating upgrade attempt and cause many same attempt value - // be log. So add a method to skip. - if (ConnectionAttemptResultCodeExistedLocked( - medium, OUTGOING, connection_token, type, - connection_attempt_metadata_params->operation_result_code)) { - return; - } - - OnOutgoingConnectionAttemptLocked(remote_endpoint_id, type, medium, result, - duration, connection_token, - connection_attempt_metadata_params); -} - -void AnalyticsRecorderImpl::OnOutgoingConnectionAttemptLocked( - const std::string& remote_endpoint_id, ConnectionAttemptType type, - Medium medium, ConnectionAttemptResult result, absl::Duration duration, - const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) { - auto* connection_attempt = - current_strategy_session_->add_connection_attempt(); - connection_attempt->set_duration_millis(absl::ToInt64Milliseconds(duration)); - connection_attempt->set_type(type); - connection_attempt->set_direction(OUTGOING); - connection_attempt->set_medium(medium); - connection_attempt->set_attempt_result(result); - connection_attempt->set_connection_token(connection_token); - - auto* connection_attempt_metadata = - connection_attempt->mutable_connection_attempt_metadata(); - connection_attempt_metadata->set_technology( - connection_attempt_metadata_params->technology); - connection_attempt_metadata->set_band( - connection_attempt_metadata_params->band); - connection_attempt_metadata->set_frequency( - connection_attempt_metadata_params->frequency); - connection_attempt_metadata->set_network_operator( - connection_attempt_metadata_params->network_operator); - connection_attempt_metadata->set_country_code( - connection_attempt_metadata_params->country_code); - connection_attempt_metadata->set_frequency( - connection_attempt_metadata_params->frequency); - connection_attempt_metadata->set_is_tdls_used( - connection_attempt_metadata_params->is_tdls_used); - connection_attempt_metadata->set_wifi_hotspot_status( - connection_attempt_metadata_params->wifi_hotspot_enabled); - connection_attempt_metadata->set_try_counts( - connection_attempt_metadata_params->try_count); - connection_attempt_metadata->set_max_tx_speed( - connection_attempt_metadata_params->max_wifi_tx_speed); - connection_attempt_metadata->set_max_rx_speed( - connection_attempt_metadata_params->max_wifi_rx_speed); - connection_attempt_metadata->set_wifi_channel_width( - connection_attempt_metadata_params->channel_width); - - auto operation_result_proto = - std::make_unique(); - operation_result_proto->set_result_code( - connection_attempt_metadata_params->operation_result_code); - operation_result_proto->set_result_category(ConvertToOperationResultCategory( - connection_attempt_metadata_params->operation_result_code)); - connection_attempt->set_allocated_operation_result( - operation_result_proto.release()); - - if (type == INITIAL && result != RESULT_SUCCESS) { - auto it = outgoing_connection_requests_.find(remote_endpoint_id); - if (it != outgoing_connection_requests_.end()) { - // An outgoing, initial ConnectionAttempt has a corresponding - // ConnectionRequest that, since the ConnectionAttempt has failed, will - // never be delivered to the advertiser. - auto pair = outgoing_connection_requests_.extract(it); - std::unique_ptr& connection_request = - pair.mapped(); - connection_request->set_local_response(NOT_SENT); - connection_request->set_remote_response(NOT_SENT); - UpdateDiscovererConnectionRequestLocked(connection_request.get()); - } - } -} - -void AnalyticsRecorderImpl::OnConnectionEstablished( - const std::string& endpoint_id, Medium medium, - const std::string& connection_token) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnConnectionEstablished")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it != active_connections_.end()) { - const std::unique_ptr& logical_connection = it->second; - logical_connection->PhysicalConnectionEstablished(medium, connection_token); - } else { - active_connections_.insert( - {endpoint_id, - std::make_unique(medium, connection_token)}); - } -} - -void AnalyticsRecorderImpl::OnConnectionClosed(const std::string& endpoint_id, - Medium medium, - DisconnectionReason reason, - SafeDisconnectionResult result) { - MutexLock lock(&mutex_); - LOG(INFO) << __func__ - << ": OnConnectionClosed is called with endpoint_id:" << endpoint_id - << ", medium:" << Medium_Name(medium) - << ", reason:" << DisconnectionReason_Name(reason) - << ", result:" << static_cast(result); - - if (!CanRecordAnalyticsLocked("OnConnectionClosed")) { - return; - } - - if (current_strategy_session_ == nullptr) { - VLOG(1) << "AnalyticsRecorderImpl CanRecordAnalytics Unexpected call " - << __func__ << " since current_strategy_session_ is required."; - return; - } - - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->PhysicalConnectionClosed(medium, reason, result); - if (reason != UPGRADED) { - // Unless this is an upgraded connection, remove this from our active - // connections. Any future communication with an endpoint will need to be - // re-established with a new ConnectionRequest. - auto pair = active_connections_.extract(it); - std::unique_ptr& logical_connection = pair.mapped(); - - absl::c_copy( - logical_connection->GetEstablisedConnections(), - RepeatedFieldBackInserter( - current_strategy_session_->mutable_established_connection())); - } -} - -void AnalyticsRecorderImpl::OnIncomingPayloadStarted( - const std::string& endpoint_id, std::int64_t payload_id, - connections::PayloadType type, std::int64_t total_size_bytes) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnIncomingPayloadStarted")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->IncomingPayloadStarted( - payload_id, PayloadTypeToProtoPayloadType(type), total_size_bytes); -} - -void AnalyticsRecorderImpl::OnPayloadChunkReceived( - const std::string& endpoint_id, std::int64_t payload_id, - std::int64_t chunk_size_bytes) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnPayloadChunkReceived")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->ChunkReceived(payload_id, chunk_size_bytes); -} - -void AnalyticsRecorderImpl::OnIncomingPayloadDone( - const std::string& endpoint_id, std::int64_t payload_id, - PayloadStatus status, OperationResultCode operation_result_code) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnIncomingPayloadDone")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->IncomingPayloadDone(payload_id, status, - operation_result_code); -} - -void AnalyticsRecorderImpl::OnOutgoingPayloadStarted( - const std::vector& endpoint_ids, std::int64_t payload_id, - connections::PayloadType type, std::int64_t total_size_bytes) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnOutgoingPayloadStarted")) { - return; - } - for (const auto& endpoint_id : endpoint_ids) { - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - continue; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->OutgoingPayloadStarted( - payload_id, PayloadTypeToProtoPayloadType(type), total_size_bytes); - } -} - -void AnalyticsRecorderImpl::OnPayloadChunkSent(const std::string& endpoint_id, - std::int64_t payload_id, - std::int64_t chunk_size_bytes) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnPayloadChunkSent")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - const std::unique_ptr& logical_connection = it->second; - logical_connection->ChunkSent(payload_id, chunk_size_bytes); -} - -void AnalyticsRecorderImpl::OnOutgoingPayloadDone( - const std::string& endpoint_id, std::int64_t payload_id, - PayloadStatus status, OperationResultCode operation_result_code) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnOutgoingPayloadDone")) { - return; - } - auto it = active_connections_.find(endpoint_id); - if (it == active_connections_.end()) { - return; - } - - const std::unique_ptr& logical_connection = it->second; - logical_connection->OutgoingPayloadDone(payload_id, status, - operation_result_code); -} - -void AnalyticsRecorderImpl::OnBandwidthUpgradeStarted( - const std::string& endpoint_id, Medium from_medium, Medium to_medium, - ConnectionAttemptDirection direction, const std::string& connection_token) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnBandwidthUpgradeStarted")) { - return; - } - auto bandwidth_upgrade_attempt = - std::make_unique(); - bandwidth_upgrade_attempt->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime())); - bandwidth_upgrade_attempt->set_from_medium(from_medium); - bandwidth_upgrade_attempt->set_to_medium(to_medium); - bandwidth_upgrade_attempt->set_direction(direction); - bandwidth_upgrade_attempt->set_connection_token(connection_token); - bandwidth_upgrade_attempts_.insert( - {endpoint_id, std::move(bandwidth_upgrade_attempt)}); -} - -void AnalyticsRecorderImpl::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 AnalyticsRecorderImpl::OnBandwidthUpgradeError( - const std::string& endpoint_id, BandwidthUpgradeResult result, - BandwidthUpgradeErrorStage error_stage, - OperationResultCode operation_result_code) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnBandwidthUpgradeError")) { - return; - } - // If the same records existed, drop this one. - if (EraseIfBandwidthUpgradeRecordExistedLocked( - endpoint_id, result, error_stage, operation_result_code)) { - return; - } - FinishUpgradeAttemptLocked(endpoint_id, result, error_stage, - operation_result_code); -} - -void AnalyticsRecorderImpl::OnBandwidthUpgradeSuccess( - const std::string& endpoint_id) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnBandwidthUpgradeSuccess")) { - return; - } - FinishUpgradeAttemptLocked(endpoint_id, UPGRADE_RESULT_SUCCESS, - UPGRADE_SUCCESS, - OperationResultCode::DETAIL_SUCCESS); -} - -void AnalyticsRecorderImpl::OnErrorCode(const ErrorCodeParams& params) { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("OnErrorCode")) { - return; - } - auto error_code = std::make_unique(); - error_code->set_medium(params.medium); - error_code->set_event(params.event); - error_code->set_connection_token(params.connection_token); - error_code->set_description(params.description); - - if (params.is_common_error) { - error_code->set_common_error(params.common_error); - } else { - switch (params.event) { - case location::nearby::errorcode::proto::START_ADVERTISING: - error_code->set_start_advertising_error(params.start_advertising_error); - break; - case location::nearby::errorcode::proto::STOP_ADVERTISING: - error_code->set_stop_advertising_error(params.stop_advertising_error); - break; - case location::nearby::errorcode::proto:: - START_LISTENING_INCOMING_CONNECTION: - error_code->set_start_listening_incoming_connection_error( - params.start_listening_incoming_connection_error); - break; - case location::nearby::errorcode::proto:: - STOP_LISTENING_INCOMING_CONNECTION: - error_code->set_stop_listening_incoming_connection_error( - params.stop_listening_incoming_connection_error); - break; - case location::nearby::errorcode::proto::START_DISCOVERING: - error_code->set_start_discovering_error(params.start_discovering_error); - break; - case location::nearby::errorcode::proto::STOP_DISCOVERING: - error_code->set_stop_discovering_error(params.stop_discovering_error); - break; - case location::nearby::errorcode::proto::CONNECT: - error_code->set_connect_error(params.connect_error); - break; - case location::nearby::errorcode::proto::DISCONNECT: - error_code->set_disconnect_error(params.disconnect_error); - break; - case location::nearby::errorcode::proto::UNKNOWN_EVENT: - default: - error_code->set_common_error(params.common_error); - break; - } - } - - ConnectionsLog connections_log; - connections_log.set_event_type(ERROR_CODE); - connections_log.set_version(kVersion); - connections_log.set_allocated_error_code(error_code.release()); - - VLOG(1) << "AnalyticsRecorderImpl LogErrorCode connections_log=" - << connections_log.DebugString(); // NOLINT - - event_logger_->Log(connections_log); -} - -void AnalyticsRecorderImpl::LogStartSession() { - MutexLock lock(&mutex_); - if (start_client_session_was_logged_) { - LOG(WARNING) << "AnalyticsRecorderImpl CanRecordAnalytics Unexpected call " - << kOnStartClientSession - << " after start client session has already been logged."; - return; - } - - session_was_logged_ = false; - if (CanRecordAnalyticsLocked(kOnStartClientSession)) { - client_session_ = std::make_unique(); - started_client_session_time_ = SystemClock::ElapsedRealtime(); - start_client_session_was_logged_ = true; - LogEvent(START_CLIENT_SESSION); - } -} - -void AnalyticsRecorderImpl::LogSession() { - MutexLock lock(&mutex_); - if (!CanRecordAnalyticsLocked("LogSession")) { - return; - } - FinishStrategySessionLocked(); - client_session_->set_duration_millis(absl::ToInt64Milliseconds( - SystemClock::ElapsedRealtime() - started_client_session_time_)); - LogClientSessionLocked(); - LogEvent(STOP_CLIENT_SESSION); - start_client_session_was_logged_ = false; - session_was_logged_ = true; -} - -bool AnalyticsRecorderImpl::CanRecordAnalyticsLocked( - absl::string_view method_name) { - VLOG(1) << "AnalyticsRecorderImpl LogEvent " << method_name << " is calling."; - if (event_logger_ == nullptr) { - return false; - } - - if (session_was_logged_) { - VLOG(1) << "AnalyticsRecorderImpl CanRecordAnalytics Unexpected call " - << method_name << " after session has already been logged."; - return false; - } - - return true; -} - -// TODO: b/391339677 - Investigate why we need to reset the resources. And -// verify in b/238375695 to see if we still meet the issue after removing the -// Reset function. -void AnalyticsRecorderImpl::LogClientSessionLocked() { - ConnectionsLog connections_log; - connections_log.set_event_type(CLIENT_SESSION); - connections_log.set_allocated_client_session(client_session_.release()); - connections_log.set_version(kVersion); - - VLOG(1) << "AnalyticsRecorderImpl LogClientSession connections_log=" - << connections_log.DebugString(); // NOLINT - - event_logger_->Log(connections_log); - client_session_ = nullptr; -} - -void AnalyticsRecorderImpl::LogEvent(EventType event_type) { - ConnectionsLog connections_log; - connections_log.set_event_type(event_type); - connections_log.set_version(kVersion); - - VLOG(1) << "AnalyticsRecorderImpl LogEvent connections_log=" - << connections_log.DebugString(); // NOLINT - - event_logger_->Log(connections_log); -} - -void AnalyticsRecorderImpl::UpdateStrategySessionLocked( - connections::Strategy strategy, SessionRole role) { - // If we're not switching strategies, just update the current StrategySession - // with the new role. - if (strategy == current_strategy_ && current_strategy_session_ != nullptr) { - if (absl::c_linear_search(current_strategy_session_->role(), role)) { - // We've already acted as this role before, so make sure we've finished - // recording the previous round. - switch (role) { - case ADVERTISER: - FinishAdvertisingPhaseLocked(); - break; - case DISCOVERER: - FinishDiscoveryPhaseLocked(); - break; - default: - break; - } - } else { - current_strategy_session_->add_role(role); - } - } else { - // Otherwise, we're starting a new Strategy. - current_strategy_ = strategy; - FinishStrategySessionLocked(); - LogEvent(START_STRATEGY_SESSION); - current_strategy_session_ = - std::make_unique(); - started_strategy_session_time_ = SystemClock::ElapsedRealtime(); - current_strategy_session_->set_strategy( - StrategyToConnectionStrategy(strategy)); - current_strategy_session_->add_role(role); - } -} - -void AnalyticsRecorderImpl::RecordAdvertisingPhaseDurationAndReasonLocked( - bool on_stop) const { - if (current_advertising_phase_ == nullptr) { - LOG(INFO) << "Unable to record advertising phase duration due to " - "null current_advertising_phase_"; - return; - } - if (!current_advertising_phase_->has_duration_millis()) { - current_advertising_phase_->set_duration_millis(absl::ToInt64Milliseconds( - SystemClock::ElapsedRealtime() - started_advertising_phase_time_)); - } - if (!current_advertising_phase_->has_stop_reason()) { - current_advertising_phase_->set_stop_reason( - on_stop ? StopAdvertisingReason::CLIENT_STOP_ADVERTISING - : StopAdvertisingReason::FINISH_SESSION_STOP_ADVERTISING); - } -} - -void AnalyticsRecorderImpl::FinishAdvertisingPhaseLocked() { - if (current_advertising_phase_ != nullptr) { - for (const auto& item : incoming_connection_requests_) { - // ConnectionRequests still pending have been ignored by the local or - // remote (or both) endpoints. - const std::unique_ptr& - connection_request = item.second; - MarkConnectionRequestIgnoredLocked(connection_request.get()); - UpdateAdvertiserConnectionRequestLocked(connection_request.get()); - } - RecordAdvertisingPhaseDurationAndReasonLocked(/* on_stop= */ false); - if (current_strategy_session_ != nullptr) { - *current_strategy_session_->add_advertising_phase() = - *std::move(current_advertising_phase_); - } else { - LOG(INFO) << "Unable to record advertising phase due to null " - "current_strategy_session_"; - } - } - incoming_connection_requests_.clear(); -} - -void AnalyticsRecorderImpl::RecordDiscoveryPhaseDurationAndReasonLocked( - bool on_stop) const { - if (current_discovery_phase_ == nullptr) { - LOG(INFO) << "Unable to record discovery phase duration due to " - "null current_discovery_phase_"; - return; - } - if (!current_discovery_phase_->has_duration_millis()) { - current_discovery_phase_->set_duration_millis(absl::ToInt64Milliseconds( - SystemClock::ElapsedRealtime() - started_discovery_phase_time_)); - } - // If the stop reason haven't been set yet, then set it. - if (!current_discovery_phase_->has_stop_reason()) { - current_discovery_phase_->set_stop_reason( - on_stop ? StopDiscoveringReason::CLIENT_STOP_DISCOVERING - : StopDiscoveringReason::FINISH_SESSION_STOP_DISCOVERING); - } -} - -void AnalyticsRecorderImpl::FinishDiscoveryPhaseLocked() { - if (current_discovery_phase_ != nullptr) { - for (const auto& item : outgoing_connection_requests_) { - // ConnectionRequests still pending have been ignored by the local or - // remote (or both) endpoints. - const std::unique_ptr& - connection_request = item.second; - MarkConnectionRequestIgnoredLocked(connection_request.get()); - UpdateDiscovererConnectionRequestLocked(connection_request.get()); - } - RecordDiscoveryPhaseDurationAndReasonLocked(/* on_stop=*/false); - if (current_strategy_session_ != nullptr) { - *current_strategy_session_->add_discovery_phase() = - *std::move(current_discovery_phase_); - } else { - LOG(INFO) << "Unable to record discovery phase due to null " - "current_strategy_session_"; - } - } - outgoing_connection_requests_.clear(); -} - -bool AnalyticsRecorderImpl::UpdateAdvertiserConnectionRequestLocked( - ConnectionsLog::ConnectionRequest* request) { - if (current_advertising_phase_ == nullptr) { - LOG(INFO) << "Unable to record advertiser connection request due to null " - "current_advertising_phase_"; - return false; - } - if (BothEndpointsRespondedLocked(request)) { - request->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - - request->duration_millis()); - *current_advertising_phase_->add_received_connection_request() = *request; - return true; - } - return false; -} - -bool AnalyticsRecorderImpl::UpdateDiscovererConnectionRequestLocked( - ConnectionsLog::ConnectionRequest* request) { - if (current_discovery_phase_ == nullptr) { - LOG(INFO) << "Unable to record discoverer connection request due " - "to null current_discovery_phase_."; - return false; - } - if (BothEndpointsRespondedLocked(request) || - request->local_response() == NOT_SENT) { - request->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - - request->duration_millis()); - *current_discovery_phase_->add_sent_connection_request() = *request; - return true; - } - return false; -} - -bool AnalyticsRecorderImpl::BothEndpointsRespondedLocked( - ConnectionsLog::ConnectionRequest* request) { - return request->has_local_response() && request->has_remote_response(); -} - -void AnalyticsRecorderImpl::LocalEndpointRespondedLocked( - const std::string& remote_endpoint_id, ConnectionRequestResponse response) { - auto out = outgoing_connection_requests_.find(remote_endpoint_id); - if (out != outgoing_connection_requests_.end()) { - ConnectionsLog::ConnectionRequest* connection_request = out->second.get(); - connection_request->set_local_response(response); - if (UpdateDiscovererConnectionRequestLocked(connection_request)) { - outgoing_connection_requests_.erase(out); - } - } - auto in = incoming_connection_requests_.find(remote_endpoint_id); - if (in != incoming_connection_requests_.end()) { - ConnectionsLog::ConnectionRequest* connection_request = in->second.get(); - connection_request->set_local_response(response); - if (UpdateAdvertiserConnectionRequestLocked(connection_request)) { - incoming_connection_requests_.erase(in); - } - } -} - -void AnalyticsRecorderImpl::RemoteEndpointRespondedLocked( - const std::string& remote_endpoint_id, ConnectionRequestResponse response) { - auto out = outgoing_connection_requests_.find(remote_endpoint_id); - if (out != outgoing_connection_requests_.end()) { - ConnectionsLog::ConnectionRequest* connection_request = out->second.get(); - connection_request->set_remote_response(response); - if (UpdateDiscovererConnectionRequestLocked(connection_request)) { - outgoing_connection_requests_.erase(out); - } - } - auto in = incoming_connection_requests_.find(remote_endpoint_id); - if (in != incoming_connection_requests_.end()) { - ConnectionsLog::ConnectionRequest* connection_request = in->second.get(); - connection_request->set_remote_response(response); - if (UpdateAdvertiserConnectionRequestLocked(connection_request)) { - incoming_connection_requests_.erase(in); - } - } -} - -void AnalyticsRecorderImpl::MarkConnectionRequestIgnoredLocked( - ConnectionsLog::ConnectionRequest* request) { - if (!request->has_local_response()) { - request->set_local_response(IGNORED); - } - if (!request->has_remote_response()) { - request->set_remote_response(IGNORED); - } -} - -bool AnalyticsRecorderImpl::ConnectionAttemptResultCodeExistedLocked( - Medium medium, ConnectionAttemptDirection direction, - const std::string& connection_token, ConnectionAttemptType type, - OperationResultCode operation_result_code) { - if (current_strategy_session_ == nullptr || - current_strategy_session_->connection_attempt_size() == 0) { - return false; - } - for (auto& connection_attempt : - current_strategy_session_->connection_attempt()) { - if (connection_attempt.medium() == medium && - connection_attempt.direction() == direction && - connection_attempt.connection_token() == connection_token && - connection_attempt.type() == type && - connection_attempt.operation_result().result_code() == - operation_result_code) { - return true; - } - } - - return false; -} - -// If bandwidth upgrade always failed on the same fromMedium, toMedium, result, -// stage and result code, we'll drop the duplicate logs for preventing the waste -// of log storage space -bool AnalyticsRecorderImpl::EraseIfBandwidthUpgradeRecordExistedLocked( - const std::string& endpoint_id, BandwidthUpgradeResult result, - BandwidthUpgradeErrorStage error_stage, - OperationResultCode operation_result_code) { - if (current_strategy_session_ == nullptr) { - return false; - } - auto it = bandwidth_upgrade_attempts_.find(endpoint_id); - if (it != bandwidth_upgrade_attempts_.end()) { - ConnectionsLog::BandwidthUpgradeAttempt* attempt = it->second.get(); - for (auto& existing_attempt : - current_strategy_session_->upgrade_attempt()) { - if (attempt->from_medium() == existing_attempt.from_medium() && - attempt->to_medium() == existing_attempt.to_medium() && - result == existing_attempt.upgrade_result() && - error_stage == existing_attempt.error_stage() && - operation_result_code == - existing_attempt.operation_result().result_code()) { - bandwidth_upgrade_attempts_.erase(it); - return true; - } - } - } - return false; -} - -void AnalyticsRecorderImpl::FinishUpgradeAttemptLocked( - const std::string& endpoint_id, BandwidthUpgradeResult result, - BandwidthUpgradeErrorStage error_stage, - OperationResultCode operation_result_code, bool erase_item) { - if (current_strategy_session_ == nullptr) { - LOG(INFO) << "Unable to record upgrade attempt due to null " - "current_strategy_session_"; - return; - } - // Add the BandwidthUpgradeAttempt in the current StrategySession. - auto it = bandwidth_upgrade_attempts_.find(endpoint_id); - if (it != bandwidth_upgrade_attempts_.end()) { - ConnectionsLog::BandwidthUpgradeAttempt* attempt = it->second.get(); - attempt->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - - attempt->duration_millis()); - attempt->set_error_stage(error_stage); - attempt->set_upgrade_result(result); - - auto operation_result_proto = - std::make_unique(); - operation_result_proto->set_result_code(operation_result_code); - operation_result_proto->set_result_category( - ConvertToOperationResultCategory(operation_result_code)); - attempt->set_allocated_operation_result(operation_result_proto.release()); - *current_strategy_session_->add_upgrade_attempt() = *attempt; - if (erase_item) { - bandwidth_upgrade_attempts_.erase(it); - } - } -} - -void AnalyticsRecorderImpl::FinishStrategySessionLocked() { - if (current_strategy_session_ != nullptr) { - FinishAdvertisingPhaseLocked(); - FinishDiscoveryPhaseLocked(); - - // Finish any unfinished LogicalConnections. - for (const auto& item : active_connections_) { - const std::unique_ptr& logical_connection = - item.second; - logical_connection->CloseAllPhysicalConnections(); - absl::c_copy( - logical_connection->GetEstablisedConnections(), - RepeatedFieldBackInserter( - current_strategy_session_->mutable_established_connection())); - } - active_connections_.clear(); - - // Finish any pending upgrade attempts. - for (const auto& item : bandwidth_upgrade_attempts_) { - FinishUpgradeAttemptLocked( - item.first, UNFINISHED_ERROR, UPGRADE_UNFINISHED, - OperationResultCode::DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS, - /*erase_item=*/false); - } - bandwidth_upgrade_attempts_.clear(); - - // Add the StrategySession in ClientSession - if (current_strategy_session_ != nullptr) { - current_strategy_session_->set_duration_millis(absl::ToInt64Milliseconds( - SystemClock::ElapsedRealtime() - started_strategy_session_time_)); - *client_session_->add_strategy_session() = - *std::move(current_strategy_session_); - } - - current_strategy_session_ = nullptr; - current_strategy_ = connections::Strategy::kNone; - LogEvent(STOP_STRATEGY_SESSION); - } -} - -ConnectionsStrategy AnalyticsRecorderImpl::StrategyToConnectionStrategy( - connections::Strategy strategy) { - if (strategy == connections::Strategy::kP2pCluster) { - return P2P_CLUSTER; - } - if (strategy == connections::Strategy::kP2pStar) { - return P2P_STAR; - } - if (strategy == connections::Strategy::kP2pPointToPoint) { - return P2P_POINT_TO_POINT; - } - return UNKNOWN_STRATEGY; -} - -PayloadType AnalyticsRecorderImpl::PayloadTypeToProtoPayloadType( - connections::PayloadType type) { - switch (type) { - case connections::PayloadType::kBytes: - return BYTES; - case connections::PayloadType::kFile: - return FILE; - case connections::PayloadType::kStream: - return STREAM; - default: - return UNKNOWN_PAYLOAD_TYPE; - } -} - -void AnalyticsRecorderImpl::PendingPayload::AddChunk( - std::int64_t chunk_size_bytes) { - num_bytes_transferred_ += chunk_size_bytes; - num_chunks_++; -} - -ConnectionsLog::Payload AnalyticsRecorderImpl::PendingPayload::GetProtoPayload( - PayloadStatus status) { - ConnectionsLog::Payload payload; - payload.set_duration_millis( - absl::ToInt64Milliseconds(SystemClock::ElapsedRealtime() - start_time_)); - payload.set_type(type_); - payload.set_total_size_bytes(total_size_bytes_); - payload.set_num_bytes_transferred(num_bytes_transferred_); - payload.set_num_chunks(num_chunks_); - payload.set_status(status); - - auto operation_result_proto = - std::make_unique(); - operation_result_proto->set_result_code(operation_result_code_); - operation_result_proto->set_result_category( - ConvertToOperationResultCategory(operation_result_code_)); - payload.set_allocated_operation_result(operation_result_proto.release()); - - return payload; -} - -void AnalyticsRecorderImpl::LogicalConnection::PhysicalConnectionEstablished( - Medium medium, const std::string& connection_token) { - if (current_medium_ != UNKNOWN_MEDIUM) { - LOG(WARNING) << "Unexpected call to PhysicalConnectionEstablished while " - "AnalyticsRecorderImpl still has an active current medium."; - } - - auto established_connection = - std::make_unique(); - established_connection->set_medium(medium); - established_connection->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime())); - established_connection->set_connection_token(connection_token); - - auto operation_result_proto = - std::make_unique(); - operation_result_proto->set_result_code(OperationResultCode::DETAIL_SUCCESS); - operation_result_proto->set_result_category( - OperationResultCategory::CATEGORY_SUCCESS); - established_connection->set_allocated_operation_result( - operation_result_proto.release()); - physical_connections_.insert({medium, std::move(established_connection)}); - current_medium_ = medium; -} - -void AnalyticsRecorderImpl::LogicalConnection::PhysicalConnectionClosed( - Medium medium, DisconnectionReason reason, SafeDisconnectionResult result) { - if (current_medium_ == UNKNOWN_MEDIUM) { - LOG(WARNING) << "Unexpected call to PhysicalConnectionClosed() for medium " - << Medium_Name(medium) - << " while AnalyticsRecorderImpl has no active current medium"; - } else if (current_medium_ != medium) { - LOG(WARNING) << "Unexpected call to PhysicalConnectionClosed() for medium " - << Medium_Name(medium) - << "while AnalyticsRecorderImpl has active medium " - << Medium_Name(current_medium_); - } - - auto it = physical_connections_.find(medium); - if (it == physical_connections_.end()) { - LOG(WARNING) - << "Unexpected call to physicalConnectionClosed() for medium " - << Medium_Name(medium) - << " with no corresponding EstablishedConnection that was previously" - " opened."; - return; - } - ConnectionsLog::EstablishedConnection* established_connection = - it->second.get(); - if (established_connection->has_disconnection_reason()) { - LOG(WARNING) << "Unexpected call to physicalConnectionClosed() for medium " - << Medium_Name(medium) - << " which already has disconnection reason " - << DisconnectionReason_Name( - established_connection->disconnection_reason()); - return; - } - FinishPhysicalConnection(established_connection, reason, result); - - if (medium == current_medium_) { - // If the EstablishedConnection we just closed was the one that we have - // marked as current, unset currentMedium. - current_medium_ = UNKNOWN_MEDIUM; - } -} - -void AnalyticsRecorderImpl::LogicalConnection::CloseAllPhysicalConnections() { - for (const auto& physical_connection : physical_connections_) { - ConnectionsLog::EstablishedConnection* established_connection = - physical_connection.second.get(); - if (!established_connection->has_disconnection_reason()) { - FinishPhysicalConnection(established_connection, UNFINISHED, - SafeDisconnectionResult::kSafeDisconnection); - } - } - current_medium_ = UNKNOWN_MEDIUM; -} - -std::vector -AnalyticsRecorderImpl::LogicalConnection::GetEstablisedConnections() { - std::vector established_connections; - if (current_medium_ != UNKNOWN_MEDIUM) { - LOG(WARNING) - << "AnalyticsRecorderImpl expected no more active physical connections " - "before logging this endpoint connection."; - return established_connections; - } - std::transform(physical_connections_.begin(), physical_connections_.end(), - std::back_inserter(established_connections), - [](auto& kv) { return *kv.second; }); - physical_connections_.clear(); - - for (auto& established_connection : established_connections) { - if (absl::Milliseconds(established_connection.duration_millis()) >= - kConnectionTokenMaxLife) { - LOG(INFO) << "connection token exceed TTL, drop token."; - established_connection.set_connection_token(""); - } - } - - return established_connections; -} - -void AnalyticsRecorderImpl::LogicalConnection::IncomingPayloadStarted( - std::int64_t payload_id, PayloadType type, std::int64_t total_size_bytes) { - incoming_payloads_.insert( - {payload_id, std::make_unique(type, total_size_bytes)}); -} - -void AnalyticsRecorderImpl::LogicalConnection::ChunkReceived( - std::int64_t payload_id, std::int64_t size_bytes) { - auto it = incoming_payloads_.find(payload_id); - if (it == incoming_payloads_.end()) { - return; - } - PendingPayload* pending_payload = it->second.get(); - pending_payload->AddChunk(size_bytes); -} - -void AnalyticsRecorderImpl::LogicalConnection::IncomingPayloadDone( - std::int64_t payload_id, PayloadStatus status, - OperationResultCode operation_result_code) { - if (current_medium_ == UNKNOWN_MEDIUM) { - LOG(WARNING) << "Unexpected call to incomingPayloadDone() while " - "AnalyticsRecorderImpl has no active current medium."; - return; - } - auto it = physical_connections_.find(current_medium_); - if (it != physical_connections_.end()) { - const std::unique_ptr& - established_connection = it->second; - auto it = incoming_payloads_.find(payload_id); - if (it != incoming_payloads_.end()) { - it->second->SetOperationResultCode(operation_result_code); - *established_connection->add_received_payload() = - it->second->GetProtoPayload(status); - incoming_payloads_.erase(it); - } - } -} - -void AnalyticsRecorderImpl::LogicalConnection::OutgoingPayloadStarted( - std::int64_t payload_id, PayloadType type, std::int64_t total_size_bytes) { - outgoing_payloads_.insert( - {payload_id, std::make_unique(type, total_size_bytes)}); -} - -void AnalyticsRecorderImpl::LogicalConnection::ChunkSent( - std::int64_t payload_id, std::int64_t size_bytes) { - auto it = outgoing_payloads_.find(payload_id); - if (it == outgoing_payloads_.end()) { - return; - } - PendingPayload* payload = it->second.get(); - payload->AddChunk(size_bytes); -} - -void AnalyticsRecorderImpl::LogicalConnection::OutgoingPayloadDone( - std::int64_t payload_id, PayloadStatus status, - OperationResultCode operation_result_code) { - if (current_medium_ == UNKNOWN_MEDIUM) { - LOG(WARNING) << "Unexpected call to outgoingPayloadDone() while " - "AnalyticsRecorderImpl has no active current medium."; - return; - } - auto it = physical_connections_.find(current_medium_); - if (it != physical_connections_.end()) { - const std::unique_ptr& - established_connection = it->second; - auto it = outgoing_payloads_.find(payload_id); - if (it != outgoing_payloads_.end()) { - it->second->SetOperationResultCode(operation_result_code); - *established_connection->add_sent_payload() = - it->second->GetProtoPayload(status); - outgoing_payloads_.erase(it); - } - } -} - -void AnalyticsRecorderImpl::LogicalConnection::FinishPhysicalConnection( - ConnectionsLog::EstablishedConnection* established_connection, - DisconnectionReason reason, SafeDisconnectionResult result) { - established_connection->set_disconnection_reason(reason); - established_connection->set_safe_disconnection_result( - ConvertToProtoSafeDisconnectionResult(result)); - established_connection->set_duration_millis( - absl::ToUnixMillis(SystemClock::ElapsedRealtime()) - - established_connection->duration_millis()); - - // Add any not-yet-finished payloads to this EstablishedConnection. - std::vector in_payloads = - ResolvePendingPayloads(incoming_payloads_, reason); - absl::c_move(in_payloads, - RepeatedFieldBackInserter( - established_connection->mutable_received_payload())); - std::vector out_payloads = - ResolvePendingPayloads(outgoing_payloads_, reason); - absl::c_move(out_payloads, - RepeatedFieldBackInserter( - established_connection->mutable_sent_payload())); -} - -std::vector -AnalyticsRecorderImpl::LogicalConnection::ResolvePendingPayloads( - absl::btree_map>& - pending_payloads, - DisconnectionReason reason) { - std::vector completed_payloads; - absl::btree_map> - upgraded_payloads; - PayloadStatus status = - reason == UPGRADED ? MOVED_TO_NEW_MEDIUM : CONNECTION_CLOSED; - - OperationResultCode operation_result_code = - GetPendingPayloadResultCodeFromReason(reason); - for (const auto& item : pending_payloads) { - const std::unique_ptr& pending_payload = item.second; - pending_payload->SetOperationResultCode(operation_result_code); - ConnectionsLog::Payload proto_payload = - pending_payload->GetProtoPayload(status); - completed_payloads.push_back(proto_payload); - if (reason == UPGRADED) { - upgraded_payloads.insert( - {item.first, - std::make_unique(pending_payload->type(), - pending_payload->total_size_bytes(), - operation_result_code)}); - } - } - pending_payloads.clear(); - - if (reason == UPGRADED) { - // Re-populate the map with a new PendingPayload for each pending payload, - // since we expect them to be completed on the next EstablishedConnection. - pending_payloads = std::move(upgraded_payloads); - } - // Return the list of completed payloads to be added to the current - // EstablishedConnection. - return completed_payloads; -} - -OperationResultCode -AnalyticsRecorderImpl::LogicalConnection::GetPendingPayloadResultCodeFromReason( - DisconnectionReason reason) { - switch (reason) { - case UPGRADED: - return OperationResultCode::MISCELLEANEOUS_MOVE_TO_NEW_MEDIUM; - case DisconnectionReason::LOCAL_DISCONNECTION: - return OperationResultCode::CLIENT_CANCELLATION_LOCAL_DISCONNECT; - case DisconnectionReason::REMOTE_DISCONNECTION: - return OperationResultCode::CLIENT_CANCELLATION_REMOTE_DISCONNECT; - default: - return OperationResultCode::NEARBY_GENERIC_CONNECTION_CLOSED; - } -} - -OperationResultCategory AnalyticsRecorderImpl::GetOperationResultCategory( - location::nearby::proto::connections::OperationResultCode result_code) { - return ConvertToOperationResultCategory(result_code); -} - -void AnalyticsRecorderImpl::Sync() { MutexLock lock(&mutex_); } - -} // namespace nearby::analytics diff --git a/connections/implementation/analytics/analytics_recorder_impl.h b/connections/implementation/analytics/analytics_recorder_impl.h deleted file mode 100644 index dfe0a342..00000000 --- a/connections/implementation/analytics/analytics_recorder_impl.h +++ /dev/null @@ -1,459 +0,0 @@ -// Copyright 2022-2023 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 ANALYTICS_ANALYTICS_RECORDER_IMPL_H_ -#define ANALYTICS_ANALYTICS_RECORDER_IMPL_H_ - -#include -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/container/btree_map.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "connections/implementation/analytics/advertising_metadata_params.h" -#include "connections/implementation/analytics/analytics_recorder.h" -#include "connections/implementation/analytics/connection_attempt_metadata_params.h" -#include "connections/implementation/analytics/discovery_metadata_params.h" -#include "connections/payload_type.h" -#include "connections/strategy.h" -#include "internal/analytics/event_logger.h" -#include "internal/platform/error_code_params.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/mutex.h" -#include "internal/proto/analytics/connections_log.pb.h" -#include "proto/connections_enums.pb.h" - -namespace nearby::analytics { - -class AnalyticsRecorderImpl : public AnalyticsRecorder { - public: - explicit AnalyticsRecorderImpl( - ::nearby::analytics::EventLogger* event_logger); - ~AnalyticsRecorderImpl() override; - - // Advertising phase - void OnStartAdvertising( - connections::Strategy strategy, - const std::vector& mediums, - AdvertisingMetadataParams* advertising_metadata_params) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnStopAdvertising() override ABSL_LOCKS_EXCLUDED(mutex_); - - int GetNextAdvertisingUpdateIndex() override ABSL_LOCKS_EXCLUDED(mutex_); - - // Connection listening - void OnStartedIncomingConnectionListening( - connections::Strategy strategy) override ABSL_LOCKS_EXCLUDED(mutex_); - void OnStoppedIncomingConnectionListening() override - ABSL_LOCKS_EXCLUDED(mutex_); - - // Discovery phase - void OnStartDiscovery( - connections::Strategy strategy, - const std::vector& mediums, - DiscoveryMetadataParams* discovery_metadata_params) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnStopDiscovery() override ABSL_LOCKS_EXCLUDED(mutex_); - - int GetNextDiscoveryUpdateIndex() override ABSL_LOCKS_EXCLUDED(mutex_); - void OnEndpointFound(location::nearby::proto::connections::Medium medium) - override ABSL_LOCKS_EXCLUDED(mutex_); - - // Connection request - void OnRequestConnection(const connections::Strategy& strategy, - const std::string& endpoint_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - - void OnConnectionRequestReceived(const std::string& remote_endpoint_id) - override ABSL_LOCKS_EXCLUDED(mutex_); - void OnConnectionRequestSent(const std::string& remote_endpoint_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnRemoteEndpointAccepted(const std::string& remote_endpoint_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnLocalEndpointAccepted(const std::string& remote_endpoint_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnRemoteEndpointRejected(const std::string& remote_endpoint_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnLocalEndpointRejected(const std::string& remote_endpoint_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - - // Connection attempt - void OnIncomingConnectionAttempt( - location::nearby::proto::connections::ConnectionAttemptType type, - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::ConnectionAttemptResult result, - absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) - override ABSL_LOCKS_EXCLUDED(mutex_); - void OnOutgoingConnectionAttempt( - const std::string& remote_endpoint_id, - location::nearby::proto::connections::ConnectionAttemptType type, - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::ConnectionAttemptResult result, - absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) - override ABSL_LOCKS_EXCLUDED(mutex_); - - // Connection established - void OnConnectionEstablished( - const std::string& endpoint_id, - location::nearby::proto::connections::Medium medium, - const std::string& connection_token) override ABSL_LOCKS_EXCLUDED(mutex_); - void OnConnectionClosed( - const std::string& endpoint_id, - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::DisconnectionReason reason, - SafeDisconnectionResult result) override ABSL_LOCKS_EXCLUDED(mutex_); - - // Payload - void OnIncomingPayloadStarted(const std::string& endpoint_id, - std::int64_t payload_id, - connections::PayloadType type, - std::int64_t total_size_bytes) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnPayloadChunkReceived(const std::string& endpoint_id, - std::int64_t payload_id, - std::int64_t chunk_size_bytes) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnIncomingPayloadDone( - const std::string& endpoint_id, std::int64_t payload_id, - location::nearby::proto::connections::PayloadStatus status, - location::nearby::proto::connections::OperationResultCode - operation_result_code) override ABSL_LOCKS_EXCLUDED(mutex_); - void OnOutgoingPayloadStarted(const std::vector& endpoint_ids, - std::int64_t payload_id, - connections::PayloadType type, - std::int64_t total_size_bytes) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnPayloadChunkSent(const std::string& endpoint_id, - std::int64_t payload_id, - std::int64_t chunk_size_bytes) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnOutgoingPayloadDone( - const std::string& endpoint_id, std::int64_t payload_id, - location::nearby::proto::connections::PayloadStatus status, - location::nearby::proto::connections::OperationResultCode - operation_result_code) override ABSL_LOCKS_EXCLUDED(mutex_); - - // BandwidthUpgrade - void OnBandwidthUpgradeStarted( - const std::string& endpoint_id, - location::nearby::proto::connections::Medium from_medium, - location::nearby::proto::connections::Medium to_medium, - location::nearby::proto::connections::ConnectionAttemptDirection - direction, - const std::string& connection_token) override ABSL_LOCKS_EXCLUDED(mutex_); - void UpdateBwUpgradeNetworkInfo(const std::string& endpoint_id, - int num_interfaces, - int num_ipv6_only_interfaces) override - ABSL_LOCKS_EXCLUDED(mutex_); - void OnBandwidthUpgradeError( - const std::string& endpoint_id, - location::nearby::proto::connections::BandwidthUpgradeResult result, - location::nearby::proto::connections::BandwidthUpgradeErrorStage - error_stage, - location::nearby::proto::connections::OperationResultCode - operation_result_code) override ABSL_LOCKS_EXCLUDED(mutex_); - void OnBandwidthUpgradeSuccess(const std::string& endpoint_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - - // Error Code - void OnErrorCode(const ErrorCodeParams& params) override; - - void LogStartSession() override ABSL_LOCKS_EXCLUDED(mutex_); - void LogSession() override ABSL_LOCKS_EXCLUDED(mutex_); - - bool IsSessionLogged() override; - - location::nearby::proto::connections::OperationResultCategory - GetOperationResultCategory( - location::nearby::proto::connections::OperationResultCode result_code) - override; - - void Sync() override; - - private: - // Tracks the chunks and duration of a Payload on a particular medium. - class PendingPayload { - public: - PendingPayload(location::nearby::proto::connections::PayloadType type, - std::int64_t total_size_bytes) - : PendingPayload(type, total_size_bytes, - location::nearby::proto::connections:: - OperationResultCode::DETAIL_UNKNOWN) {} - PendingPayload(location::nearby::proto::connections::PayloadType type, - std::int64_t total_size_bytes, - location::nearby::proto::connections::OperationResultCode - operation_result_code) - : start_time_(SystemClock::ElapsedRealtime()), - type_(type), - total_size_bytes_(total_size_bytes), - num_bytes_transferred_(0), - num_chunks_(0), - operation_result_code_(operation_result_code) {} - ~PendingPayload() = default; - - void AddChunk(std::int64_t chunk_size_bytes); - - location::nearby::analytics::proto::ConnectionsLog::Payload GetProtoPayload( - location::nearby::proto::connections::PayloadStatus status); - - location::nearby::proto::connections::PayloadType type() const { - return type_; - } - - std::int64_t total_size_bytes() const { return total_size_bytes_; } - - void SetOperationResultCode( - location::nearby::proto::connections::OperationResultCode - operation_result_code) { - operation_result_code_ = operation_result_code; - } - - private: - absl::Time start_time_; - location::nearby::proto::connections::PayloadType type_; - std::int64_t total_size_bytes_; - std::int64_t num_bytes_transferred_; - int num_chunks_; - location::nearby::proto::connections::OperationResultCode - operation_result_code_ = location::nearby::proto::connections:: - OperationResultCode::DETAIL_UNKNOWN; - }; - - class LogicalConnection { - public: - LogicalConnection( - location::nearby::proto::connections::Medium initial_medium, - const std::string& connection_token) { - PhysicalConnectionEstablished(initial_medium, connection_token); - } - LogicalConnection(const LogicalConnection&) = delete; - LogicalConnection(LogicalConnection&& other) - : current_medium_(std::move(other.current_medium_)), - physical_connections_(std::move(other.physical_connections_)), - incoming_payloads_(std::move(other.incoming_payloads_)), - outgoing_payloads_(std::move(other.outgoing_payloads_)) {} - LogicalConnection& operator=(const LogicalConnection&) = delete; - LogicalConnection&& operator=(LogicalConnection&&) = delete; - ~LogicalConnection() = default; - - void PhysicalConnectionEstablished( - location::nearby::proto::connections::Medium medium, - const std::string& connection_token); - void PhysicalConnectionClosed( - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::DisconnectionReason reason, - SafeDisconnectionResult result); - void CloseAllPhysicalConnections(); - - void IncomingPayloadStarted( - std::int64_t payload_id, - location::nearby::proto::connections::PayloadType type, - std::int64_t total_size_bytes); - void ChunkReceived(std::int64_t payload_id, std::int64_t size_bytes); - void IncomingPayloadDone( - std::int64_t payload_id, - location::nearby::proto::connections::PayloadStatus status, - location::nearby::proto::connections::OperationResultCode - operation_result_code); - void OutgoingPayloadStarted( - std::int64_t payload_id, - location::nearby::proto::connections::PayloadType type, - std::int64_t total_size_bytes); - void ChunkSent(std::int64_t payload_id, std::int64_t size_bytes); - void OutgoingPayloadDone( - std::int64_t payload_id, - location::nearby::proto::connections::PayloadStatus status, - location::nearby::proto::connections::OperationResultCode - operation_result_code); - - std::vector - GetEstablisedConnections(); - - private: - void FinishPhysicalConnection( - location::nearby::analytics::proto::ConnectionsLog:: - EstablishedConnection* established_connection, - location::nearby::proto::connections::DisconnectionReason reason, - SafeDisconnectionResult result); - std::vector - ResolvePendingPayloads( - absl::btree_map>& - pending_payloads, - location::nearby::proto::connections::DisconnectionReason reason); - location::nearby::proto::connections::OperationResultCode - GetPendingPayloadResultCodeFromReason( - location::nearby::proto::connections::DisconnectionReason reason); - - location::nearby::proto::connections::Medium current_medium_ = - location::nearby::proto::connections::UNKNOWN_MEDIUM; - absl::btree_map> - physical_connections_; - absl::btree_map> - incoming_payloads_; - absl::btree_map> - outgoing_payloads_; - }; - - bool CanRecordAnalyticsLocked(absl::string_view method_name) - ABSL_SHARED_LOCKS_REQUIRED(mutex_); - - // Callbacks the ConnectionsLog proto byte array data to the EventLogger with - // ClientSession sub-proto. - void LogClientSessionLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - // Callbacks the ConnectionsLog proto byte array data to the EventLogger. - void LogEvent(location::nearby::proto::connections::EventType event_type); - - void UpdateStrategySessionLocked( - connections::Strategy strategy, - location::nearby::proto::connections::SessionRole role) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - void RecordAdvertisingPhaseDurationAndReasonLocked(bool on_stop) const - ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void FinishAdvertisingPhaseLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - void RecordDiscoveryPhaseDurationAndReasonLocked(bool on_stop) const - ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void FinishDiscoveryPhaseLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - bool UpdateAdvertiserConnectionRequestLocked( - location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* - request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - bool UpdateDiscovererConnectionRequestLocked( - location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* - request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - bool BothEndpointsRespondedLocked( - location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* - request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void LocalEndpointRespondedLocked( - const std::string& remote_endpoint_id, - location::nearby::proto::connections::ConnectionRequestResponse response) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - void RemoteEndpointRespondedLocked( - const std::string& remote_endpoint_id, - location::nearby::proto::connections::ConnectionRequestResponse response) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - void MarkConnectionRequestIgnoredLocked( - location::nearby::analytics::proto::ConnectionsLog::ConnectionRequest* - request) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void OnIncomingConnectionAttemptLocked( - location::nearby::proto::connections::ConnectionAttemptType type, - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::ConnectionAttemptResult result, - absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) - ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void OnOutgoingConnectionAttemptLocked( - const std::string& remote_endpoint_id, - location::nearby::proto::connections::ConnectionAttemptType type, - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::ConnectionAttemptResult result, - absl::Duration duration, const std::string& connection_token, - ConnectionAttemptMetadataParams* connection_attempt_metadata_params) - ABSL_SHARED_LOCKS_REQUIRED(mutex_); - bool ConnectionAttemptResultCodeExistedLocked( - location::nearby::proto::connections::Medium medium, - location::nearby::proto::connections::ConnectionAttemptDirection - direction, - const std::string& connection_token, - location::nearby::proto::connections::ConnectionAttemptType type, - location::nearby::proto::connections::OperationResultCode - operation_result_code) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - bool EraseIfBandwidthUpgradeRecordExistedLocked( - const std::string& endpoint_id, - location::nearby::proto::connections::BandwidthUpgradeResult result, - location::nearby::proto::connections::BandwidthUpgradeErrorStage - error_stage, - location::nearby::proto::connections::OperationResultCode - operation_result_code) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void FinishUpgradeAttemptLocked( - const std::string& endpoint_id, - location::nearby::proto::connections::BandwidthUpgradeResult result, - location::nearby::proto::connections::BandwidthUpgradeErrorStage - error_stage, - location::nearby::proto::connections::OperationResultCode - operation_result_code, - bool erase_item = true) ABSL_SHARED_LOCKS_REQUIRED(mutex_); - void FinishStrategySessionLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - int GetLatestUpdateIndexLocked( - const std::vector& list) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - location::nearby::proto::connections::ConnectionsStrategy - StrategyToConnectionStrategy(connections::Strategy strategy); - location::nearby::proto::connections::PayloadType - PayloadTypeToProtoPayloadType(connections::PayloadType type); - - // Not owned by AnalyticsRecorderImpl. Pointer must refer to a valid object - // that outlives the one constructed. - ::nearby::analytics::EventLogger* event_logger_; - - // Protects all sub-protos reading and writing in ConnectionLog. - Mutex mutex_; - - // ClientSession - std::unique_ptr< - location::nearby::analytics::proto::ConnectionsLog::ClientSession> - client_session_; - absl::Time started_client_session_time_; - bool session_was_logged_ ABSL_GUARDED_BY(mutex_) = false; - bool start_client_session_was_logged_ ABSL_GUARDED_BY(mutex_) = false; - - // Current StrategySession - connections::Strategy current_strategy_ ABSL_GUARDED_BY(mutex_) = - connections::Strategy::kNone; - std::unique_ptr< - location::nearby::analytics::proto::ConnectionsLog::StrategySession> - current_strategy_session_ ABSL_GUARDED_BY(mutex_); - absl::Time started_strategy_session_time_ ABSL_GUARDED_BY(mutex_); - - // Current AdvertisingPhase - std::unique_ptr< - location::nearby::analytics::proto::ConnectionsLog::AdvertisingPhase> - current_advertising_phase_; - absl::Time started_advertising_phase_time_ = absl::InfinitePast(); - - // Current DiscoveryPhase - std::unique_ptr< - location::nearby::analytics::proto::ConnectionsLog::DiscoveryPhase> - current_discovery_phase_; - absl::Time started_discovery_phase_time_ = absl::InfinitePast(); - - absl::btree_map> - incoming_connection_requests_ ABSL_GUARDED_BY(mutex_); - absl::btree_map> - outgoing_connection_requests_ ABSL_GUARDED_BY(mutex_); - absl::btree_map> - active_connections_ ABSL_GUARDED_BY(mutex_); - absl::btree_map> - bandwidth_upgrade_attempts_ ABSL_GUARDED_BY(mutex_); -}; - -} // namespace nearby::analytics - -#endif // ANALYTICS_ANALYTICS_RECORDER_IMPL_H_ diff --git a/connections/implementation/analytics/analytics_recorder_impl_test.cc b/connections/implementation/analytics/analytics_recorder_impl_test.cc deleted file mode 100644 index 53bf6afe..00000000 --- a/connections/implementation/analytics/analytics_recorder_impl_test.cc +++ /dev/null @@ -1,2579 +0,0 @@ -// Copyright 2022-2023 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. - -#include "connections/implementation/analytics/analytics_recorder_impl.h" - -#include - -#include -#include -#include -#include - -#include "net/proto2/contrib/parse_proto/parse_text_proto.h" -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/time/time.h" -#include "connections/implementation/analytics/analytics_recorder.h" -#include "connections/implementation/analytics/connection_attempt_metadata_params.h" -#include "connections/implementation/analytics/operation_result_with_medium.h" -#include "connections/payload_type.h" -#include "connections/strategy.h" -#include "internal/analytics/mock_event_logger.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/error_code_params.h" -#include "internal/platform/error_code_recorder.h" -#include "internal/platform/exception.h" -#include "internal/platform/medium_environment.h" -#include "internal/proto/analytics/connections_log.proto.h" -#include "proto/connections_enums.proto.h" - -namespace nearby::analytics { -namespace { - -using ::location::nearby::analytics::proto::ConnectionsLog; -using SafeDisconnectionResult = nearby::analytics::SafeDisconnectionResult; -using ::location::nearby::errorcode::proto::DISCONNECT; -using ::location::nearby::errorcode::proto::DISCONNECT_NETWORK_FAILED; -using ::location::nearby::errorcode::proto::INVALID_PARAMETER; -using ::location::nearby::errorcode::proto::NULL_BLUETOOTH_DEVICE_NAME; -using ::location::nearby::errorcode::proto::START_DISCOVERING; -using ::location::nearby::errorcode::proto::START_EXTENDED_DISCOVERING_FAILED; -using ::location::nearby::errorcode::proto:: - TACHYON_SEND_MESSAGE_STATUS_EXCEPTION; -using ::location::nearby::proto::connections::BLE; -using ::location::nearby::proto::connections::BLUETOOTH; -using ::location::nearby::proto::connections::CLIENT_SESSION; -using ::location::nearby::proto::connections::ERROR_CODE; -using ::location::nearby::proto::connections::EventType; -using ::location::nearby::proto::connections::INCOMING; -using ::location::nearby::proto::connections::INITIAL; -using ::location::nearby::proto::connections::LOCAL_DISCONNECTION; -using ::location::nearby::proto::connections::Medium; -using ::location::nearby::proto::connections::OperationResultCategory; -using ::location::nearby::proto::connections::OperationResultCode; -using ::location::nearby::proto::connections::RESULT_ERROR; -using ::location::nearby::proto::connections::RESULT_SUCCESS; -using ::location::nearby::proto::connections::START_CLIENT_SESSION; -using ::location::nearby::proto::connections::START_STRATEGY_SESSION; -using ::location::nearby::proto::connections::STOP_CLIENT_SESSION; -using ::location::nearby::proto::connections::STOP_STRATEGY_SESSION; -using ::location::nearby::proto::connections::SUCCESS; -using ::location::nearby::proto::connections::UPGRADED; -using ::location::nearby::proto::connections::WEB_RTC; -using ::location::nearby::proto::connections::WIFI_LAN; -using ::location::nearby::proto::connections::WIFI_LAN_MEDIUM_ERROR; -using ::location::nearby::proto::connections::WIFI_LAN_SOCKET_CREATION; -using ::nearby::analytics::MockEventLogger; -using ::proto2::contrib::parse_proto::ParseTextProtoOrDie; -using ::testing::Contains; -using ::protobuf_matchers::EqualsProto; -using ::testing::Not; - -constexpr absl::Duration kDefaultTimeout = absl::Milliseconds(1000); - -class FakeEventLogger : public MockEventLogger { - public: - explicit FakeEventLogger(CountDownLatch& client_session_done_latch) - : client_session_done_latch_(client_session_done_latch) {} - - FakeEventLogger(CountDownLatch& client_session_done_latch, - CountDownLatch* start_client_session_done_latch_ptr) - : client_session_done_latch_(client_session_done_latch), - start_client_session_done_latch_ptr_( - start_client_session_done_latch_ptr) {} - - void Log(const ConnectionsLog& message) override { - EventType event_type = message.event_type(); - logged_event_types_.push_back(event_type); - if (event_type == CLIENT_SESSION) { - logged_client_session_count_++; - logged_client_session_ = message.client_session(); - } - if (event_type == ERROR_CODE) { - error_code_ = message.error_code(); - } - if (event_type == STOP_CLIENT_SESSION) { - client_session_done_latch_.CountDown(); - } - if (start_client_session_done_latch_ptr_ != nullptr && - event_type == START_CLIENT_SESSION) { - start_client_session_done_latch_ptr_->CountDown(); - } - } - - int GetLoggedClientSessionCount() const { - return logged_client_session_count_; - } - - const ConnectionsLog::ClientSession& GetLoggedClientSession() { - return logged_client_session_; - } - - const ConnectionsLog::ErrorCode& GetErrorCode() { return error_code_; } - - std::vector GetLoggedEventTypes() { return logged_event_types_; } - - void SetClientSessionDoneLatch( - const CountDownLatch& client_session_done_latch) { - client_session_done_latch_ = client_session_done_latch; - } - - void SetStartClientSessionDoneLatchPtr( - CountDownLatch* start_client_session_done_latch_ptr) { - start_client_session_done_latch_ptr_ = start_client_session_done_latch_ptr; - } - - private: - int logged_client_session_count_ = 0; - CountDownLatch& client_session_done_latch_; - CountDownLatch* start_client_session_done_latch_ptr_ = nullptr; - ConnectionsLog::ClientSession logged_client_session_; - ConnectionsLog::ErrorCode error_code_; - std::vector logged_event_types_; -}; - -class AnalyticsRecorderTest : public ::testing::Test { - protected: - void SetUp() override { - MediumEnvironment::Instance().Start({.use_simulated_clock = true}); - } - - void TearDown() override { MediumEnvironment::Instance().Stop(); } -}; - -// Test if session_was_logged_ is reset by checking if LogSession can take -// effect again or not. -TEST_F(AnalyticsRecorderTest, SessionOnlyLoggedOnceWorks) { - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - analytics_recorder.LogSession(); - analytics_recorder.LogSession(); - analytics_recorder.LogSession(); - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - // Only called once. - EXPECT_EQ(event_logger.GetLoggedClientSessionCount(), 1); -} - -TEST_F(AnalyticsRecorderTest, SetFieldsCorrectlyForNestedAdvertisingCalls) { - connections::Strategy strategy = connections::Strategy::kP2pStar; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - OperationResultWithMedium operation_result; - operation_result.set_medium(BLUETOOTH); - operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); - operation_result.set_result_category( - OperationResultCategory::CATEGORY_SUCCESS); - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - advertising_metadata_params->operation_result_with_mediums = { - operation_result}; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(50)); - analytics_recorder.OnStartAdvertising(strategy, /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStopAdvertising(); - operation_result.set_medium(BLE); - advertising_metadata_params->operation_result_with_mediums = { - operation_result}; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnStartAdvertising(strategy, /*mediums=*/{BLUETOOTH}, - advertising_metadata_params.get()); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 650 - strategy_session { - duration_millis: 600 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 100 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - adv_dis_result { - medium: BLUETOOTH - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - stop_reason: CLIENT_STOP_ADVERTISING - } - advertising_phase { - duration_millis: 300 - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - adv_dis_result { - medium: BLE - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - stop_reason: FINISH_SESSION_STOP_ADVERTISING - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - (EqualsProto(strategy_session_proto))); -} - -TEST_F(AnalyticsRecorderTest, SetFieldsCorrectlyForNestedDiscoveryCalls) { - connections::Strategy strategy = connections::Strategy::kP2pStar; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - OperationResultWithMedium operation_result; - operation_result.set_medium(BLUETOOTH); - operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); - operation_result.set_result_category( - OperationResultCategory::CATEGORY_SUCCESS); - OperationResultWithMedium operation_result2; - operation_result2.set_medium(BLE); - operation_result2.set_result_code(OperationResultCode::DETAIL_SUCCESS); - operation_result2.set_result_category( - OperationResultCategory::CATEGORY_SUCCESS); - - auto discovery_metadata_params = - analytics_recorder.BuildDiscoveryMetadataParams( - /*is_extended_advertisement_supported*/ true, - /*connected_ap_frequency*/ 1, /*is_nfc_available=*/false, - {operation_result, operation_result2}); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartDiscovery(strategy, /*mediums=*/{BLE, BLUETOOTH}, - discovery_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnStopDiscovery(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnEndpointFound(BLUETOOTH); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnEndpointFound(BLE); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - - auto discovery_metadata_params2 = - analytics_recorder.BuildDiscoveryMetadataParams( - /*is_extended_advertisement_supported*/ true, - /*connected_ap_frequency*/ 1, /*is_nfc_available=*/false, - {operation_result}); - analytics_recorder.OnStartDiscovery(strategy, /*mediums=*/{BLUETOOTH}, - discovery_metadata_params2.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 2100 - strategy_session { - duration_millis: 2000 - strategy: P2P_STAR - role: DISCOVERER - discovery_phase { - duration_millis: 200 - medium: BLE - medium: BLUETOOTH - discovered_endpoint { medium: BLUETOOTH latency_millis: 500 } - discovered_endpoint { medium: BLE latency_millis: 900 } - discovery_metadata { - supports_extended_ble_advertisements: true - connected_ap_frequency: 1 - supports_nfc_technology: false - } - adv_dis_result { - medium: BLUETOOTH - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - adv_dis_result { - medium: BLE - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - stop_reason: CLIENT_STOP_DISCOVERING - } - discovery_phase { - duration_millis: 600 - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: true - connected_ap_frequency: 1 - supports_nfc_technology: false - } - adv_dis_result { - medium: BLUETOOTH - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - stop_reason: FINISH_SESSION_STOP_DISCOVERING - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, - OneStrategySessionForMultipleRoundsOfDiscoveryAdvertising) { - connections::Strategy strategy = connections::Strategy::kP2pStar; - std::vector mediums = {BLE, BLUETOOTH}; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(strategy, mediums, - advertising_metadata_params.get()); - auto discovery_metadata_params = - analytics_recorder.BuildDiscoveryMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnStartDiscovery(strategy, mediums, - discovery_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnStopAdvertising(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnStopDiscovery(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.OnStartAdvertising(strategy, mediums, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.OnStopAdvertising(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - analytics_recorder.OnStartDiscovery(strategy, mediums, - discovery_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); - analytics_recorder.OnStopDiscovery(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); - analytics_recorder.OnStartDiscovery(strategy, mediums, {}); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1000)); - analytics_recorder.OnStartAdvertising(strategy, mediums, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1100)); - analytics_recorder.OnStopDiscovery(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1200)); - analytics_recorder.OnStopAdvertising(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1300)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - std::vector event_types = event_logger.GetLoggedEventTypes(); - EXPECT_THAT(event_types, Contains(START_STRATEGY_SESSION).Times(1)); - EXPECT_THAT(event_types, Contains(STOP_STRATEGY_SESSION).Times(1)); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 9100 - strategy_session { - duration_millis: 9000 - strategy: P2P_STAR - role: ADVERTISER - role: DISCOVERER - discovery_phase { - duration_millis: 700 - medium: BLE - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_DISCOVERING - } - discovery_phase { - duration_millis: 800 - medium: BLE - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_DISCOVERING - } - discovery_phase { - duration_millis: 2100 - medium: BLE - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_DISCOVERING - } - advertising_phase { - duration_millis: 500 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_ADVERTISING - } - advertising_phase { - duration_millis: 600 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_ADVERTISING - } - advertising_phase { - duration_millis: 2300 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_ADVERTISING - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, AdvertiserConnectionRequestsWorks) { - std::string endpoint_id_0 = "endpoint_id_0"; - std::string endpoint_id_1 = "endpoint_id_1"; - std::string endpoint_id_2 = "endpoint_id_2"; - std::string endpoint_id_3 = "endpoint_id_3"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - OperationResultWithMedium operation_result; - operation_result.set_medium(BLE); - operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); - operation_result.set_result_category( - OperationResultCategory::CATEGORY_SUCCESS); - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - advertising_metadata_params->operation_result_with_mediums = { - operation_result}; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnConnectionRequestReceived(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnLocalEndpointAccepted(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.OnConnectionRequestReceived(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - analytics_recorder.OnRemoteEndpointRejected(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); - analytics_recorder.OnConnectionRequestReceived(endpoint_id_2); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); - analytics_recorder.OnLocalEndpointRejected(endpoint_id_2); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1000)); - analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_2); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1100)); - analytics_recorder.OnConnectionRequestReceived(endpoint_id_3); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1200)); - analytics_recorder.OnLocalEndpointRejected(endpoint_id_3); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1300)); - analytics_recorder.OnRemoteEndpointRejected(endpoint_id_3); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1400)); - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 10500 - strategy_session { - duration_millis: 10400 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 10400 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - adv_dis_result { - medium: BLE - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - stop_reason: FINISH_SESSION_STOP_ADVERTISING - received_connection_request { - duration_millis: 700 - request_delay_millis: 200 - local_response: ACCEPTED - remote_response: ACCEPTED - } - received_connection_request { - duration_millis: 1300 - request_delay_millis: 1400 - local_response: ACCEPTED - remote_response: REJECTED - } - received_connection_request { - duration_millis: 1900 - request_delay_millis: 3500 - local_response: REJECTED - remote_response: ACCEPTED - } - received_connection_request { - duration_millis: 2500 - request_delay_millis: 6500 - local_response: REJECTED - remote_response: REJECTED - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, DiscoveryConnectionRequestsWorks) { - std::string endpoint_id_0 = "endpoint_id_0"; - std::string endpoint_id_1 = "endpoint_id_1"; - std::string endpoint_id_2 = "endpoint_id_2"; - std::string endpoint_id_3 = "endpoint_id_3"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - OperationResultWithMedium operation_result; - operation_result.set_medium(BLUETOOTH); - operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); - operation_result.set_result_category( - OperationResultCategory::CATEGORY_SUCCESS); - auto discovery_metadata_params = - analytics_recorder.BuildDiscoveryMetadataParams(); - discovery_metadata_params->operation_result_with_mediums = {operation_result}; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - discovery_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnConnectionRequestSent(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnLocalEndpointAccepted(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.OnConnectionRequestSent(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - analytics_recorder.OnRemoteEndpointRejected(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); - analytics_recorder.OnConnectionRequestSent(endpoint_id_2); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); - analytics_recorder.OnLocalEndpointRejected(endpoint_id_2); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1000)); - analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_2); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1100)); - - analytics_recorder.OnConnectionRequestSent(endpoint_id_3); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1200)); - analytics_recorder.OnLocalEndpointRejected(endpoint_id_3); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1300)); - analytics_recorder.OnRemoteEndpointRejected(endpoint_id_3); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1400)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 10500 - strategy_session { - duration_millis: 10400 - strategy: P2P_STAR - role: DISCOVERER - discovery_phase { - duration_millis: 10400 - medium: BLE - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - adv_dis_result { - medium: BLUETOOTH - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - stop_reason: FINISH_SESSION_STOP_DISCOVERING - sent_connection_request { - duration_millis: 700 - request_delay_millis: 200 - local_response: ACCEPTED - remote_response: ACCEPTED - } - sent_connection_request { - duration_millis: 1300 - request_delay_millis: 1400 - local_response: ACCEPTED - remote_response: REJECTED - } - sent_connection_request { - duration_millis: 1900 - request_delay_millis: 3500 - local_response: REJECTED - remote_response: ACCEPTED - } - sent_connection_request { - duration_millis: 2500 - request_delay_millis: 6500 - local_response: REJECTED - remote_response: REJECTED - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, - AdvertiserUnfinishedConnectionRequestsIncludedAsIgnored) { - std::string endpoint_id_0 = "endpoint_id_0"; - std::string endpoint_id_1 = "endpoint_id_1"; - std::string endpoint_id_2 = "endpoint_id_2"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - OperationResultWithMedium operation_result; - operation_result.set_medium(BLUETOOTH); - operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); - operation_result.set_result_category( - OperationResultCategory::CATEGORY_SUCCESS); - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - advertising_metadata_params->operation_result_with_mediums = { - operation_result}; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - // Ignored by local. - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnConnectionRequestReceived(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - - // Ignored by remote. - analytics_recorder.OnConnectionRequestReceived(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - - // Ignored by both. - analytics_recorder.OnConnectionRequestReceived(endpoint_id_2); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 2800 - strategy_session { - duration_millis: 2700 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 2700 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - adv_dis_result { - medium: BLUETOOTH - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - stop_reason: FINISH_SESSION_STOP_ADVERTISING - received_connection_request { - duration_millis: 2500 - request_delay_millis: 200 - local_response: IGNORED - remote_response: ACCEPTED - } - received_connection_request { - duration_millis: 1800 - request_delay_millis: 900 - local_response: ACCEPTED - remote_response: IGNORED - } - received_connection_request { - duration_millis: 700 - request_delay_millis: 2000 - local_response: IGNORED - remote_response: IGNORED - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, - DiscovererUnfinishedConnectionRequestsIncludedAsIgnored) { - std::string endpoint_id_0 = "endpoint_id_0"; - std::string endpoint_id_1 = "endpoint_id_1"; - std::string endpoint_id_2 = "endpoint_id_2"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - OperationResultWithMedium operation_result; - operation_result.set_medium(BLUETOOTH); - operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); - operation_result.set_result_category( - OperationResultCategory::CATEGORY_SUCCESS); - auto discovery_metadata_params = - analytics_recorder.BuildDiscoveryMetadataParams(); - discovery_metadata_params->operation_result_with_mediums = {operation_result}; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - discovery_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - - // Ignored by local. - analytics_recorder.OnConnectionRequestSent(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - - // Ignored by remote. - analytics_recorder.OnConnectionRequestSent(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - - // Ignored by both. - analytics_recorder.OnConnectionRequestSent(endpoint_id_2); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 2800 - strategy_session { - duration_millis: 2700 - strategy: P2P_STAR - role: DISCOVERER - discovery_phase { - duration_millis: 2700 - medium: BLE - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - adv_dis_result { - medium: BLUETOOTH - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - stop_reason: FINISH_SESSION_STOP_DISCOVERING - sent_connection_request { - duration_millis: 2500 - request_delay_millis: 200 - local_response: IGNORED - remote_response: ACCEPTED - } - sent_connection_request { - duration_millis: 1800 - request_delay_millis: 900 - local_response: ACCEPTED - remote_response: IGNORED - } - sent_connection_request { - duration_millis: 700 - request_delay_millis: 2000 - local_response: IGNORED - remote_response: IGNORED - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, SuccessfulIncomingConnectionAttempt) { - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - OperationResultWithMedium operation_result; - operation_result.set_medium(BLUETOOTH); - operation_result.set_result_code(OperationResultCode::DETAIL_SUCCESS); - operation_result.set_result_category( - OperationResultCategory::CATEGORY_SUCCESS); - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - advertising_metadata_params->operation_result_with_mediums = { - operation_result}; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - - auto connections_attempt_metadata_params = - std::make_unique(); - connections_attempt_metadata_params->operation_result_code = - OperationResultCode::DETAIL_SUCCESS; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnIncomingConnectionAttempt( - INITIAL, BLUETOOTH, RESULT_SUCCESS, absl::Duration{}, - /*connection_token=*/"", connections_attempt_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnStopAdvertising(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 1000 - strategy_session { - duration_millis: 900 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 500 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_ADVERTISING - adv_dis_result { - medium: BLUETOOTH - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - connection_attempt { - duration_millis: 0 - type: INITIAL - direction: INCOMING - medium: BLUETOOTH - attempt_result: RESULT_SUCCESS - connection_token: "" - connection_attempt_metadata { - technology: CONNECTION_TECHNOLOGY_UNKNOWN_TECHNOLOGY - band: CONNECTION_BAND_UNKNOWN_BAND - frequency: -1 - network_operator: "" - country_code: "" - is_tdls_used: false - try_counts: 0 - wifi_hotspot_status: false - max_tx_speed: 0 - max_rx_speed: 0 - wifi_channel_width: -1 - } - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, - FailedConnectionAttemptUpdatesConnectionRequestNotSent) { - std::string endpoint_id = "endpoint_id"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto connections_attempt_metadata_params = - analytics_recorder.BuildConnectionAttemptMetadataParams( - ::location::nearby::proto::connections:: - CONNECTION_TECHNOLOGY_HOTSPOT_LOCALONLY, - ::location::nearby::proto::connections:: - CONNECTION_BAND_WIFI_BAND_6GHZ, - /*frequency*/ 2400, /*try_count*/ 0, /*network_operator*/ {}, - /*country_code*/ {}, /*is_tdls_used*/ false, - /*wifi_hotspot_enabled*/ false, /*max_wifi_tx_speed*/ 0, - /*max_wifi_rx_speed*/ 0, /*channel_width*/ 0, - OperationResultCode::CONNECTIVITY_BT_CLIENT_SOCKET_CREATION_FAILURE); - auto discovery_metadata_params = - analytics_recorder.BuildDiscoveryMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - discovery_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnConnectionRequestSent(endpoint_id); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnOutgoingConnectionAttempt( - endpoint_id, INITIAL, BLUETOOTH, RESULT_ERROR, absl::Duration{}, - /*connection_token=*/"", connections_attempt_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 1000 - strategy_session { - duration_millis: 900 - strategy: P2P_STAR - role: DISCOVERER - discovery_phase { - duration_millis: 900 - medium: BLE - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: FINISH_SESSION_STOP_DISCOVERING - sent_connection_request { - duration_millis: 300 - request_delay_millis: 200 - local_response: NOT_SENT - remote_response: NOT_SENT - } - } - connection_attempt { - duration_millis: 0 - type: INITIAL - direction: OUTGOING - medium: BLUETOOTH - attempt_result: RESULT_ERROR - connection_token: "" - connection_attempt_metadata { - technology: CONNECTION_TECHNOLOGY_HOTSPOT_LOCALONLY - band: CONNECTION_BAND_WIFI_BAND_6GHZ - frequency: 2400 - network_operator: "" - country_code: "" - is_tdls_used: false - try_counts: 0 - wifi_hotspot_status: false - max_tx_speed: 0 - max_rx_speed: 0 - wifi_channel_width: 0 - } - operation_result { - result_category: CATEGORY_CONNECTIVITY_ERROR - result_code: CONNECTIVITY_BT_CLIENT_SOCKET_CREATION_FAILURE - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, - UnfinishedEstablishedConnectionsAddedAsUnfinished) { - std::string endpoint_id = "endpoint_id"; - std::string connection_token = "connection_token"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnConnectionEstablished(endpoint_id, BLUETOOTH, - connection_token); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnConnectionClosed(endpoint_id, BLUETOOTH, UPGRADED, - SafeDisconnectionResult::kUnknown); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnConnectionEstablished(endpoint_id, WIFI_LAN, - connection_token); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 1500 - strategy_session { - duration_millis: 1400 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 1400 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: FINISH_SESSION_STOP_ADVERTISING - } - established_connection { - duration_millis: 300 - medium: BLUETOOTH - disconnection_reason: UPGRADED - connection_token: "connection_token" - safe_disconnection_result: UNKNOWN_SAFE_DISCONNECTION_RESULT - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - established_connection { - duration_millis: 500 - medium: WIFI_LAN - disconnection_reason: UNFINISHED - connection_token: "connection_token" - safe_disconnection_result: SAFE_DISCONNECTION - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, OutgoingPayloadUpgraded) { - std::string endpoint_id = "endpoint_id"; - std::int64_t payload_id = 123456789; - std::string connection_token = "connection_token"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnConnectionEstablished(endpoint_id, BLUETOOTH, - connection_token); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnOutgoingPayloadStarted( - {endpoint_id}, payload_id, connections::PayloadType::kFile, 50); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnPayloadChunkSent(endpoint_id, payload_id, 10); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.OnPayloadChunkSent(endpoint_id, payload_id, 10); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.OnConnectionClosed( - endpoint_id, BLUETOOTH, UPGRADED, - SafeDisconnectionResult::kSafeDisconnection); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - analytics_recorder.OnConnectionEstablished(endpoint_id, WIFI_LAN, - connection_token); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); - analytics_recorder.OnPayloadChunkSent(endpoint_id, payload_id, 10); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); - analytics_recorder.OnPayloadChunkSent(endpoint_id, payload_id, 10); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1000)); - analytics_recorder.OnPayloadChunkSent(endpoint_id, payload_id, 10); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1100)); - analytics_recorder.OnOutgoingPayloadDone(endpoint_id, payload_id, SUCCESS, - OperationResultCode::DETAIL_SUCCESS); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1200)); - analytics_recorder.OnConnectionClosed( - endpoint_id, WIFI_LAN, LOCAL_DISCONNECTION, - SafeDisconnectionResult::kSafeDisconnection); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1300)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 9100 - strategy_session { - duration_millis: 9000 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 9000 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: FINISH_SESSION_STOP_ADVERTISING - } - established_connection { - duration_millis: 1800 - medium: BLUETOOTH - sent_payload { - duration_millis: 1500 - type: FILE - total_size_bytes: 50 - num_bytes_transferred: 20 - num_chunks: 2 - status: MOVED_TO_NEW_MEDIUM - operation_result { - result_category: CATEGORY_MISCELLANEOUS - result_code: MISCELLEANEOUS_MOVE_TO_NEW_MEDIUM - } - } - disconnection_reason: UPGRADED - connection_token: "connection_token" - safe_disconnection_result: SAFE_DISCONNECTION - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - established_connection { - duration_millis: 5000 - medium: WIFI_LAN - sent_payload { - duration_millis: 4500 - type: FILE - total_size_bytes: 50 - num_bytes_transferred: 30 - num_chunks: 3 - status: SUCCESS - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - disconnection_reason: LOCAL_DISCONNECTION - connection_token: "connection_token" - safe_disconnection_result: SAFE_DISCONNECTION - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, UpgradeAttemptWorks) { - std::string endpoint_id = "endpoint_id"; - std::string endpoint_id_1 = "endpoint_id_1"; - std::string endpoint_id_2 = "endpoint_id_2"; - std::string connection_token = "connection_token"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - - analytics_recorder.OnBandwidthUpgradeStarted(endpoint_id, BLE, WIFI_LAN, - INCOMING, connection_token); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - - analytics_recorder.OnBandwidthUpgradeStarted( - endpoint_id_1, BLUETOOTH, WIFI_LAN, INCOMING, connection_token); - // Error to upgrade. - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnBandwidthUpgradeError( - endpoint_id, WIFI_LAN_MEDIUM_ERROR, WIFI_LAN_SOCKET_CREATION, - OperationResultCode::CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL); - // Success to upgrade. - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.OnBandwidthUpgradeSuccess(endpoint_id_1); - // Upgrade is unfinished. - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.OnBandwidthUpgradeStarted( - endpoint_id_2, BLUETOOTH, WIFI_LAN, INCOMING, connection_token); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 2800 - strategy_session { - duration_millis: 2700 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 2700 - medium: BLE - 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 { - duration_millis: 700 - direction: INCOMING - from_medium: BLE - to_medium: WIFI_LAN - upgrade_result: WIFI_LAN_MEDIUM_ERROR - error_stage: WIFI_LAN_SOCKET_CREATION - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_CONNECTIVITY_ERROR - result_code: CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL - } - } - upgrade_attempt { - duration_millis: 900 - direction: INCOMING - from_medium: BLUETOOTH - to_medium: WIFI_LAN - upgrade_result: UPGRADE_RESULT_SUCCESS - error_stage: UPGRADE_SUCCESS - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - upgrade_attempt { - duration_millis: 700 - direction: INCOMING - from_medium: BLUETOOTH - to_medium: WIFI_LAN - upgrade_result: UNFINISHED_ERROR - error_stage: UPGRADE_UNFINISHED - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_DEVICE_STATE_ERROR - result_code: DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, StartListeningForIncomingConnectionsWorks) { - std::string endpoint_id = "endpoint_id"; - std::string endpoint_id_1 = "endpoint_id_1"; - std::string endpoint_id_2 = "endpoint_id_2"; - std::string connection_token = "connection_token"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartedIncomingConnectionListening( - connections::Strategy::kP2pStar); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - - analytics_recorder.OnBandwidthUpgradeStarted(endpoint_id, BLE, WIFI_LAN, - INCOMING, connection_token); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnBandwidthUpgradeStarted( - endpoint_id_1, BLUETOOTH, WIFI_LAN, INCOMING, connection_token); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - // Error to upgrade. - analytics_recorder.OnBandwidthUpgradeError( - endpoint_id, WIFI_LAN_MEDIUM_ERROR, WIFI_LAN_SOCKET_CREATION, - OperationResultCode::CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - // Success to upgrade. - analytics_recorder.OnBandwidthUpgradeSuccess(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - - analytics_recorder.LogSession(); - // ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 2100 - strategy_session { - duration_millis: 2000 - strategy: P2P_STAR - role: ADVERTISER - upgrade_attempt { - direction: INCOMING - duration_millis: 700 - from_medium: BLE - to_medium: WIFI_LAN - upgrade_result: WIFI_LAN_MEDIUM_ERROR - error_stage: WIFI_LAN_SOCKET_CREATION - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_CONNECTIVITY_ERROR - result_code: CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL - } - } - upgrade_attempt { - direction: INCOMING - duration_millis: 900 - from_medium: BLUETOOTH - to_medium: WIFI_LAN - upgrade_result: UPGRADE_RESULT_SUCCESS - error_stage: UPGRADE_SUCCESS - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -TEST_F(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectly) { - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto discovery_metadata_params = - analytics_recorder.BuildDiscoveryMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, - /*mediums=*/{WEB_RTC}, - discovery_metadata_params.get()); - - ErrorCodeParams error_code_params = ErrorCodeRecorder::BuildErrorCodeParams( - WEB_RTC, DISCONNECT, DISCONNECT_NETWORK_FAILED, - TACHYON_SEND_MESSAGE_STATUS_EXCEPTION, "", "connection_token"); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnErrorCode(error_code_params); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ErrorCode error_code_proto = ParseTextProtoOrDie(R"pb( - medium: WEB_RTC - event: DISCONNECT - description: TACHYON_SEND_MESSAGE_STATUS_EXCEPTION - disconnect_error: DISCONNECT_NETWORK_FAILED - connection_token: "connection_token" - )pb"); - - EXPECT_THAT(event_logger.GetErrorCode(), EqualsProto(error_code_proto)); -} - -TEST_F(AnalyticsRecorderTest, - SetErrorCodeFieldsCorrectlyForUnknownDescription) { - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto discovery_metadata_params = - analytics_recorder.BuildDiscoveryMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, - /*mediums=*/{BLUETOOTH}, - discovery_metadata_params.get()); - - ErrorCodeParams error_code_params; - // Skip setting error_code_params.description - error_code_params.medium = BLUETOOTH; - error_code_params.event = START_DISCOVERING; - error_code_params.start_discovering_error = START_EXTENDED_DISCOVERING_FAILED; - error_code_params.connection_token = "connection_token"; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnErrorCode(error_code_params); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ErrorCode error_code_proto = ParseTextProtoOrDie(R"pb( - medium: BLUETOOTH - event: START_DISCOVERING - description: UNKNOWN - start_discovering_error: START_EXTENDED_DISCOVERING_FAILED - connection_token: "connection_token" - )pb"); - - EXPECT_THAT(event_logger.GetErrorCode(), EqualsProto(error_code_proto)); -} - -TEST_F(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectlyForCommonError) { - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto discovery_metadata_params = - analytics_recorder.BuildDiscoveryMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, - /*mediums=*/{BLUETOOTH}, - discovery_metadata_params.get()); - - ErrorCodeParams error_code_params = ErrorCodeRecorder::BuildErrorCodeParams( - BLUETOOTH, START_DISCOVERING, INVALID_PARAMETER, - NULL_BLUETOOTH_DEVICE_NAME, "", "connection_token"); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnErrorCode(error_code_params); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ErrorCode error_code_proto = ParseTextProtoOrDie(R"pb( - medium: BLUETOOTH - event: START_DISCOVERING - description: NULL_BLUETOOTH_DEVICE_NAME - common_error: INVALID_PARAMETER - connection_token: "connection_token" - )pb"); - - EXPECT_THAT(event_logger.GetErrorCode(), EqualsProto(error_code_proto)); -} - -TEST_F(AnalyticsRecorderTest, CheckIfSessionWasLogged) { - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - // LogSession to count down client_session_done_latch. - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - EXPECT_TRUE(analytics_recorder.IsSessionLogged()); -} - -TEST_F(AnalyticsRecorderTest, ConstructAnalyticsRecorder) { - CountDownLatch client_session_done_latch(0); - CountDownLatch start_client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch, - &start_client_session_done_latch); - - // Call the constructor to count down the session_done_latch. - AnalyticsRecorderImpl analytics_recorder(&event_logger); - ASSERT_TRUE(start_client_session_done_latch.Await(kDefaultTimeout).result()); - - std::vector event_types = event_logger.GetLoggedEventTypes(); - EXPECT_EQ(event_types.size(), 1); - EXPECT_THAT(event_types, Contains(START_CLIENT_SESSION).Times(1)); -} - -TEST_F( - AnalyticsRecorderTest, - StartClientSessionOnlyLoggedOnceWorksAfterAnalyticsRecorderIsConstructed) { - CountDownLatch client_session_done_latch(0); - CountDownLatch start_client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch, - &start_client_session_done_latch); - - // Call the constructor to count down the start_client_session_done_latch. - AnalyticsRecorderImpl analytics_recorder(&event_logger); - ASSERT_TRUE(start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // Log start client session once. - EXPECT_THAT(event_logger.GetLoggedEventTypes(), - Contains(START_CLIENT_SESSION).Times(1)); - - // Reset the start_client_session_done_latch. However, LogStartSession cannot - // count down the start_client_session_done_latch. - CountDownLatch new_start_client_session_done_latch(1); - event_logger.SetStartClientSessionDoneLatchPtr( - &new_start_client_session_done_latch); - analytics_recorder.LogStartSession(); - ASSERT_FALSE( - new_start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // No more start client session was logged. - EXPECT_THAT(event_logger.GetLoggedEventTypes(), - Contains(START_CLIENT_SESSION).Times(1)); -} - -TEST_F(AnalyticsRecorderTest, - CanLogStartClientSessionOnceAgainAfterSessionWasLogged) { - CountDownLatch client_session_done_latch(0); - CountDownLatch start_client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch, - &start_client_session_done_latch); - - // Call the constructor to count down the start_client_session_done_latch. - AnalyticsRecorderImpl analytics_recorder(&event_logger); - ASSERT_TRUE(start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // Log start client session once. - EXPECT_THAT(event_logger.GetLoggedEventTypes(), - Contains(START_CLIENT_SESSION).Times(1)); - - // Reset the client_session_done_latch. Call LogSession to count down the - // client_session_done_latch. - CountDownLatch new_client_session_done_latch(1); - event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - // Reset the start_client_session_done_latch. Call LogStartSession to count - // down the start_client_session_done_latch. - CountDownLatch new_start_client_session_done_latch(1); - event_logger.SetStartClientSessionDoneLatchPtr( - &new_start_client_session_done_latch); - analytics_recorder.LogStartSession(); - analytics_recorder.LogStartSession(); - analytics_recorder.LogStartSession(); - analytics_recorder.LogStartSession(); - ASSERT_TRUE( - new_start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // Can log start client session once again. - EXPECT_THAT(event_logger.GetLoggedEventTypes(), - Contains(START_CLIENT_SESSION).Times(2)); -} - -TEST_F(AnalyticsRecorderTest, - ClearcIncomingConnectionRequestsAfterSessionWasLogged) { - std::string endpoint_id_0 = "endpoint_id_0"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnConnectionRequestReceived(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnLocalEndpointAccepted(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - - // LogSession - analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto1 = - ParseTextProtoOrDie(R"pb( - duration_millis: 1500 - strategy_session { - duration_millis: 1400 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 1400 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: FINISH_SESSION_STOP_ADVERTISING - received_connection_request { - duration_millis: 700 - request_delay_millis: 200 - local_response: ACCEPTED - remote_response: ACCEPTED - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto1)); - - // LogStartSession - CountDownLatch new_start_client_session_done_latch(1); - event_logger.SetStartClientSessionDoneLatchPtr( - &new_start_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.LogStartSession(); - ASSERT_TRUE( - new_start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // LogSession again - CountDownLatch new_client_session_done_latch(1); - event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - std::string endpoint_id_1 = "endpoint_id_1"; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - analytics_recorder.OnConnectionRequestReceived(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); - analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); - analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(1000)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(new_client_session_done_latch.Await(kDefaultTimeout).result()); - - // - if the current_strategy_session_ and current_advertising_phase_ are not - // reset, the duplicate advertising_phase (with the additional - // received_connection_request) will append to the strategy_session) - ConnectionsLog::ClientSession strategy_session_proto2 = ParseTextProtoOrDie( - R"pb( - duration_millis: 0 - strategy_session { - duration_millis: 0 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 0 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - received_connection_request { - duration_millis: 0 - request_delay_millis: 0 - local_response: ACCEPTED - remote_response: ACCEPTED - } - } - advertising_phase { - duration_millis: 0 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - received_connection_request { - duration_millis: 0 - request_delay_millis: 0 - local_response: ACCEPTED - remote_response: ACCEPTED - } - received_connection_request { - duration_millis: 0 - request_delay_millis: 0 - local_response: ACCEPTED - remote_response: ACCEPTED - } - } - })pb"); - EXPECT_THAT(event_logger.GetLoggedClientSession(), - Not(EqualsProto(strategy_session_proto2))); -} - -TEST_F(AnalyticsRecorderTest, - ClearcOutgoingConnectionRequestsAfterSessionWasLogged) { - std::string endpoint_id_0 = "endpoint_id_0"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto discovery_metadata_params = - analytics_recorder.BuildDiscoveryMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartDiscovery(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - discovery_metadata_params.get()); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnConnectionRequestSent(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnLocalEndpointAccepted(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - - // LogSession - analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto1 = - ParseTextProtoOrDie(R"pb( - duration_millis: 1500 - strategy_session { - duration_millis: 1400 - strategy: P2P_STAR - role: DISCOVERER - discovery_phase { - duration_millis: 1400 - medium: BLE - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: FINISH_SESSION_STOP_DISCOVERING - sent_connection_request { - duration_millis: 700 - request_delay_millis: 200 - local_response: ACCEPTED - remote_response: ACCEPTED - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto1)); - - // LogStartSession - CountDownLatch new_start_client_session_done_latch(1); - event_logger.SetStartClientSessionDoneLatchPtr( - &new_start_client_session_done_latch); - analytics_recorder.LogStartSession(); - ASSERT_TRUE( - new_start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // LogSession again - CountDownLatch new_client_session_done_latch(1); - event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - std::string endpoint_id_1 = "endpoint_id_1"; - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.OnConnectionRequestSent(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); - analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_1); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - // - if the current_strategy_session_ and current_discovery_phase_ are - // not reset, the duplicate discovery_phase (with the additional - // sent_connection_request) will append to the strategy_session) - ConnectionsLog::ClientSession strategy_session_proto2 = - ParseTextProtoOrDie(R"pb( - duration_millis: 0 - strategy_session { - duration_millis: 0 - strategy: P2P_STAR - role: DISCOVERER - discovery_phase { - duration_millis: 0 - medium: BLE - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - sent_connection_request { - duration_millis: 0 - request_delay_millis: 0 - local_response: ACCEPTED - remote_response: ACCEPTED - } - } - discovery_phase { - duration_millis: 0 - medium: BLE - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - sent_connection_request { - duration_millis: 0 - request_delay_millis: 0 - local_response: ACCEPTED - remote_response: ACCEPTED - } - sent_connection_request { - duration_millis: 0 - request_delay_millis: 0 - local_response: ACCEPTED - remote_response: ACCEPTED - } - } - })pb"); - EXPECT_THAT(event_logger.GetLoggedClientSession(), - Not(EqualsProto(strategy_session_proto2))); -} - -TEST_F(AnalyticsRecorderTest, ClearcActiveConnectionsAfterSessionWasLogged) { - connections::Strategy strategy = connections::Strategy::kP2pStar; - std::vector mediums = {BLE, BLUETOOTH}; - std::string endpoint_id = "endpoint_id"; - std::string connection_token = "connection_token"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(strategy, mediums, - advertising_metadata_params.get()); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnConnectionEstablished(endpoint_id, BLUETOOTH, - connection_token); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - - // LogSession - analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - ConnectionsLog::ClientSession strategy_session_proto1 = - ParseTextProtoOrDie(R"pb( - duration_millis: 600 - strategy_session { - duration_millis: 500 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 500 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: FINISH_SESSION_STOP_ADVERTISING - } - established_connection { - duration_millis: 300 - medium: BLUETOOTH - disconnection_reason: UNFINISHED - connection_token: "connection_token" - safe_disconnection_result: SAFE_DISCONNECTION - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto1)); - - // LogStartSession - CountDownLatch new_start_client_session_done_latch(1); - event_logger.SetStartClientSessionDoneLatchPtr( - &new_start_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.LogStartSession(); - ASSERT_TRUE( - new_start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // LogSession again - CountDownLatch new_client_session_done_latch(1); - event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - // - if the current_strategy_session_ and advertising_phase_ are not - // reset, the duplicate advertising_phase_ (with the additional - // will append to the strategy_session), and the active connection (i.e. - // established_connection) will stay there. - ConnectionsLog::ClientSession strategy_session_proto2 = - ParseTextProtoOrDie(R"pb( - duration_millis: 0 - strategy_session { - duration_millis: 0 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 0 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - } - advertising_phase { - duration_millis: 0 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - } - established_connection { - duration_millis: 0 - medium: BLUETOOTH - disconnection_reason: UNFINISHED - connection_token: "connection_token" - safe_disconnection_result: SAFE_DISCONNECTION - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - Not(EqualsProto(strategy_session_proto2))); -} - -TEST_F(AnalyticsRecorderTest, - ClearBandwidthUpgradeAttemptsAfterSessionWasLogged) { - std::string endpoint_id = "endpoint_id"; - std::string endpoint_id_1 = "endpoint_id_1"; - std::string endpoint_id_2 = "endpoint_id_2"; - std::string connection_token = "connection_token"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnBandwidthUpgradeStarted(endpoint_id, BLE, WIFI_LAN, - INCOMING, connection_token); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnBandwidthUpgradeStarted( - endpoint_id_1, BLUETOOTH, WIFI_LAN, INCOMING, connection_token); - // - Error to upgrade. - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnBandwidthUpgradeError( - endpoint_id, WIFI_LAN_MEDIUM_ERROR, WIFI_LAN_SOCKET_CREATION, - OperationResultCode::CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL); - // - Success to upgrade. - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.OnBandwidthUpgradeSuccess(endpoint_id_1); - - // - Upgrade is unfinished. - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.OnBandwidthUpgradeStarted( - endpoint_id_2, BLUETOOTH, WIFI_LAN, INCOMING, connection_token); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - // LogSession - analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - // - if the current_strategy_session_ and advertising_phase_ are not - // reset, the duplicate advertising_phase_, and the upgrade_attempts (i.e. - // bandwidth_upgrade_attempts_) will stay there. - ConnectionsLog::ClientSession strategy_session_proto1 = - ParseTextProtoOrDie(R"pb( - duration_millis: 2800 - strategy_session { - duration_millis: 2700 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 2700 - medium: BLE - 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: INCOMING - duration_millis: 700 - from_medium: BLE - to_medium: WIFI_LAN - upgrade_result: WIFI_LAN_MEDIUM_ERROR - error_stage: WIFI_LAN_SOCKET_CREATION - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_CONNECTIVITY_ERROR - result_code: CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL - } - } - upgrade_attempt { - direction: INCOMING - duration_millis: 900 - from_medium: BLUETOOTH - to_medium: WIFI_LAN - upgrade_result: UPGRADE_RESULT_SUCCESS - error_stage: UPGRADE_SUCCESS - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - upgrade_attempt { - direction: INCOMING - duration_millis: 700 - from_medium: BLUETOOTH - to_medium: WIFI_LAN - upgrade_result: UNFINISHED_ERROR - error_stage: UPGRADE_UNFINISHED - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_DEVICE_STATE_ERROR - result_code: DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS - } - } - })pb"); - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto1)); - - // LogStartSession - CountDownLatch new_start_client_session_done_latch(1); - event_logger.SetStartClientSessionDoneLatchPtr( - &new_start_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(800)); - analytics_recorder.LogStartSession(); - ASSERT_TRUE( - new_start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // LogSession again - CountDownLatch new_client_session_done_latch(1); - event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(900)); - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto2 = - ParseTextProtoOrDie(R"pb( - duration_millis: 0 - strategy_session { - duration_millis: 0 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 0 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - } - advertising_phase { - duration_millis: 0 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - } - upgrade_attempt { - direction: INCOMING - from_medium: BLE - to_medium: WIFI_LAN - upgrade_result: WIFI_LAN_MEDIUM_ERROR - error_stage: WIFI_LAN_SOCKET_CREATION - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_CONNECTIVITY_ERROR - result_code: CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL - } - } - upgrade_attempt { - direction: INCOMING - from_medium: BLUETOOTH - to_medium: WIFI_LAN - upgrade_result: UPGRADE_RESULT_SUCCESS - error_stage: UPGRADE_SUCCESS - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_SUCCESS - result_code: DETAIL_SUCCESS - } - } - upgrade_attempt { - direction: INCOMING - from_medium: BLUETOOTH - to_medium: WIFI_LAN - upgrade_result: UNFINISHED_ERROR - error_stage: UPGRADE_UNFINISHED - connection_token: "connection_token" - operation_result { - result_category: CATEGORY_DEVICE_STATE_ERROR - result_code: DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS - } - } - })pb"); - EXPECT_THAT(event_logger.GetLoggedClientSession(), - Not(EqualsProto(strategy_session_proto2))); -} - -// Test if current_strategy_ is reset by checking if the same strategy would -// be logged for different client sessions or not. If yes, it should be logged. -// Otherwise, not. -TEST_F(AnalyticsRecorderTest, - CanLogSeparateStartStrategySessionForSameStrategyAfterSessionWasLogged) { - connections::Strategy strategy = connections::Strategy::kP2pStar; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLUETOOTH}, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnStopAdvertising(); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - // LogSession - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - // The same strategy session shouldn't be logged again with the same client - // session. - EXPECT_THAT(event_logger.GetLoggedEventTypes(), - Contains(START_STRATEGY_SESSION).Times(1)); - - // LogStartSession - CountDownLatch new_start_client_session_done_latch(1); - event_logger.SetStartClientSessionDoneLatchPtr( - &new_start_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.LogStartSession(); - ASSERT_TRUE( - new_start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // LogSession again - CountDownLatch new_client_session_done_latch(1); - event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.OnStartAdvertising(strategy, /*mediums=*/{BLUETOOTH}, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.OnStopAdvertising(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(700)); - - analytics_recorder.LogSession(); - ASSERT_TRUE(new_client_session_done_latch.Await(kDefaultTimeout).result()); - - EXPECT_THAT(event_logger.GetLoggedEventTypes(), - Contains(START_STRATEGY_SESSION).Times(2)); -} - -// Test if current_strategy_session_ is reset. If not, the same strategy session -// proto will be logged. -TEST_F(AnalyticsRecorderTest, - NotLogSameStrategySessionProtoAfterSessionWasLogged) { - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - // Via OnStartAdvertising, current_strategy_session_is set in - // UpdateStrategySessionLocked. - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnStopAdvertising(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - // LogSession - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 600 - strategy_session { - duration_millis: 500 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 200 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_ADVERTISING - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); - - // LogStartSession - CountDownLatch new_start_client_session_done_latch(1); - event_logger.SetStartClientSessionDoneLatchPtr( - &new_start_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.LogStartSession(); - ASSERT_TRUE( - new_start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // LogSession again - // - if current_strategy_session_ is reset, the same - // strategy_session_proto will be logged. - CountDownLatch new_client_session_done_latch(1); - event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.LogSession(); - ASSERT_TRUE(new_client_session_done_latch.Await(kDefaultTimeout).result()); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - Not(EqualsProto(strategy_session_proto))); -} - -// Test if current_advertising_phase_ is reset. -TEST_F(AnalyticsRecorderTest, - NotLogDuplicateAdvertisingPhaseAfterSessionWasLogged) { - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising( - connections::Strategy::kP2pStar, - /*mediums=*/{BLUETOOTH}, - advertising_metadata_params.get()); // set current_advertising_phase_ - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnStopAdvertising(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - - // LogSession - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto1 = - ParseTextProtoOrDie(R"pb( - duration_millis: 600 - strategy_session { - duration_millis: 500 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 200 - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_ADVERTISING - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto1)); - - // LogStartSession - CountDownLatch new_start_client_session_done_latch(1); - event_logger.SetStartClientSessionDoneLatchPtr( - &new_start_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.LogStartSession(); - ASSERT_TRUE( - new_start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // LogSession again - // - if the current_strategy_session_ and current_advertising_phase_ are - // not reset, the same strategy_session with two same advertising_phase will - // be logged. - CountDownLatch new_client_session_done_latch(1); - event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto2 = - ParseTextProtoOrDie(R"pb( - duration_millis: 0 - strategy_session { - duration_millis: 0 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 0 - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - } - advertising_phase { - duration_millis: 0 - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - } - })pb"); - EXPECT_THAT(event_logger.GetLoggedClientSession(), - Not(EqualsProto(strategy_session_proto2))); -} - -// Test if current_discovery_phase_ is reset. -TEST_F(AnalyticsRecorderTest, - NotLogDuplicateDiscoveryPhaseAfterSessionWasLogged) { - connections::Strategy strategy = connections::Strategy::kP2pStar; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - auto discovery_metadata_params = - analytics_recorder.BuildDiscoveryMetadataParams( - /*is_extended_advertisement_supported*/ true, - /*connected_ap_frequency*/ 1, /*is_nfc_available=*/false); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartDiscovery( - strategy, {BLUETOOTH}, - discovery_metadata_params.get()); // set current_discovery_phase_ - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnStopDiscovery(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - analytics_recorder.OnEndpointFound(BLUETOOTH); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - // LogSession - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto1 = - ParseTextProtoOrDie(R"pb( - duration_millis: 1000 - strategy_session { - duration_millis: 900 - strategy: P2P_STAR - role: DISCOVERER - discovery_phase { - duration_millis: 200 - medium: BLUETOOTH - discovered_endpoint { medium: BLUETOOTH latency_millis: 500 } - discovery_metadata { - supports_extended_ble_advertisements: true - connected_ap_frequency: 1 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_DISCOVERING - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto1)); - - // LogStartSession - CountDownLatch new_start_client_session_done_latch(1); - event_logger.SetStartClientSessionDoneLatchPtr( - &new_start_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.LogStartSession(); - ASSERT_TRUE( - new_start_client_session_done_latch.Await(kDefaultTimeout).result()); - - // LogSession again - // - if the current_strategy_session_ and current_discovery_phase_ are not - // reset, the same strategy_session with two same discovery_phase will be - // logged. - CountDownLatch new_client_session_done_latch(1); - event_logger.SetClientSessionDoneLatch(new_client_session_done_latch); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto2 = - ParseTextProtoOrDie(R"pb( - duration_millis: 0 - strategy_session { - duration_millis: 0 - strategy: P2P_STAR - role: DISCOVERER - discovery_phase { - duration_millis: 0 - medium: BLUETOOTH - discovered_endpoint { medium: BLUETOOTH } - discovery_metadata { - supports_extended_ble_advertisements: true - connected_ap_frequency: 1 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_DISCOVERING - } - discovery_phase { - duration_millis: 0 - medium: BLUETOOTH - discovery_metadata { - supports_extended_ble_advertisements: true - connected_ap_frequency: 1 - supports_nfc_technology: false - } - } - })pb"); - EXPECT_THAT(event_logger.GetLoggedClientSession(), - Not(EqualsProto(strategy_session_proto2))); -} - -TEST_F(AnalyticsRecorderTest, - NotAddNewConnectionWithoutCallingOnStartAdvertising) { - std::string endpoint_id = "endpoint_id"; - - CountDownLatch client_session_done_latch(1); - FakeEventLogger event_logger(client_session_done_latch); - AnalyticsRecorderImpl analytics_recorder(&event_logger); - - // via OnStartAdvertising, current_strategy_session_ is set in - // UpdateStrategySessionLocked. - auto advertising_metadata_params = - analytics_recorder.BuildAdvertisingMetadataParams(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(100)); - analytics_recorder.OnStartAdvertising(connections::Strategy::kP2pStar, - /*mediums=*/{BLE, BLUETOOTH}, - advertising_metadata_params.get()); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(200)); - analytics_recorder.OnStopAdvertising(); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(300)); - - // LogSession - analytics_recorder.LogSession(); - ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result()); - - ConnectionsLog::ClientSession strategy_session_proto = - ParseTextProtoOrDie(R"pb( - duration_millis: 600 - strategy_session { - duration_millis: 500 - strategy: P2P_STAR - role: ADVERTISER - advertising_phase { - duration_millis: 200 - medium: BLE - medium: BLUETOOTH - advertising_metadata { - supports_extended_ble_advertisements: false - connected_ap_frequency: 0 - supports_nfc_technology: false - } - stop_reason: CLIENT_STOP_ADVERTISING - } - })pb"); - - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); - - // Without calling OnStartAdvertising won't create new - // current_strategy_session_. - MediumEnvironment::Instance().FastForward(absl::Milliseconds(400)); - analytics_recorder.OnConnectionEstablished(endpoint_id, BLUETOOTH, - /*connection_token=*/""); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(500)); - analytics_recorder.OnConnectionClosed( - endpoint_id, BLUETOOTH, UPGRADED, - SafeDisconnectionResult::kSafeDisconnection); - MediumEnvironment::Instance().FastForward(absl::Milliseconds(600)); - analytics_recorder.LogSession(); - - // The proto won't change. - EXPECT_THAT(event_logger.GetLoggedClientSession(), - EqualsProto(strategy_session_proto)); -} - -} // namespace -} // namespace nearby::analytics diff --git a/internal/analytics/BUILD b/internal/analytics/BUILD deleted file mode 100644 index 9b22ebf8..00000000 --- a/internal/analytics/BUILD +++ /dev/null @@ -1,50 +0,0 @@ -load("@rules_cc//cc:cc_library.bzl", "cc_library") - -licenses(["notice"]) -# Copyright 2020 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. - -cc_library( - name = "event_logger", - hdrs = [ - "event_logger.h", - ], - visibility = [ - "//connections:__subpackages__", - "//location/nearby/analytics/cpp:__subpackages__", - "//location/nearby/cpp/experiments:__subpackages__", - "//location/nearby/sharing/lib:__subpackages__", - "//sharing:__subpackages__", - ], - deps = [ - "//internal/proto/analytics:connections_log_cc_proto", - "//sharing/proto/analytics:sharing_log_cc_proto", - ], -) - -cc_library( - name = "mock_event_logger", - testonly = True, - hdrs = [ - "mock_event_logger.h", - "sharing_log_matchers.h", - ], - compatible_with = ["//buildenv/target:non_prod"], - visibility = ["//visibility:public"], - deps = [ - ":event_logger", - "@com_google_googletest//:gtest_for_library_testonly", - "@com_google_protobuf//:protobuf_lite", - ], -) diff --git a/internal/analytics/event_logger.h b/internal/analytics/event_logger.h deleted file mode 100644 index b360c659..00000000 --- a/internal/analytics/event_logger.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2022 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 NEARBY_ANALYTICS_EVENT_LOGGER_H_ -#define NEARBY_ANALYTICS_EVENT_LOGGER_H_ - -#include "internal/proto/analytics/connections_log.pb.h" -#include "sharing/proto/analytics/nearby_sharing_log.pb.h" - -namespace nearby { -namespace analytics { - -// Allows callers to log the proto collected at the client (e.g. Nearby -// Connections, Nearby Sharing, etc). Callers need to implement the API -// if they want to collect this log. -class EventLogger { - public: - virtual ~EventLogger() = default; - - // Logs the proto details. Might block to do I/O, e.g. upload - // synchronously to some metrics server. - virtual void Log( - const location::nearby::analytics::proto::ConnectionsLog& message) = 0; - virtual void Log(const sharing::analytics::proto::SharingLog& message) = 0; -}; - -} // namespace analytics -} // namespace nearby - -#endif // NEARBY_ANALYTICS_EVENT_LOGGER_H_ diff --git a/internal/analytics/mock_event_logger.h b/internal/analytics/mock_event_logger.h deleted file mode 100644 index 2a6b5774..00000000 --- a/internal/analytics/mock_event_logger.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2024 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_ANALYTICS_MOCK_EVENT_LOGGER_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_ANALYTICS_MOCK_EVENT_LOGGER_H_ - -#include "gmock/gmock.h" -#include "internal/analytics/event_logger.h" - -namespace nearby::analytics { - -class MockEventLogger : public ::nearby::analytics::EventLogger { - public: - MockEventLogger() = default; - ~MockEventLogger() override = default; - - MOCK_METHOD( - void, Log, - (const location::nearby::analytics::proto::ConnectionsLog& message), - (override)); - MOCK_METHOD(void, Log, (const sharing::analytics::proto::SharingLog& message), - (override)); -}; - -} // namespace nearby::analytics - -#endif // THIRD_PARTY_NEARBY_INTERNAL_ANALYTICS_MOCK_EVENT_LOGGER_H_ diff --git a/internal/analytics/sharing_log_matchers.h b/internal/analytics/sharing_log_matchers.h deleted file mode 100644 index ce01eb84..00000000 --- a/internal/analytics/sharing_log_matchers.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2024 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_ANALYTICS_SHARING_LOG_MATCHERS_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_ANALYTICS_SHARING_LOG_MATCHERS_H_ - -#include "gmock/gmock.h" - -namespace nearby::analytics { - -MATCHER_P(HasCategory, category, "has category") { - return arg.event_category() == category; -} - -MATCHER_P(HasEventType, event_type, "has event type") { - return arg.event_type() == event_type; -} - -MATCHER_P(HasAction, action, "has action") { - return arg.action() == action; -} - -MATCHER_P(HasSessionId, session_id, "has session id") { - return arg.session_id() == session_id; -} - -MATCHER_P(HasDurationMillis, duration_millis, "has duration millis") { - return arg.duration_millis() == duration_millis; -} - -MATCHER_P(SharingLogHasStatus, status, "has status") { - return arg.status() == status; -} - -MATCHER_P(HasRpcName, rpc_name, "has rpc_name") { - return arg.rpc_name() == rpc_name; -} - -MATCHER_P(HasDirection, direction, "has direction") { - return arg.direction() == direction; -} - -MATCHER_P(HasErrorCode, error_code, "has error_code") { - return arg.error_code() == error_code; -} - -MATCHER_P(HasLatencyMillis, latency_millis, "has latency_millis") { - return arg.latency_millis() == latency_millis; -} - -} // namespace nearby::analytics - -#endif // THIRD_PARTY_NEARBY_INTERNAL_ANALYTICS_SHARING_LOG_MATCHERS_H_ diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 22a42037..94a03367 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -182,6 +182,8 @@ cc_library( tags = ["keep_dep"], # Prevent build_cleaner from removing the dependency. visibility = [ "//:__subpackages__", + "//location/nearby/analytics/cpp:__subpackages__", + "//location/nearby/cpp:__subpackages__", "//location/nearby/sharing/lib:__subpackages__", ], deps = [ diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index ef0c9b3f..6fb81f20 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -196,7 +196,6 @@ cc_library( "//internal/preferences:__subpackages__", "//internal/proto/analytics:__subpackages__", "//internal/weave:__subpackages__", - "//location/nearby/cpp:__subpackages__", "//location/nearby/sharing/sdk:__subpackages__", "//sharing:__subpackages__", "//third_party/nearby/presence:__subpackages__", diff --git a/internal/proto/analytics/BUILD b/internal/proto/analytics/BUILD index 352db000..f4beb852 100644 --- a/internal/proto/analytics/BUILD +++ b/internal/proto/analytics/BUILD @@ -13,7 +13,9 @@ # limitations under the License. load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library") +load("@com_google_protobuf//bazel:java_lite_proto_library.bzl", "java_lite_proto_library") load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") +load("@com_google_protobuf//rust:defs.bzl", "rust_proto_library") load("@rules_cc//cc:cc_test.bzl", "cc_test") licenses(["notice"]) @@ -25,14 +27,17 @@ proto_library( srcs = [ "connections_log.proto", ], + compatible_with = ["//buildenv/target:non_prod"], deps = [ "//proto:connections_enums_proto", "//proto/errorcode:error_code_enums_proto", + "//storage/datapol/annotations/proto:datapol_annotations", ], ) cc_proto_library( name = "connections_log_cc_proto", + compatible_with = ["//buildenv/target:non_prod"], visibility = [ "//connections:__subpackages__", "//internal/analytics:__pkg__", @@ -52,9 +57,20 @@ cc_test( ":connections_log_cc_proto", "//internal/platform:logging", "//internal/platform/implementation/g3", # build_cleaner: keep + "//logs/proto/location/nearby:nearby_client_log_cc_proto", "//proto:connections_enums_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_googletest//:gtest_main", "@com_google_protobuf//:protobuf", ], ) + +rust_proto_library( + name = "connections_log_rust_proto", + deps = [":connections_log_proto"], +) + +java_lite_proto_library( + name = "connections_log_java_proto_lite", + deps = [":connections_log_proto"], +) diff --git a/sharing/BUILD b/sharing/BUILD index 5020ce68..8ab13f26 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -390,7 +390,6 @@ cc_library( "//connections:core_types", "//connections/implementation:internal", "//connections/implementation/analytics:analytics_recorder_impl", - "//internal/analytics:event_logger", "//internal/base", "//internal/base:file_path", "//internal/flags:nearby_flags", @@ -401,6 +400,7 @@ cc_library( "//internal/platform:mac_address", "//internal/platform:types", "//internal/platform/implementation:types", + "//location/nearby/analytics/cpp/logging:event_logger", "//location/nearby/sharing/lib/account:account_manager", "//location/nearby/sharing/lib/rpc:grpc_async_client_factory", "//location/nearby/sharing/lib/rpc:sharing_rpc_client", @@ -653,12 +653,12 @@ cc_test( ":transfer_metadata", ":transfer_metadata_matchers", ":types", - "//internal/analytics:mock_event_logger", "//internal/base:file_path", "//internal/base:files", "//internal/flags:nearby_flags", "//internal/platform/implementation:platform_impl", "//internal/test", + "//location/nearby/analytics/cpp/logging:mock_event_logger", "//location/nearby/sharing/lib/account:fake_account_manager", "//location/nearby/sharing/lib/account:mock_account_manager", "//location/nearby/sharing/lib/account:signin_attempt", @@ -873,9 +873,9 @@ cc_test( ":transfer_metadata", ":transfer_metadata_matchers", ":types", - "//internal/analytics:mock_event_logger", "//internal/platform/implementation:platform_impl", "//internal/test", + "//location/nearby/analytics/cpp/logging:mock_event_logger", "//location/nearby/sharing/lib/analytics", "//sharing/certificates:test_support", "@com_github_protobuf_matchers//protobuf-matchers", @@ -924,12 +924,12 @@ cc_test( ":transfer_metadata", ":transfer_metadata_matchers", ":types", - "//internal/analytics:mock_event_logger", "//internal/base:file_path", "//internal/base:files", "//internal/network:url", "//internal/platform/implementation:platform_impl", "//internal/test", + "//location/nearby/analytics/cpp/logging:mock_event_logger", "//location/nearby/sharing/lib/analytics", "//net/proto2/contrib/parse_proto:parse_text_proto", "//sharing/certificates:test_support", @@ -957,10 +957,10 @@ cc_test( ":transfer_metadata", ":transfer_metadata_matchers", ":types", - "//internal/analytics:mock_event_logger", "//internal/base:file_path", "//internal/platform/implementation:platform_impl", "//internal/test", + "//location/nearby/analytics/cpp/logging:mock_event_logger", "//location/nearby/sharing/lib/analytics", "//proto:sharing_enums_cc_proto", "//sharing/internal/public:logging", diff --git a/sharing/incoming_share_session_test.cc b/sharing/incoming_share_session_test.cc index f90be90a..fe19813e 100644 --- a/sharing/incoming_share_session_test.cc +++ b/sharing/incoming_share_session_test.cc @@ -24,14 +24,14 @@ #include #include +#include "location/nearby/analytics/cpp/logging/mock_event_logger.h" +#include "location/nearby/analytics/cpp/logging/sharing_log_matchers.h" #include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" -#include "internal/analytics/mock_event_logger.h" -#include "internal/analytics/sharing_log_matchers.h" #include "internal/base/file_path.h" #include "internal/test/fake_clock.h" #include "internal/test/fake_device_info.h" diff --git a/sharing/nearby_connections_manager_factory.cc b/sharing/nearby_connections_manager_factory.cc index 9f0d40e3..cba3ccbd 100644 --- a/sharing/nearby_connections_manager_factory.cc +++ b/sharing/nearby_connections_manager_factory.cc @@ -16,7 +16,7 @@ #include -#include "internal/analytics/event_logger.h" +#include "location/nearby/analytics/cpp/logging/event_logger.h" #include "internal/platform/implementation/device_info.h" #include "internal/platform/task_runner.h" #include "sharing/internal/public/context.h" diff --git a/sharing/nearby_connections_manager_factory.h b/sharing/nearby_connections_manager_factory.h index bb45b9c7..f856a140 100644 --- a/sharing/nearby_connections_manager_factory.h +++ b/sharing/nearby_connections_manager_factory.h @@ -17,7 +17,7 @@ #include -#include "internal/analytics/event_logger.h" +#include "location/nearby/analytics/cpp/logging/event_logger.h" #include "internal/platform/implementation/device_info.h" #include "internal/platform/task_runner.h" #include "sharing/internal/public/context.h" diff --git a/sharing/nearby_connections_service_impl.cc b/sharing/nearby_connections_service_impl.cc index 51d235fc..42a8ba75 100644 --- a/sharing/nearby_connections_service_impl.cc +++ b/sharing/nearby_connections_service_impl.cc @@ -23,6 +23,7 @@ #include #include +#include "location/nearby/analytics/cpp/logging/event_logger.h" #include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" @@ -40,7 +41,6 @@ #include "connections/payload_type.h" #include "connections/status.h" #include "connections/strategy.h" -#include "internal/analytics/event_logger.h" #include "internal/platform/byte_array.h" #include "internal/platform/logging.h" #include "internal/platform/mac_address.h" diff --git a/sharing/nearby_connections_service_impl.h b/sharing/nearby_connections_service_impl.h index cdcfcf30..76d34891 100644 --- a/sharing/nearby_connections_service_impl.h +++ b/sharing/nearby_connections_service_impl.h @@ -22,10 +22,10 @@ #include #include +#include "location/nearby/analytics/cpp/logging/event_logger.h" #include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" #include "absl/types/span.h" -#include "internal/analytics/event_logger.h" #include "sharing/internal/public/connectivity_manager.h" #include "sharing/nearby_connections_service.h" #include "sharing/nearby_connections_types.h" diff --git a/sharing/nearby_sharing_service_factory.cc b/sharing/nearby_sharing_service_factory.cc index 06ef08b3..3bbb801c 100644 --- a/sharing/nearby_sharing_service_factory.cc +++ b/sharing/nearby_sharing_service_factory.cc @@ -17,8 +17,8 @@ #include #include +#include "location/nearby/analytics/cpp/logging/event_logger.h" #include "location/nearby/sharing/lib/rpc/grpc_async_client_factory.h" -#include "internal/analytics/event_logger.h" #include "internal/platform/task_runner.h" #include "sharing/analytics/analytics_recorder.h" #include "sharing/internal/api/sharing_platform.h" diff --git a/sharing/nearby_sharing_service_factory.h b/sharing/nearby_sharing_service_factory.h index 6370de1d..100221cf 100644 --- a/sharing/nearby_sharing_service_factory.h +++ b/sharing/nearby_sharing_service_factory.h @@ -17,9 +17,9 @@ #include +#include "location/nearby/analytics/cpp/logging/event_logger.h" #include "location/nearby/sharing/lib/rpc/grpc_async_client_factory.h" #include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h" -#include "internal/analytics/event_logger.h" #include "sharing/analytics/analytics_recorder.h" #include "sharing/internal/api/sharing_platform.h" #include "sharing/internal/public/context.h" diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index 20bd479d..491a56ef 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -30,6 +30,7 @@ #include #include +#include "location/nearby/analytics/cpp/logging/mock_event_logger.h" #include "location/nearby/sharing/lib/account/fake_account_manager.h" #include "location/nearby/sharing/lib/account/mock_account_observer.h" #include "location/nearby/sharing/lib/account/signin_attempt.h" @@ -48,7 +49,6 @@ #include "absl/time/clock.h" #include "absl/time/time.h" #include "absl/types/span.h" -#include "internal/analytics/mock_event_logger.h" #include "internal/base/file_path.h" #include "internal/base/files.h" #include "internal/flags/nearby_flags.h" diff --git a/sharing/outgoing_share_session_test.cc b/sharing/outgoing_share_session_test.cc index 6aed6372..f314a90e 100644 --- a/sharing/outgoing_share_session_test.cc +++ b/sharing/outgoing_share_session_test.cc @@ -22,6 +22,8 @@ #include #include +#include "location/nearby/analytics/cpp/logging/mock_event_logger.h" +#include "location/nearby/analytics/cpp/logging/sharing_log_matchers.h" #include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" #include "net/proto2/contrib/parse_proto/parse_text_proto.h" #include "gmock/gmock.h" @@ -29,8 +31,6 @@ #include "gtest/gtest.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" -#include "internal/analytics/mock_event_logger.h" -#include "internal/analytics/sharing_log_matchers.h" #include "internal/base/file_path.h" #include "internal/base/files.h" #include "internal/network/url.h" diff --git a/sharing/share_session_test.cc b/sharing/share_session_test.cc index d82b8c14..98a969fb 100644 --- a/sharing/share_session_test.cc +++ b/sharing/share_session_test.cc @@ -21,6 +21,7 @@ #include #include +#include "location/nearby/analytics/cpp/logging/mock_event_logger.h" #include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" @@ -29,7 +30,6 @@ #include "absl/synchronization/notification.h" #include "absl/time/clock.h" #include "absl/time/time.h" -#include "internal/analytics/mock_event_logger.h" #include "internal/test/fake_clock.h" #include "internal/test/fake_device_info.h" #include "internal/test/fake_task_runner.h" From 28b1118c5306f7c165797c46c6ba76a726534c19 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 1 Jun 2026 22:32:22 -0700 Subject: [PATCH 132/151] Remove ConnectionsLog proto. PiperOrigin-RevId: 925117791 --- internal/proto/analytics/BUILD | 76 -- .../proto/analytics/connections_log.proto | 752 ------------------ .../proto/analytics/connections_log_test.cc | 124 --- 3 files changed, 952 deletions(-) delete mode 100644 internal/proto/analytics/BUILD delete mode 100644 internal/proto/analytics/connections_log.proto delete mode 100644 internal/proto/analytics/connections_log_test.cc diff --git a/internal/proto/analytics/BUILD b/internal/proto/analytics/BUILD deleted file mode 100644 index f4beb852..00000000 --- a/internal/proto/analytics/BUILD +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2020 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. - -load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library") -load("@com_google_protobuf//bazel:java_lite_proto_library.bzl", "java_lite_proto_library") -load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") -load("@com_google_protobuf//rust:defs.bzl", "rust_proto_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -licenses(["notice"]) - -package(default_visibility = ["//visibility:public"]) - -proto_library( - name = "connections_log_proto", - srcs = [ - "connections_log.proto", - ], - compatible_with = ["//buildenv/target:non_prod"], - deps = [ - "//proto:connections_enums_proto", - "//proto/errorcode:error_code_enums_proto", - "//storage/datapol/annotations/proto:datapol_annotations", - ], -) - -cc_proto_library( - name = "connections_log_cc_proto", - compatible_with = ["//buildenv/target:non_prod"], - visibility = [ - "//connections:__subpackages__", - "//internal/analytics:__pkg__", - "//location/nearby/analytics/cpp:__subpackages__", - ], - deps = [":connections_log_proto"], -) - -cc_test( - name = "proto_analytics_test", - size = "small", - srcs = [ - "connections_log_test.cc", - ], - shard_count = 16, - deps = [ - ":connections_log_cc_proto", - "//internal/platform:logging", - "//internal/platform/implementation/g3", # build_cleaner: keep - "//logs/proto/location/nearby:nearby_client_log_cc_proto", - "//proto:connections_enums_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - "@com_google_protobuf//:protobuf", - ], -) - -rust_proto_library( - name = "connections_log_rust_proto", - deps = [":connections_log_proto"], -) - -java_lite_proto_library( - name = "connections_log_java_proto_lite", - deps = [":connections_log_proto"], -) diff --git a/internal/proto/analytics/connections_log.proto b/internal/proto/analytics/connections_log.proto deleted file mode 100644 index 8da414dc..00000000 --- a/internal/proto/analytics/connections_log.proto +++ /dev/null @@ -1,752 +0,0 @@ -// Copyright 2020 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. - -syntax = "proto2"; - -package location.nearby.analytics.proto; - -// import "storage/datapol/annotations/proto/semantic_annotations.proto"; -import "proto/connections_enums.proto"; -import "proto/errorcode/error_code_enums.proto"; - -option optimize_for = LITE_RUNTIME; -option java_package = "com.google.location.nearby.analytics.proto"; -option java_outer_classname = "ConnectionsLogProto"; -option objc_class_prefix = "GNCP"; - -// Top-level log proto for Nearby Connections. -// LINT.IfChange(ConnectionsLog) -// Next Tag: 7 -message ConnectionsLog { - // The type of this log. - optional location.nearby.proto.connections.EventType event_type = 1; - - // Non-null for EventType.CLIENT_SESSION. - // Encapsulates all client activity between connecting to and disconnecting - // from the Nearby Connections API via Client. - optional ClientSession client_session = 2; - - // The version of Nearby Connections. E.g. "v1.0.4". - optional string version = 3 /* type = ST_SOFTWARE_ID */; - - // For EventType.ERROR_CODE - optional ErrorCode error_code = 4; - - // Indicates the source of the log. - optional location.nearby.proto.connections.LogSource log_source = 5; - - // This is a temporary logging field for FilesGo migration phase based on - // device geolocation. Example values are "P1", "P2", "PA" etc. - // In files migration, we have different phases to rollout Files-> Nearby - // migration on different list of countries. For example, at phase A (PA), - // the migration happens in Asian countries; P1 for Europe countries; P2 - // for North and South Americas. - // Reference: http://shortn/_9smZZ8CTD6, http://shortn/_Y08gVwZRKc - optional string files_migration_phase = 6; - - // Encapsulates one session of a client connected to Nearby Connections API. - message ClientSession { - // Elapsed time in milliseconds between Client connect and - // disconnect. - optional int64 duration_millis = 1; - - // Zero or more StrategySessions. - repeated StrategySession strategy_session = 2; - - // The client session flow id. - optional int64 client_flow_id = 3 /* type = ST_SESSION_ID */; - - // All the connection tokens used in this client session. - optional string connection_token = 4 - /* type = ST_SESSION_ID */; - - reserved 5; // device type isdeprecated and moved to StrategySession - } - - message OperationResult { - // The category of the operation result - optional location.nearby.proto.connections.OperationResultCategory - result_category = 1; - - // The result code of the operation result - optional location.nearby.proto.connections.OperationResultCode result_code = - 2; - } - - message OperationResultWithMedium { - optional location.nearby.proto.connections.Medium medium = 1; - - // Indicate which mediums belong to the same update API Call. - optional int32 update_index = 2; - - // The category of the operation result - optional location.nearby.proto.connections.OperationResultCategory - result_category = 3; - - // The result code of the operation result - optional location.nearby.proto.connections.OperationResultCode result_code = - 4; - - // The connection mode. - optional location.nearby.proto.connections.ConnectionMode connection_mode = - 5; - } - - // One round of a particular Strategy done by a client. - message StrategySession { - // Elapsed time in milliseconds between a call to startAdvertising/Discovery - // and the end of this particular Strategy. A StrategySession may end due to - // - the client disconnecting from Client; - // - a call to stopAllEndpoints, which disconnects all endpoints and - // stops any advertising/discovery; - // - a new call to startAdvertising/Discovery. - optional int64 duration_millis = 1; - - // The Strategy used for this session. - optional location.nearby.proto.connections.ConnectionsStrategy strategy = 2; - - // The role(s) played by this device during this StrategySession. - repeated location.nearby.proto.connections.SessionRole role = 3; - - // One or more of the following *Phase is present, depending on the role(s). - - // Encapsulates discovery information. - repeated DiscoveryPhase discovery_phase = 4; - // Encapsulates advertising information. - repeated AdvertisingPhase advertising_phase = 5; - - // Attempts at establishing a connection to another device. - repeated ConnectionAttempt connection_attempt = 6; - - // Successful and accepted connections to another device. - repeated EstablishedConnection established_connection = 7; - - // Attempts to upgrade a connection from one medium to another. - repeated BandwidthUpgradeAttempt upgrade_attempt = 9; - - // The build version of the user's device (Same value as the Build number in - // Settings -> about phone). - optional string build_version = 10 - /* type = ST_SOFTWARE_ID */; - } - - // Encapsulates activity during a period of discovery. - message DiscoveryPhase { - // Elapsed time in milliseconds between startDiscovery and stopDiscovery. - optional int64 duration_millis = 1; - - // The Medium(s) used for discovery. - repeated location.nearby.proto.connections.Medium medium = 2; - - // Discovered endpoints during this round of discovery. - repeated DiscoveredEndpoint discovered_endpoint = 3; - - // Attempted ConnectionRequests (requested by the client). They may or - // may not reach the other endpoint. - repeated ConnectionRequest sent_connection_request = 4; - - // UWB ranging related data during discovery (May range with multiple - // endpoints) - repeated UwbRangingProcess uwb_ranging = 5; - - // The SendingEvent flow id. - optional int64 client_flow_id = 6 /* type = ST_SESSION_ID */; - - // Encapsulates additional discovery information. - optional DiscoveryMetadata discovery_metadata = 7; - - // Collect the discovery results of the mediums - repeated OperationResultWithMedium adv_dis_result = 8; - - // The readon of stopping discoverying - optional location.nearby.proto.connections.StopDiscoveringReason - stop_reason = 9; - - // The type of the device. - optional location.nearby.proto.connections.DeviceType device_type = 10; - - // The supported service. - optional location.nearby.proto.connections.SupportedService - supported_service = 11; - } - - // An endpoint discovered on a particular medium during discovery. - message DiscoveredEndpoint { - // The medium on which this endpoint was discovered. - optional location.nearby.proto.connections.Medium medium = 1; - - // Elapsed time between the call to startDiscovery() and the time at which - // this endpoint was discovered. - optional int64 latency_millis = 2; - } - - // Encapsulates activity during UWB ranging. - message UwbRangingProcess { - // Elapsed time in milliseconds between startRanging and stopRanging. - optional int64 duration_millis = 1; - - // UWB raw ranging data received during discovery. This is optional. Only - // certain devices (Debug/Testing etc.) will log the raw data. - repeated RawUwbRangingEvent uwb_ranging_data = 2; - - // Number of ranging data received - optional int32 number_of_ranging_data = 3; - - // The minimum distance during a UWB ranging session - optional int32 distance_min = 4; - - // The maximum distance during a UWB ranging session - optional int32 distance_max = 5; - - // The average distance during a UWB ranging session - optional int32 distance_ave = 6; - - // The distance variance during a UWB ranging session - optional int32 distance_variance = 7; - - // The minimum AoA during a UWB ranging session - optional int32 azimuth_min = 8; - - // The maximum AoA during a UWB ranging session - optional int32 azimuth_max = 9; - - // The average AoA during a UWB ranging session - optional int32 azimuth_ave = 10; - - // The AoA variance during a UWB ranging session - optional int32 azimuth_variance = 11; - } - - // Ranging data received during discovery phase. - message RawUwbRangingEvent { - // Distance in cm - optional int32 distance = 1; - - // Azimuth angle in degree - optional int32 azimuth_angle = 2; - - // Polar angle in degree (0 if the device doesn't support it) - optional int32 polar_angle = 3; - } - - // Encapsulates activity during a period of advertising. - message AdvertisingPhase { - // Elapsed time in milliseconds between startAdvertising and - // stopAdvertising. - optional int64 duration_millis = 1; - - // The Medium(s) used for advertising. - repeated location.nearby.proto.connections.Medium medium = 2; - - // Received ConnectionRequests from remote endpoints. - repeated ConnectionRequest received_connection_request = 3; - - // The ReceivingEvent flow id. - optional int64 client_flow_id = 4 /* type = ST_SESSION_ID */; - - // Encapsulates additional advertising information. - optional AdvertisingMetadata advertising_metadata = 5; - - // Collect the discovery results of the mediums - repeated OperationResultWithMedium adv_dis_result = 6; - - // The readon of stopping advertising - optional location.nearby.proto.connections.StopAdvertisingReason - stop_reason = 7; - - // The type of the device. - optional location.nearby.proto.connections.DeviceType device_type = 8; - - // The supported service. - optional location.nearby.proto.connections.SupportedService - supported_service = 9; - } - - // A request to connect, corresponding to the API's concept of - // request/accept/rejectConnection(). - message ConnectionRequest { - // Elapsed time in milliseconds between the connection request being - // initiated and the responses being received. - optional int64 duration_millis = 1; - - // Elapsed time in milliseconds between the start of the containing - // Advertising/DiscoveryPhase and the start of this ConnectionRequest, i.e. - // the time at which the request is sent (on the discoverer, at the request - // of the client) or received (on the advertiser, over the wire from the - // remote endpoint). - optional int64 request_delay_millis = 2; - - // The local endpoint's response to this connection request. - optional location.nearby.proto.connections.ConnectionRequestResponse - local_response = 3; - - // The remote endpoint's response to this connection request. - optional location.nearby.proto.connections.ConnectionRequestResponse - remote_response = 4; - - // The SendingEvent flow id. - optional int64 client_flow_id = 5 /* type = ST_SESSION_ID */; - } - - // An attempt to connect to an endpoint over a particular medium. - message ConnectionAttempt { - // Elapsed time in milliseconds between starting the connection attempt - // and succeeding/failing. - optional int64 duration_millis = 1; - - // The type of connection attempt. - optional location.nearby.proto.connections.ConnectionAttemptType type = 2; - - // The direction (incoming vs outgoing) of this attempt. - optional location.nearby.proto.connections.ConnectionAttemptDirection - direction = 3; - - // The Medium of this connection attempt. - optional location.nearby.proto.connections.Medium medium = 4; - - // The result of the connection attempt. - optional location.nearby.proto.connections.ConnectionAttemptResult - attempt_result = 5; - - // The ReceivingEvent flow id. - optional int64 client_flow_id = 6 /* type = ST_SESSION_ID */; - - // The token used to identify this connection pair. - optional string connection_token = 7 - /* type = ST_SESSION_ID */; - - // Encapsulates additional connection information. - optional ConnectionAttemptMetadata connection_attempt_metadata = 8; - - // The result code of this connection attempt - optional OperationResult operation_result = 9; - - // The connection mode. - optional location.nearby.proto.connections.ConnectionMode connection_mode = - 10; - - // The type of the device. - optional location.nearby.proto.connections.DeviceType device_type = 11; - - // The supported service. - optional location.nearby.proto.connections.SupportedService - supported_service = 12; - - // The latency of the wifi connection in milliseconds, starting from when - // the wifi credentials are received from the remote device, to the moment - // wifi connection is established with internet access. - optional int64 wifi_connection_latency_millis = 13; - - // The latency of the device attestation in milliseconds, starting from when - // the device attestation is initiated, to the moment the device attestation - // is finished. - optional int64 device_attestation_latency_millis = 14; - - // The error code returned by Play Integrity API during device attestation. - optional int64 play_integrity_error_code = 15; - - // If this connection is forced over USB. - optional bool is_forced_usb = 16; - } - - message DeviceInfo { - enum Platform { - UNKNOWN = 0; - ANDROID = 1; - IOS = 2; - CROS = 3; - WINDOWS = 4; - } - optional string device_model = 1; - optional Platform device_platform = 2; - optional string country_code = 3; - optional string manufacturer = 4; - } - - message DisconnectionReasonDetail { - enum DisconnectionReason { - UNKNOWN_DISCONNECTION_REASON = 0; - DCT_ERROR_MDNS_DISCOVERY_TIMEOUT = 1; - DCT_ERROR_MDNS_REGISTER_SERVICE = 2; - DCT_ERROR_SUBSEQUENT_TLS_SPAKE = 3; - DCT_ERROR_REQUEST_FAILED = 4; - DCT_ERROR_RESPONSE_FAILED = 5; - DCT_ERROR_CONTROL_MESSAGE_EXCHANGE = 6; - DCT_ERROR_CAPABILITY_MISMATCH = 7; - DCT_ERROR_HIGH_SPEED_MEDIUM_UNAVAILABLE = 8; - DCT_ERROR_WIFI_DISABLED = 9; - DCT_ERROR_WIFI_DISCONNECTED = 10; - DCT_ERROR_WIFI_CREDENTIAL_TRANSFER = 11; - DCT_ERROR_WIFI_INTERNET_CONNECTION = 12; - DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED = 13; - DCT_ERROR_USER_CANCELLED = 14; - DCT_ERROR_SERVICE_CANCELLED = 15; - DCT_ERROR_UNVERIFIED_INTEGRITY = 16; - SESSION_SUCCESS = 17; - } - optional bool is_local_disconnection = 1; - optional DisconnectionReason disconnection_reason = 2; - } - - // A successfully-established connection over a particular medium. - message EstablishedConnection { - enum SafeDisconnectionResult { - UNKNOWN_SAFE_DISCONNECTION_RESULT = 0; - SAFE_DISCONNECTION = 1; - UNSAFE_DISCONNECTION = 2; - } - - // Elapsed time in milliseconds that the connection is active. - optional int64 duration_millis = 1; - - // The Medium of this connection. - optional location.nearby.proto.connections.Medium medium = 2; - - // Payloads sent over this connection. - repeated Payload sent_payload = 3; - - // Payloads received over this connection. - repeated Payload received_payload = 4; - - // The reason this connection was disconnected. - optional location.nearby.proto.connections.DisconnectionReason - disconnection_reason = 5; - - // The SendingEvent flow id. - optional int64 client_flow_id = 6 /* type = ST_SESSION_ID */; - - // The token use to identify this established connection. - optional string connection_token = 7 - /* type = ST_SESSION_ID */; - - // The type of established connection. - optional location.nearby.proto.connections.ConnectionAttemptType type = 8; - - // If this is a safe disconnection. - optional SafeDisconnectionResult safe_disconnection_result = 9; - - // The result code of this established connection - optional OperationResult operation_result = 10; - - // The remote device info - optional DeviceInfo remote_device_info = 11; - - // The disconnection reason details - optional DisconnectionReasonDetail disconnection_reason_detail = 12; - - // The type of the device. - optional location.nearby.proto.connections.DeviceType device_type = 13; - - // The supported service. - optional location.nearby.proto.connections.SupportedService - supported_service = 14; - - // The speed test report. - optional SpeedTestReport speed_test_report = 15; - - // The count of long inactivity events without any payload transfer. - optional int32 inactivity_count = 16; - - // The RSSI (radio signal strength indicator) in dBm. - // INTERNET_RSSI_UNKNOWN (-127) if unknown. - optional int32 rssi = 17; - - // If this connection is forced over USB. - optional bool is_forced_usb = 18; - } - - message SpeedTestReport { - // The throughput in kbytes per second. - optional int32 throughput_kbytes_per_sec = 1; - - // Whether the throughput is incoming or outgoing. - optional bool is_incoming = 2; - } - - // Contains the transfer statistics for a DCT payload. - message DctPayloadTransferStats { - // The type of the DCT payload. - // Note: For legacy payloads, the type is logged in the Payload message - // instead. - optional location.nearby.proto.connections.DctPayloadType type = 1; - - // Indicates whether the payload was sent using the multipart protocol. - // True if multipart was used, false otherwise. - optional bool is_multipart = 2; - - // The number of parts that were successfully transferred. - // This field is only meaningful when is_multipart is true. - // The counting method differs for outgoing and incoming multipart payloads: - // - OUTGOING: All parts associated with the same request are treated as one - // payload. This field increments by 1 if the payload transfers - // successfully. - // - INCOMING: Each part of the incoming multipart payload is logged - // individually. This field increments for each successfully received - // part. - optional int32 num_parts_success = 3; - - // The number of parts that failed to transfer. - // This field is only meaningful when is_multipart is true. - // The counting method differs for outgoing and incoming multipart payloads: - // - OUTGOING: All parts associated with the same request are treated as one - // payload. This field increments by 1 if the payload fails to transfer. - // - INCOMING: Each part of the incoming multipart payload is logged - // individually. This field increments for each part that fails to be - // received. - optional int32 num_parts_failure = 4; - - // True if this payload transfer is an attempt to resume an interrupted - // payload after a reconnection. False if it's a new payload transfer. - optional bool is_resumption = 5; - - // The data speed report in kbyte per second using global bytes counter - optional int32 data_speed_report_kbyte_per_sec = 6; - } - - // A Payload transferred (or attempted to be transferred) between devices. - message Payload { - // Elapsed time in milliseconds that num_bytes_transferred took to transfer. - optional int64 duration_millis = 1; - - // The type of this payload. - optional location.nearby.proto.connections.PayloadType type = 2; - - // Total size of the payload in bytes. - optional int64 total_size_bytes = 3; - - // Total number of bytes transferred successfully. - optional int64 num_bytes_transferred = 4; - - // The number of chunks used to transfer num_bytes_transferred. - optional int32 num_chunks = 5; - - // The end status of the payload transfer. - optional location.nearby.proto.connections.PayloadStatus status = 6; - - // The number of successful auto resume. - optional int32 num_successful_auto_resume = 7; - - // The result code of this sent payload - optional OperationResult operation_result = 8; - - // The number of failed auto resume attempts. - optional int32 num_failed_auto_resume = 9; - - // Statistics for DCT payloads, e.g., type, multipart details. Populated - // only for DCT payloads. - optional DctPayloadTransferStats dct_payload_transfer_stats = 10; - } - - // An attempt to upgrade an existing connection from one medium to another. - message BandwidthUpgradeAttempt { - // The direction (incoming vs outgoing) of the upgrade attempt. - optional location.nearby.proto.connections.ConnectionAttemptDirection - direction = 1; - - // Elapsed time in milliseconds of the upgrade attempt. - optional int64 duration_millis = 2; - - // The original medium (e.g. bluetooth). - optional location.nearby.proto.connections.Medium from_medium = 3; - - // The new medium that we're hoping to upgrade to (e.g. wifi). - optional location.nearby.proto.connections.Medium to_medium = 4; - - // The result of the upgrade attempt. - optional location.nearby.proto.connections.BandwidthUpgradeResult - upgrade_result = 5; - - // If upgrade_result is not success, the stage at which the error occurred. - optional location.nearby.proto.connections.BandwidthUpgradeErrorStage - error_stage = 6; - - // The SendingEvent flow id. - optional int64 client_flow_id = 7 /* type = ST_SESSION_ID */; - - // The token used to identify this upgrade pair. - optional string connection_token = 8 - /* type = ST_SESSION_ID */; - - // The result code of this upgrade attempt - optional OperationResult operation_result = 9; - - optional location.nearby.proto.connections.DeviceType device_type = 10; - - // 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; - // The number of times the upgrade attempt is tried. - // This count is reset to 0 when the upgrade is successful. - optional int32 try_count = 14; - // If true, the upgrade attempt is forced to use the USB medium, regardless - // of the available mediums. - optional bool is_forced_usb = 15; - } - - // Next Id: 22 - message ErrorCode { - // The direction (incoming vs outgoing) of this error. - optional location.nearby.proto.connections.ConnectionAttemptDirection - direction = 1; - optional string service_id = 2; - // The error medium (e.g. bluetooth). - optional location.nearby.proto.connections.Medium medium = 3; - // The event which the error occurs on. - optional location.nearby.errorcode.proto.Event event = 4; - // The error description. - optional location.nearby.errorcode.proto.Description description = 5; - // The flow id which the error occurs on. - optional int64 flow_id = 6 /* type = ST_SESSION_ID */; - - // Error code value - oneof ErrorCodeDetail { - location.nearby.errorcode.proto.CommonError common_error = 7; - location.nearby.errorcode.proto.StartAdvertisingError - start_advertising_error = 8; - location.nearby.errorcode.proto.StartDiscoveringError - start_discovering_error = 9; - location.nearby.errorcode.proto.StopAdvertisingError - stop_advertising_error = 10; - location.nearby.errorcode.proto.StopDiscoveringError - stop_discovering_error = 11; - location.nearby.errorcode.proto.StartListeningIncomingConnectionError - start_listening_incoming_connection_error = 12; - location.nearby.errorcode.proto.StopListeningIncomingConnectionError - stop_listening_incoming_connection_error = 13; - location.nearby.errorcode.proto.ConnectError connect_error = 14; - location.nearby.errorcode.proto.DisconnectError disconnect_error = 15; - location.nearby.errorcode.proto.SendPayloadError send_payload_error = 17; - location.nearby.errorcode.proto.ReceivePayloadError - receive_payload_error = 18; - location.nearby.errorcode.proto.UpgradeError upgrade_error = 19; - location.nearby.errorcode.proto.AcceptConnectionError - accept_connection_error = 20; - location.nearby.errorcode.proto.RejectConnectionError - reject_connection_error = 21; - } - - // The token use to identify this established connection. - optional string connection_token = 16 - /* type = ST_SESSION_ID */; - } - - // Some additional information to keep with the advertising phase. - message AdvertisingMetadata { - // The bluetooth low energy extended advertisement support status. - optional bool supports_extended_ble_advertisements = 1; - - // The frequency of the connected WiFi AP. - optional int32 connected_ap_frequency = 2; - - // The NFC (Near Field Communication) support status - optional bool supports_nfc_technology = 3; - - // The Bluetooth multiple advertisement support status. - optional bool multiple_advertisement_supported = 4; - - // The power level of this advertising - optional location.nearby.proto.connections.PowerLevel power_level = 5; - - // The dual band support status - optional bool supports_dual_band = 6; - - // The wifi aware support status - optional bool supports_wifi_aware = 7; - - // The endpoint info size - optional int32 endpoint_info_size = 8; - } - - // Some additional information to keep with the discovery phase. - message DiscoveryMetadata { - // The bluetooth low energy extended advertisement support status. - optional bool supports_extended_ble_advertisements = 1; - - // The frequency of the connected WiFi AP. - optional int32 connected_ap_frequency = 2; - - // The NFC (Near Field Communication) support status - optional bool supports_nfc_technology = 3; - - // The power level of this discovering - optional location.nearby.proto.connections.PowerLevel power_level = 4; - } - - // Some additional information to keep with the connection attempt. - message ConnectionAttemptMetadata { - // The technology used by the mediums. - optional location.nearby.proto.connections.ConnectionTechnology technology = - 1; - - // The wifi band used by the wifi mediums. - optional location.nearby.proto.connections.ConnectionBand band = 2; - - // The frequency used by the wifi mediums. - optional int32 frequency = 3; - - // The MCC (Mobile country code) MNC (Mobile network code) of the network - // operator. - optional string network_operator = 4 - /* type = ST_LOCATION */; - - // The upper-case ISO 3166-1 alpha-2 country code of: - // 1. the current connected WiFi network - // 2. or the current registered operator's MCC (Mobile Country Code) - // 3. or empty string. - optional string country_code = 5 /* type = ST_LOCATION */; - - // The TDLS status used by the wifi lan medium, - // TDLS, shortened from Tunneled Direct Link Setup, is "a seamless way to - // stream media and other data faster between devices already on the same - // Wi-Fi network." Devices using it communicate directly with one another, - // without involving the wireless network's router. - optional bool is_tdls_used = 6; - - // The try times for this hosted group or connection operation. - optional int32 try_counts = 7; - - // The enabled status of the wifi hotspot(tethering) when doing this - // connection attempt. - optional bool wifi_hotspot_status = 8; - - // The MAX supported TX link speed (Mbps). - optional int32 max_tx_speed = 9; - - // The MAX supported RX link speed (Mbps). - optional int32 max_rx_speed = 10; - - // The connected wifi channel width. - optional int32 wifi_channel_width = 11; - - // The send buffer size of the created socket - optional int32 send_buffer_size = 12; - - // The receive buffer size of the created socket - optional int32 receive_buffer_size = 13; - - // The frequency of the connected WiFi AP. - optional int32 connected_ap_frequency = 14; - - // The connectivity MCC mode - optional bool is_mcc_mode = 15; - } -} -// LINT.ThenChange() diff --git a/internal/proto/analytics/connections_log_test.cc b/internal/proto/analytics/connections_log_test.cc deleted file mode 100644 index 53048875..00000000 --- a/internal/proto/analytics/connections_log_test.cc +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2020 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. - -// #include "logs/proto/location/nearby/nearby_client_log.proto.h" -#include "google/protobuf/descriptor.h" -#include "gtest/gtest.h" -#include "internal/platform/logging.h" -#include "internal/proto/analytics/connections_log.pb.h" -#include "proto/connections_enums.pb.h" - -namespace nearby { -namespace analytics { -namespace proto { - -namespace { - -using G3ConnectionsLog = ::location::nearby::analytics::proto::ConnectionsLog; -using P3ConnectionsLog = ::location::nearby::analytics::proto::ConnectionsLog; - -using ::proto2::Descriptor; -using ::proto2::FieldDescriptor; - -// Forward declaration. -bool Compare(const Descriptor* desc1, const Descriptor* desc2); - -// Compares the two field descriptors and return false if name, number, label, -// or type is different. -bool Compare(const FieldDescriptor* field1, const FieldDescriptor* field2) { - if (field1->name() != field2->name()) { - LOG(WARNING) << "Field name diff: " << field1->name() << " <=> " - << field2->name(); - return false; - } - if (field1->number() != field2->number()) { - LOG(WARNING) << "Field " << field1->name() - << " number diff: " << field1->number() << " <=> " - << field2->number(); - return false; - } - if (field1->label() != field2->label()) { - LOG(WARNING) << "Field " << field1->name() - << " label diff: " << field1->label() << " <=> " - << field2->label(); - return false; - } - bool bRet = false; - if (field1->type() != field2->type()) { - LOG(WARNING) << "Field " << field1->name() - << " type diff: " << field1->type() << " <=> " - << field2->type(); - return bRet; - } else if (field1->type() == FieldDescriptor::TYPE_MESSAGE) { - const Descriptor* msg1 = field1->message_type(); - const Descriptor* msg2 = field2->message_type(); - - bRet = Compare(msg1, msg2); - } else { - bRet = true; - } - - return bRet; -} - -// Compares the two descriptors and return false immediately if different. -bool Compare(const Descriptor* desc1, const Descriptor* desc2) { - LOG(INFO) << "Descriptor1 full name: " << desc1->full_name() << " <=> " - << desc2->full_name(); - for (int i = 0; i < desc1->field_count(); ++i) { - const FieldDescriptor* field1 = desc1->field(i); - const FieldDescriptor* field2 = desc2->FindFieldByName(field1->name()); - - bool bRet = false; - if (field2) { - bRet = Compare(field1, field2); - } else { - LOG(ERROR) << "Descriptor1 full name: " << desc1->full_name() - << "=> Extra field1 name=" << field1->name() - << ", number=" << field1->number() - << ", label=" << field1->label() - << ", type=" << field1->type(); - } - if (!bRet) { - return false; - } - } - for (int i = 0; i < desc2->field_count(); ++i) { - const FieldDescriptor* field2 = desc2->field(i); - const FieldDescriptor* field1 = desc1->FindFieldByName(field2->name()); - if (!field1) { - LOG(ERROR) << "Descriptor2 full name: " << desc2->full_name() - << "=> Extra field2 name=" << field2->name() - << ", number=" << field2->number() - << ", label=" << field2->label() - << ", type=" << field2->type(); - return false; - } - } - - return true; -} - -TEST(ConnectionsLogTest, TwoMessagesAreIdentical) { - const proto2::Descriptor* descriptor1 = G3ConnectionsLog::descriptor(); - const proto2::Descriptor* descriptor2 = P3ConnectionsLog::descriptor(); - - EXPECT_TRUE(Compare(descriptor1, descriptor2)); -} - -} // namespace - -} // namespace proto -} // namespace analytics -} // namespace nearby From a78012cc36e688ae19baa777a34f8721b9bd02e4 Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 2 Jun 2026 09:41:12 -0700 Subject: [PATCH 133/151] Refactor ServiceControllerRouter::RequestConnectionV3 lambda captures. PiperOrigin-RevId: 925407906 --- .../implementation/base_pcp_handler.cc | 11 ++- .../service_controller_router.cc | 68 ++++++++++++------- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 07f033ed..81bb0181 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -730,8 +730,15 @@ void BasePcpHandler::OnEncryptionSuccessRunnableV3( // // TODO(b/305004353): Authenticate the connection in the responder role for // outgoing connections. - if (!pending_connection_info.is_incoming) { + if (pending_connection_info.is_incoming) { LOG(ERROR) << __func__ << ": only outgoing connections are supported"; + ProcessPreConnectionInitiationFailure( + pending_connection_info.client, pending_connection_info.medium, + remote_device.GetEndpointId(), pending_connection_info.channel.get(), + pending_connection_info.is_incoming, /*log_failure=*/true, + pending_connection_info.start_time, {Status::kConnectionRejected}, + OperationResultCode::DETAIL_UNKNOWN, + pending_connection_info.result.lock().get()); return; } @@ -1196,7 +1203,7 @@ Status BasePcpHandler::RequestConnectionV3( pending_connection_info.client = client; pending_connection_info.remote_endpoint_info = endpoint->endpoint_info; pending_connection_info.nonce = connection_info.nonce; - pending_connection_info.is_incoming = true; + pending_connection_info.is_incoming = false; pending_connection_info.start_time = start_time; pending_connection_info.listener = info.listener; pending_connection_info.connection_options = connection_options; diff --git a/connections/implementation/service_controller_router.cc b/connections/implementation/service_controller_router.cc index 250296cd..c79ec237 100644 --- a/connections/implementation/service_controller_router.cc +++ b/connections/implementation/service_controller_router.cc @@ -15,30 +15,43 @@ #include "connections/implementation/service_controller_router.h" #include +#include #include #include #include #include +#include #include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" +#include "absl/types/span.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/flags/nearby_connections_feature_flags.h" #include "connections/implementation/offline_service_controller.h" +#include "connections/implementation/service_controller.h" #include "connections/listeners.h" #include "connections/medium_selector.h" +#include "connections/out_of_band_connection_metadata.h" #include "connections/params.h" #include "connections/payload.h" +#include "connections/status.h" #include "connections/v3/bandwidth_info.h" +#include "connections/v3/connection_listening_options.h" #include "connections/v3/connection_result.h" #include "connections/v3/connections_device.h" +#include "connections/v3/listeners.h" #include "connections/v3/listening_result.h" +#include "connections/v3/params.h" #include "internal/flags/nearby_flags.h" +#include "internal/interop/device.h" +#include "internal/platform/byte_array.h" #include "internal/platform/feature_flags.h" #include "internal/platform/logging.h" +#include "internal/platform/runnable.h" namespace nearby { namespace connections { @@ -413,30 +426,35 @@ void ServiceControllerRouter::RequestConnectionV3( // CancellationListener as soon as possible. client->AddCancellationFlag(remote_device.GetEndpointId()); + // v3_info must outlive the serializer task: the v1 ConnectionListener we + // build below is COPIED into ClientProxy::connections_ and its + // disconnected_cb / bandwidth_changed_cb fire long after this task returns. + auto v3_shared = + std::make_shared(std::move(info.listener)); + std::string remote_endpoint_id = remote_device.GetEndpointId(); + RouteToServiceController( "scr-request-connection-v3", - [this, client, &remote_device, v3_info = std::move(info), + [this, client, remote_endpoint_id, v3_shared, + local_endpoint_info = + (info.local_device.GetType() == + NearbyDevice::Type::kConnectionsDevice) + ? reinterpret_cast(info.local_device) + .GetEndpointInfo() + : "", connection_options, callback = std::move(callback)]() mutable { - std::string endpoint_id = remote_device.GetEndpointId(); + const std::string& endpoint_id = remote_endpoint_id; if (client->HasPendingConnectionToEndpoint(endpoint_id) || client->IsConnectedToEndpoint(endpoint_id)) { callback({Status::kAlreadyConnectedToEndpoint}); return; } - std::string endpoint_info; - if (v3_info.local_device.GetType() == - NearbyDevice::Type::kConnectionsDevice) { - endpoint_info = - reinterpret_cast(v3_info.local_device) - .GetEndpointInfo(); - } - ConnectionListener listener = { .initiated_cb = - [&v3_info, &remote_device]( - const std::string& endpoint_id, - const ConnectionResponseInfo& response_info) mutable { + [v3_shared, endpoint_id]( + const std::string& /*endpoint_id*/, + const ConnectionResponseInfo& response_info) { v3::InitialConnectionInfo new_info = { .authentication_digits = response_info.authentication_token, @@ -447,18 +465,19 @@ void ServiceControllerRouter::RequestConnectionV3( .authentication_status = response_info.authentication_status, }; - v3_info.listener.initiated_cb(remote_device, new_info); + v3_shared->initiated_cb( + v3::ConnectionsDevice(endpoint_id, "", {}), new_info); }, .accepted_cb = - [result_cb = v3_info.listener.result_cb]( - const std::string& endpoint_id) { + [result_cb = + v3_shared->result_cb](const std::string& endpoint_id) { v3::ConnectionResult result = { .status = {Status::kSuccess}, }; result_cb(v3::ConnectionsDevice(endpoint_id, "", {}), result); }, .rejected_cb = - [result_cb = v3_info.listener.result_cb]( + [result_cb = v3_shared->result_cb]( const std::string& endpoint_id, Status status) { v3::ConnectionResult result = { .status = status, @@ -466,28 +485,29 @@ void ServiceControllerRouter::RequestConnectionV3( result_cb(v3::ConnectionsDevice(endpoint_id, "", {}), result); }, .disconnected_cb = - [&v3_info](const std::string& endpoint_id) mutable { + [v3_shared](const std::string& endpoint_id) { auto device = v3::ConnectionsDevice(endpoint_id, "", {}); - v3_info.listener.disconnected_cb(device); + v3_shared->disconnected_cb(device); }, .bandwidth_changed_cb = - [this, &v3_info](const std::string& endpoint_id, - Medium medium) mutable { + [this, v3_shared](const std::string& endpoint_id, + Medium medium) mutable { v3::BandwidthInfo bandwidth_info = { .quality = GetMediumQuality(medium), .medium = medium, }; - v3_info.listener.bandwidth_changed_cb( + v3_shared->bandwidth_changed_cb( v3::ConnectionsDevice(endpoint_id, "", {}), bandwidth_info); }, }; ConnectionRequestInfo old_info = { - .endpoint_info = ByteArray(endpoint_info), + .endpoint_info = ByteArray(local_endpoint_info), .listener = std::move(listener), }; Status status = GetServiceController()->RequestConnectionV3( - client, remote_device, std::move(old_info), connection_options); + client, v3::ConnectionsDevice(endpoint_id, "", {}), + std::move(old_info), connection_options); if (!status.Ok()) { LOG(WARNING) << "Unable to request connection to endpoint " << endpoint_id << ": " << status.ToString(); From ec9759d88a96085614e3f0cc82c99103e93dc4f4 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 2 Jun 2026 11:34:36 -0700 Subject: [PATCH 134/151] Remove SharingLog. PiperOrigin-RevId: 925485033 --- connections/c/BUILD | 2 +- connections/c/nc.cc | 2 +- sharing/BUILD | 4 +- sharing/incoming_share_session_test.cc | 2 +- sharing/outgoing_share_session_test.cc | 4 +- sharing/proto/analytics/BUILD | 36 - .../proto/analytics/nearby_sharing_log.proto | 1128 ----------------- 7 files changed, 7 insertions(+), 1171 deletions(-) delete mode 100644 sharing/proto/analytics/BUILD delete mode 100644 sharing/proto/analytics/nearby_sharing_log.proto diff --git a/connections/c/BUILD b/connections/c/BUILD index 930b191c..c745e9c9 100644 --- a/connections/c/BUILD +++ b/connections/c/BUILD @@ -62,7 +62,7 @@ cc_library( "//internal/platform:types", "//location/nearby/analytics/cpp/logging:event_logger", "//location/nearby/analytics/cpp/proto:connections_log_cc_proto", - "//sharing/proto/analytics:sharing_log_cc_proto", + "//location/nearby/analytics/cpp/proto:sharing_log_cc_proto", "@com_google_absl//absl/base:no_destructor", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/strings", diff --git a/connections/c/nc.cc b/connections/c/nc.cc index f31d1c8f..2c975cb9 100644 --- a/connections/c/nc.cc +++ b/connections/c/nc.cc @@ -28,6 +28,7 @@ #if !defined(NC_OSS_BUILD) #include "location/nearby/analytics/cpp/logging/event_logger.h" #include "location/nearby/analytics/cpp/proto/connections_log.pb.h" +#include "location/nearby/analytics/cpp/proto/nearby_sharing_log.pb.h" #endif // !defined(NC_OSS_BUILD) #include "absl/base/no_destructor.h" #include "absl/container/flat_hash_map.h" @@ -56,7 +57,6 @@ #include "internal/platform/file.h" #include "internal/platform/logging.h" #include "internal/platform/mac_address.h" -#include "sharing/proto/analytics/nearby_sharing_log.pb.h" #if TARGET_OS_IOS #include "internal/platform/implementation/apple/nearby_logger.h" #endif // TARGET_OS_IOS diff --git a/sharing/BUILD b/sharing/BUILD index 8ab13f26..e66e1ce5 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -930,12 +930,12 @@ cc_test( "//internal/platform/implementation:platform_impl", "//internal/test", "//location/nearby/analytics/cpp/logging:mock_event_logger", + "//location/nearby/analytics/cpp/proto:sharing_log_cc_proto", "//location/nearby/sharing/lib/analytics", "//net/proto2/contrib/parse_proto:parse_text_proto", "//sharing/certificates:test_support", "//sharing/common:enum", "//sharing/proto:wire_format_cc_proto", - "//sharing/proto/analytics:sharing_log_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/time", @@ -961,11 +961,11 @@ cc_test( "//internal/platform/implementation:platform_impl", "//internal/test", "//location/nearby/analytics/cpp/logging:mock_event_logger", + "//location/nearby/analytics/cpp/proto:sharing_log_cc_proto", "//location/nearby/sharing/lib/analytics", "//proto:sharing_enums_cc_proto", "//sharing/internal/public:logging", "//sharing/proto:wire_format_cc_proto", - "//sharing/proto/analytics:sharing_log_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/time", diff --git a/sharing/incoming_share_session_test.cc b/sharing/incoming_share_session_test.cc index fe19813e..1c77ae79 100644 --- a/sharing/incoming_share_session_test.cc +++ b/sharing/incoming_share_session_test.cc @@ -26,6 +26,7 @@ #include "location/nearby/analytics/cpp/logging/mock_event_logger.h" #include "location/nearby/analytics/cpp/logging/sharing_log_matchers.h" +#include "location/nearby/analytics/cpp/proto/nearby_sharing_log.pb.h" #include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" @@ -43,7 +44,6 @@ #include "sharing/internal/public/logging.h" #include "sharing/nearby_connection_impl.h" #include "sharing/nearby_connections_types.h" -#include "sharing/proto/analytics/nearby_sharing_log.pb.h" #include "sharing/proto/wire_format.pb.h" #include "sharing/share_session_usage.h" #include "sharing/share_target.h" diff --git a/sharing/outgoing_share_session_test.cc b/sharing/outgoing_share_session_test.cc index f314a90e..21b01d6c 100644 --- a/sharing/outgoing_share_session_test.cc +++ b/sharing/outgoing_share_session_test.cc @@ -24,6 +24,8 @@ #include "location/nearby/analytics/cpp/logging/mock_event_logger.h" #include "location/nearby/analytics/cpp/logging/sharing_log_matchers.h" +#include "location/nearby/analytics/cpp/proto/nearby_sharing_log.pb.h" +#include "location/nearby/analytics/cpp/proto/nearby_sharing_log.proto.static_reflection.h" #include "location/nearby/sharing/lib/analytics/analytics_recorder_impl.h" #include "net/proto2/contrib/parse_proto/parse_text_proto.h" #include "gmock/gmock.h" @@ -46,8 +48,6 @@ #include "sharing/nearby_connection_impl.h" #include "sharing/nearby_connections_manager.h" #include "sharing/nearby_connections_types.h" -#include "sharing/proto/analytics/nearby_sharing_log.pb.h" -#include "sharing/proto/analytics/nearby_sharing_log.proto.static_reflection.h" #include "sharing/proto/wire_format.pb.h" #include "sharing/share_session_usage.h" #include "sharing/share_target.h" diff --git a/sharing/proto/analytics/BUILD b/sharing/proto/analytics/BUILD deleted file mode 100644 index 3a8e26d8..00000000 --- a/sharing/proto/analytics/BUILD +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2022 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. - -load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library") -load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") - -licenses(["notice"]) - -package(default_visibility = ["//visibility:public"]) - -proto_library( - name = "sharing_log_proto", - srcs = [ - "nearby_sharing_log.proto", - ], - deps = [ - "//proto:sharing_enums_proto", - "@com_google_protobuf//:duration_proto", - ], -) - -cc_proto_library( - name = "sharing_log_cc_proto", - deps = [":sharing_log_proto"], -) diff --git a/sharing/proto/analytics/nearby_sharing_log.proto b/sharing/proto/analytics/nearby_sharing_log.proto deleted file mode 100644 index 0f7b30f6..00000000 --- a/sharing/proto/analytics/nearby_sharing_log.proto +++ /dev/null @@ -1,1128 +0,0 @@ -// Copyright 2022 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. - -syntax = "proto2"; - -package nearby.sharing.analytics.proto; - -import "google/protobuf/duration.proto"; - -// "privacy/pattributes/annotations/proto_field.proto"; -// import "storage/datapol/annotations/proto/semantic_annotations.proto"; -// import "storage/googlesql/public/proto/type_annotation.proto"; -import "proto/sharing_enums.proto"; - -option optimize_for = LITE_RUNTIME; -option java_package = "nearby.sharing.analytics.proto"; -option java_outer_classname = "SharingLogProto"; -option objc_class_prefix = "GNCP"; - -// Top-level log proto for all NearbySharing logging. -// Each log contains a key (event_type), value (a verb-noun event) pair. -// Next Tag: 90 -// LINT.IfChange -message SharingLog { - /* justification = { - collection_basis: CB_CHECKBOX - purposes: [ INFRASTRUCTURE_METRICS, BUSINESS_ANALYSIS ] - } */ - - reserved 71; // Deprecated TransferUIEvent. - - optional location.nearby.proto.sharing.EventType event_type = 1; - - optional UnknownEvent unknown_event = 2; - - optional AcceptAgreements accept_agreements = 3; - - optional EnableNearbySharing enable_nearby_sharing = 4; - - optional SetVisibility set_visibility = 5; - - optional DescribeAttachments describe_attachments = 6; - - optional ScanForShareTargetsStart scan_for_share_targets_start = 7; - - optional ScanForShareTargetsEnd scan_for_share_targets_end = 8; - - optional AdvertiseDevicePresenceStart advertise_device_presence_start = 9; - - optional AdvertiseDevicePresenceEnd advertise_device_presence_end = 10; - - optional SendFastInitialization send_initialization = 11; - - optional ReceiveFastInitialization receive_initialization = 12; - - optional DiscoverShareTarget discover_share_target = 13; - - optional SendIntroduction send_introduction = 14; - - optional ReceiveIntroduction receive_introduction = 15; - - optional RespondToIntroduction respond_introduction = 16; - - optional SendAttachmentsStart send_attachments_start = 17; - - optional SendAttachmentsEnd send_attachments_end = 18; - - optional ReceiveAttachmentsStart receive_attachments_start = 19; - - optional ReceiveAttachmentsEnd receive_attachments_end = 20; - - optional CancelSendingAttachments cancel_sending_attachments = 21; - - optional CancelReceivingAttachments cancel_receiving_attachments = 22; - - optional OpenReceivedAttachments open_received_attachments = 23; - - optional LaunchActivity launch_activity = 24; - - optional AddContact add_contact = 25; - - optional RemoveContact remove_contact = 26; - - optional location.nearby.proto.sharing.LogSource log_source = 27; - - optional FastShareServerResponse fast_share_server_response = 28; - - optional SendStart send_start = 29; - - optional AcceptFastInitialization accept_fast_initialization = 30; - - optional SetDataUsage set_data_usage = 31; - - // The version of Nearby Sharing. E.g. "v1.0.2". - optional string version = 32 /* type = ST_SOFTWARE_ID */; - - optional location.nearby.proto.sharing.EventCategory event_category = 33; - - optional DismissFastInitialization dismiss_fast_initialization = 34; - - optional CancelConnection cancel_connection = 35; - - optional DismissPrivacyNotification dismiss_privacy_notification = 36; - - // Tap privacy notification to update visibility setting. - // http://shortn/_LMJHzPFZM0 - optional TapPrivacyNotification tap_privacy_notification = 37; - - optional TapHelp tap_help = 38; - - optional TapFeedback tap_feedback = 39; - - optional AddQuickSettingsTile add_quick_settings_tile = 40; - - optional RemoveQuickSettingsTile remove_quick_settings_tile = 41; - - optional LaunchPhoneConsent launch_phone_consent = 42; - - optional TapQuickSettingsTile tap_quick_settings_tile = 43; - - optional InstallAPKStatus install_apk_status = 44; - - optional VerifyAPKStatus verify_apk_status = 45; - - optional LaunchConsent launch_consent = 46; - - optional ProcessReceivedAttachmentsEnd process_received_attachments_end = 47; - - optional ToggleShowNotification toggle_show_notification = 48; - - optional SetDeviceName set_device_name = 49; - - // This is a temporary logging field for FilesGo migration phase based on - // device geolocation. Example values are "Phase 1", "Phase 2", etc. - // Reference: http://shortn/_BkSTmDjzWc - optional string files_migration_phase = 50; - - optional DeclineAgreements decline_agreements = 51; - - optional RequestSettingPermissions request_setting_permissions = 52; - - optional DeviceSettings device_settings = 53; - - optional EstablishConnection establish_connection = 54; - - optional AutoDismissFastInitialization auto_dismiss_fast_initialization = 55; - - optional EventMetadata event_metadata = 56; - - // Used only for Nearby Share Windows app now, e.g. "1.0.408". Deprecated and - // move it to the AppInfo below. - optional string app_version = 57 - /* type = ST_SOFTWARE_ID */[deprecated = true]; - - // Used only for Nearby Share Windows app now - optional AppCrash app_crash = 58; - - // Used only for Nearby Share android app now - optional TapQuickSettingsFileShare tap_quick_settings_file_share = 59; - - // Used only for Nearby Share Windows app now. - // TODO(b/260732897): To deprecate, and will be replaced by - // NearbyClientLog.AppInfo. - optional AppInfo app_info = 60; - - // Used only for Nearby Share android app now - optional DisplayPrivacyNotification display_privacy_notification = 61; - - // Used only for Nearby Share android app now - optional DisplayPhoneConsent display_phone_consent = 62; - - // Used only for Nearby Share Windows app now. - optional PreferencesUsage preferences_usage = 63; - - // Used only for Nearby Share android app now. - optional DefaultOptIn default_opt_in = 64; - - optional SetupWizard setup_wizard = 65; - - // Used only for Nearby Share android app now. - optional TapQrCode tap_qr_code = 66; - - optional QrCodeLinkShown qr_code_link_shown = 67; - - optional ParsingFailedEndpointId parsing_failed_endpoint_id = 68; - - optional FastInitDiscoverDevice fast_init_discover_device = 69; - - optional SendDesktopNotification send_desktop_notification = 70; - - optional SendDesktopTransferEvent send_desktop_transfer_event = 72; - - optional SetAccount set_account = 73; - - optional DecryptCertificateFailure decrypt_certificate_failure = 74; - - // Used only for Nearby Share android app now. - optional ShowAllowPermissionAutoAccess show_allow_permission_auto_access = 75; - - optional ShowWaitingForAccept show_waiting_for_accept = 76; - - optional HighQualityMediumSetup high_quality_medium_setup = 77; - - optional RpcCallStatus rpc_call_status = 78; - - optional StartQrCodeSession start_qr_code_session = 79; - - optional QrCodeOpenedInWebClient qr_code_opened_in_web_client = 80; - - optional HatsJointEvent hats_joint_event = 81; - - optional ReceivePreviews receive_previews = 82; - - // Two types of QR code sharing: P2P and Cloud-based - // P2P QR code flow re-uses a lot of the existing events from scan to send. - // Cloud-based QR code flow has the following new events. - // QR code events for sender side. - optional CloudCreateSharingRequest cloud_create_sharing_request = 83; - - // QR code CLOUD_REGISTER_RECEIVER event for receiver side. - optional CloudRegisterReceiver cloud_register_receiver = 84; - - optional CloudUploadStart cloud_upload_start = 85; - - optional CloudUploadEnd cloud_upload_end = 86; - - optional CloudDownloadStart cloud_download_start = 87; - - optional CloudDownloadEnd cloud_download_end = 88; - - // Cloud sharing RPC call event. - optional CloudSharingRpcResult cloud_sharing_rpc_result = 89; - - // Used only for Nearby Share Windows app now. - message AppInfo { - // e.g. "1.0.408" - optional string app_version = 1 /* type = ST_SOFTWARE_ID */; - // e.g. en. In Windows app, it's from the registry value. - optional string app_language = 2 - /* type = ST_DEMOGRAPHIC_INFO */; - optional string update_track = - 3; // e.g. "developer". In Windows app, it's from the registry value. - } - - message DeviceSettings { - // Device visibility setting at Nearby Share settings page, e.g. Contacts. - optional location.nearby.proto.sharing.Visibility visibility = 1; - // Device data usage preference at Nearby Share settings page, e.g.Wi-Fi - // only, Data, etc. - optional location.nearby.proto.sharing.DataUsage data_usage = 2; - // Device name length - optional int32 device_name_size = 3; - // Whether device allows show notification when devices are sharing nearby. - optional bool is_show_notification_enabled = 4; - // True if the BlueTooth setting is enabled - optional bool is_bt_enabled = 5; - // True if the location setting is enabled - optional bool is_location_enabled = 6; - // True if the wifi setting is enabled - optional bool is_wifi_enabled = 7; - // Date(YYYYMMDD) in decimal format for the first successful transfer in - // America/Los_Angeles timezone. If no successful transfer exists, the value - // is 0. - optional int32 first_successful_transfer_date = 8 - /* format = googlesql.format */; - // Date(YYYYMMDD) in decimal format for the previous successful transfer in - // America/Los_Angeles timezone. If no successful transfer exists, the value - // is 0. - optional int32 previous_successful_transfer_date = 9 - /* format = googlesql.format */; - // The cumulative number of transfers the device has completed. - // Exact transfer count stored on device, but when logging put the transfer - // count in buckets, initially we use buckets: 1, 2, 3, …, 10, 11+ - optional int32 lifetime_transfer_count = 10; - // Upload Contact data according to Device consent or Quick Share consent. - optional location.nearby.proto.sharing.ContactAccess contact_access = 11; - // Phone number verification. - optional location.nearby.proto.sharing.IdentityVerification - identity_verification = 12; - } - - // Used only for Nearby Share Windows app now. Here is the screenshot about - // where preferences are set: - // https://screenshot.googleplex.com/6HFrEfKCPxuSiYz. - message PreferencesUsage { - optional location.nearby.proto.sharing.PreferencesAction action = 1; - optional location.nearby.proto.sharing.PreferencesActionStatus - action_status = 2; - optional location.nearby.proto.sharing.PreferencesAction prev_sub_action = - 3; - optional location.nearby.proto.sharing.PreferencesAction next_sub_action = - 4; - } - - // EventType: UNKNOWN_EVENT_TYPE - message UnknownEvent {} - - // EventType: ESTABLISH_CONNECTION - message EstablishConnection { - // The result status of the attempt to establish a connection. - optional location.nearby.proto.sharing.EstablishConnectionStatus status = 1; - - optional int64 session_id = 2 /* type = ST_SESSION_ID */; - // For group share, 1-based number for transfer position. - optional int32 transfer_position = 3; - // For group share. - optional int32 concurrent_connections = 4; - // For calculating latency. - optional int64 duration_millis = 5; - optional ShareTargetInfo share_target_info = 6; - optional string referrer_name = 7; - // Deprecated. Use share_target_info.has_matching_qr_code instead. - optional bool qr_code_flow = 8 [deprecated = true]; - // True if the connection established from receiver - optional bool is_incoming_connection = 9; - // Duration from when the receiver attempts to receive from a QR code to - // when the QR code sender successfully connects to this receiver. Only set - // for QR-code based receive flows. - optional google.protobuf.Duration qr_code_receiver_connect_latency = 10; - } - - // EventType: ACCEPT_AGREEMENTS - message AcceptAgreements {} - - // EventType: DECLINE_AGREEMENTS - message DeclineAgreements {} - - // EventType: ENABLE_NEARBY_SHARING - message EnableNearbySharing { - optional location.nearby.proto.sharing.NearbySharingStatus status = 1; - optional bool has_opted_in = 2; - } - - // EventType: SET_ACCOUNT - // Activity Name: SETUP_ACTIVITY or SETTINGS_ACTIVITY - message SetAccount { - optional location.nearby.proto.sharing.ActivityName activity_name = 1; - } - - // EventType: SET_VISIBILITY - message SetVisibility { - // The new visibility that the device is set to. - optional location.nearby.proto.sharing.Visibility visibility = 1; - - // The current visibility of the device. - optional location.nearby.proto.sharing.Visibility source_visibility = 2; - - // The duration in millis of this visibility setting. - optional int64 duration_millis = 3; - - optional location.nearby.proto.sharing.ActivityName source_activity_name = 4 - /* type = ST_NOT_REQUIRED */; - } - - // EventType: SET_DATA_USAGE - message SetDataUsage { - // The current data usage preference of the device. - optional location.nearby.proto.sharing.DataUsage original_preference = 1; - - // The new data usage preference that the device is set to. - optional location.nearby.proto.sharing.DataUsage preference = 2; - } - - // EventType: SCAN_FOR_SHARE_TARGETS_START - message ScanForShareTargetsStart { - // A randomly generated number to be used to join the start and end of a - // session (mostly used to compute the duration of the session, e.g. how - // long does it take for attachments to be shared/sent via the Nearby - // Connections api). A same number is used twice for the start and - // end of a session. It is not designed to be associated to user or device, - // and can only be used to join the start and end of a particular session. - // Each session itself does not contain user or device information, and is - // not designed to be joined with other sessions/events of the same user to - // reconstruct particular user's activity pattern. - optional int64 session_id = 1 /* type = ST_SESSION_ID */; - optional location.nearby.proto.sharing.SessionStatus status = 2; - optional location.nearby.proto.sharing.ScanType scan_type = 3; - optional int64 flow_id = 4 /* type = ST_SESSION_ID */; - optional string referrer_name = 5; - // Represents whether this scan was started with an active QR code session - // that can be used to help discover targets that have scanned the same QR - // code - optional bool use_qr_code = 6; - } - - // EventType: SCAN_FOR_SHARE_TARGETS_END - message ScanForShareTargetsEnd { - optional int64 session_id = 1 /* type = ST_SESSION_ID */; - } - - // EventType: ADVERTISE_DEVICE_PRESENCE_START - message AdvertiseDevicePresenceStart { - // No longer needed for advertisement. - optional int64 session_id = 1 - /* type = ST_SESSION_ID */[deprecated = true]; - optional location.nearby.proto.sharing.Visibility visibility = 2; - optional location.nearby.proto.sharing.SessionStatus status = 3; - optional location.nearby.proto.sharing.DataUsage data_usage = 4; - // No longer needed for advertisement, replace this with - // SET_NAME_DEVICE. - optional int32 device_name_size = 5 [deprecated = true]; - optional string referrer_name = 6; - optional location.nearby.proto.sharing.AdvertisingMode advertising_mode = 7; - optional bool qr_code_flow = 8; - } - - // EventType: ADVERTISE_DEVICE_PRESENCE_END - message AdvertiseDevicePresenceEnd { - // No longer needed for advertisement. - optional int64 session_id = 1 - /* type = ST_SESSION_ID */[deprecated = true]; - } - - // EventType: SEND_FAST_INITIALIZATION - message SendFastInitialization {} - - // EventType: RECEIVE_FAST_INITIALIZATION - message ReceiveFastInitialization { - // The time elapse from the beginning of screen unlock to the time - // when the FastInitialization is received. - optional int64 time_elapse_since_screen_unlock_millis = 1; - // True if the notification is enabled - optional bool notifications_enabled = 2; - // True if the notification is being filtered when being shown - optional bool notifications_filtered = 3; - } - - // EventType: DISMISS_FAST_INITIALIZATION - message DismissFastInitialization {} - - // EventType: AUTO_DISMISS_FAST_INITIALIZATION - message AutoDismissFastInitialization {} - - // TODO(b/302987763): We need to deprecate flow_id and session_id in each - // event once these two fields in metadata are released to prod and - // pipelines are updated to read them. - message EventMetadata { - optional location.nearby.proto.sharing.SharingUseCase use_case = 1; - // The opt-in status before the user enters the first opt-in screen in each - // time file share or it is always “true” if the user has opted in before. - // Deprecated. - optional bool initial_opt_in = 2 [deprecated = true]; - // The opt-in status after the user leaves the first opt-in screen in each - // time file share or it is always “true” if the user has opted in before. - // Deprecated. - optional bool opt_in = 3 [deprecated = true]; - // The Nearby Share enable status before the user enters the first - // opt-in screen in each time file share. - // Deprecated. - optional bool initial_enable_status = 4 [deprecated = true]; - // The same id means it is in the same sharing file flow of sender side. - // Ex: when sender share file to 2 receivers, the flow_id in sender side is - // the same for all the discovery/connection/transfer events. - optional int64 flow_id = 5 /* type = ST_SESSION_ID */; - // A randomly generated number to be used to join the start and end of a - // session (mostly used to compute the duration of the session, e.g. how - // long does it take for attachments to be shared/sent via the Nearby - // Connections api). A same number is used twice for the start and - // end of a session. It is not designed to be associated to user or device, - // and can only be used to join the start and end of a particular session. - // Each session itself does not contain user or device information, and is - // not designed to be joined with other sessions/events of the same user to - // reconstruct particular user's activity pattern. - optional int64 session_id = 6 /* type = ST_SESSION_ID */; - optional int32 vendor_id = 7 /* type = ST_PARTNER_ID */; - - // The cloud_sharing_id: used by both sender and receiver during QR code - // cloud sharing flow to join sender and receiver events. - optional string cloud_sharing_id = 8 - /* type = ST_SESSION_ID */; - // receiver session id: used by QR code cloud receiver. - optional string cloud_receiver_session_id = 9 - /* type = ST_SESSION_ID */; - - // The name of the external provider, it will not be set if the provider is - // not external. - optional string external_provider_name = 10; - // The service id of the external provider, it will not be set if the - // provider is not external. - optional string external_provider_id = 11 - /* type = ST_SESSION_ID */; - // Is this file transfer from a direct share target. This is only available - // for the sender log. - optional bool is_direct_share = 12; - } - - // TODO(fdi): may consider adding a field about decipherability later. - // EventType: DISCOVER_SHARE_TARGET - message DiscoverShareTarget { - optional ShareTargetInfo share_target_info = 1; - // The time elapse from the beginning of an scanning session to the time - // when the share target is discovered. - optional google.protobuf.Duration duration_since_scanning = 2; - optional int64 session_id = 3 /* type = ST_SESSION_ID */; - optional int64 flow_id = 4 /* type = ST_SESSION_ID */; - optional string referrer_name = 5; - // The time elapse from the share sheet activity starts (foreground - // send surface) to the time when the share target is discovered. - // Only uses foreground send surfaces, since this is when users - // directly engage with NS to send. - optional int64 latency_since_activity_start_millis = 6 [default = -1]; - optional location.nearby.proto.sharing.ScanType scan_type = 7; - - // receiver session id: used by QR code cloud receiver. - optional string cloud_receiver_session_id = 8 - /* type = ST_SESSION_ID */; - } - - // EventType: PARSING_FAILED_ENDPOINT_ID - message ParsingFailedEndpointId { - optional string endpoint_id = 1 /* type = ST_SESSION_ID */; - // The time elapse from the beginning of an scanning session to the time - // when the share target is discovered. - optional google.protobuf.Duration duration_since_scanning = 2; - optional int64 session_id = 3 /* type = ST_SESSION_ID */; - optional int64 flow_id = 4 /* type = ST_SESSION_ID */; - optional string referrer_name = 5 - /* type = ST_REFERER_URL */; - // The time elapse from the share sheet activity starts to the time - // when the share target is discovered. - optional int64 latency_since_activity_start_millis = 6 [default = -1]; - optional location.nearby.proto.sharing.ScanType scan_type = 7; - // The time elapse from the beginning of sync to download the certificates - // to the time when the scanning fails in parsing. - optional google.protobuf.Duration duration_since_last_sync = 8; - optional location.nearby.proto.sharing.ParsingFailedType - parsing_failed_type = 9; - optional location.nearby.proto.sharing.DiscoveryMode discovery_mode = 10; - } - - // EventType: DESCRIBE_ATTACHMENTS - message DescribeAttachments { - optional AttachmentsInfo attachments_info = 1; - - // Time taken to download the attachments before sending - optional google.protobuf.Duration download_duration = 2; - } - - // TODO(fdi): may want to add duration_from_scanning_millis later. - // EventType: SEND_INTRODUCTION - message SendIntroduction { - optional ShareTargetInfo share_target_info = 1; - optional int64 session_id = 2 /* type = ST_SESSION_ID */; - // 1-based number for transfer position. - optional int32 transfer_position = 3; - optional int32 concurrent_connections = 4; - } - - // EventType: RECEIVE_INTRODUCTION - message ReceiveIntroduction { - optional int64 session_id = 1 /* type = ST_SESSION_ID */; - optional ShareTargetInfo share_target_info = 2; - optional string referrer_name = 3; - } - - // TODO(fdi): may add AttachmentInfo, or ShareTargetInfo later. - // EventType: RESPOND_TO_INTRODUCTION - message RespondToIntroduction { - optional location.nearby.proto.sharing.ResponseToIntroduction action = 1; - optional int64 session_id = 2 /* type = ST_SESSION_ID */; - optional bool qr_code_flow = 3; - } - - // EventType: SEND_ATTACHMENTS_START - message SendAttachmentsStart { - optional int64 session_id = 1 /* type = ST_SESSION_ID */; - optional AttachmentsInfo attachments_info = 2; - // 1-based number for transfer position. - optional int32 transfer_position = 3; - optional int32 concurrent_connections = 4; - // Deprecated. Use share_target_info.has_matching_qr_code instead. - optional bool qr_code_flow = 5 [deprecated = true]; - optional ShareTargetInfo share_target_info = 6; - // True if the advanced protection is enabled and the sender needed to - // confirm the transfer. - optional bool advanced_protection_enabled = 7; - // True if the advanced protection flag from NearbyService BE is different - // from the mendel flag. - optional bool advanced_protection_mismatch = 8; - } - - // EventType: SEND_ATTACHMENTS_END - message SendAttachmentsEnd { - optional int64 session_id = 1 /* type = ST_SESSION_ID */; - optional int64 sent_bytes = 2; - optional location.nearby.proto.sharing.AttachmentTransmissionStatus status = - 3; - // 1-based number for transfer position. - optional int32 transfer_position = 4; - optional int32 concurrent_connections = 5; - optional AttachmentsInfo attachments_info = 6; - // the duration from transfer start to transfer is finished. - optional int64 duration_millis = 7; - optional ShareTargetInfo share_target_info = 8; - optional string referrer_name = 9; - // connection status from nearby connections layer - optional location.nearby.proto.sharing.ConnectionLayerStatus - connection_layer_status = 10; - // Date(YYYYMMDD) in decimal format for the first successful transfer in - // America/Los_Angeles timezone. If no successful transfer exists, the value - // is 0. - optional int32 first_successful_transfer_date = 11 - /* format = googlesql.format */; - // Date(YYYYMMDD) in decimal format for the previous successful transfer in - // America/Los_Angeles timezone. If no successful transfer exists, the value - // is 0. - optional int32 previous_successful_transfer_date = 12 - /* format = googlesql.format */; - // The cumulative number of transfers the device has completed. - // Exact transfer count stored on device, but when logging put the transfer - // count in buckets, initially we use buckets: 1, 2, 3, …, 10, 11+ - optional int32 lifetime_transfer_count = 13; - // The medium used for the connection. - optional int32 connection_medium = 14; - // The data usage of the user settings. - optional location.nearby.proto.sharing.DataUsage data_usage = 15; - - // True if the sender and receiver are mutual contacts. - optional bool is_mutual_contact = 16; - } - - // EventType: RECEIVE_ATTACHMENTS_START - message ReceiveAttachmentsStart { - optional int64 session_id = 1 /* type = ST_SESSION_ID */; - optional AttachmentsInfo attachments_info = 2; - optional ShareTargetInfo share_target_info = 3; - } - - // EventType: RECEIVE_ATTACHMENTS_END - message ReceiveAttachmentsEnd { - optional int64 session_id = 1 /* type = ST_SESSION_ID */; - optional int64 received_bytes = 2; - optional location.nearby.proto.sharing.AttachmentTransmissionStatus status = - 3; - optional string referrer_name = 4; - optional ShareTargetInfo share_target_info = 5; - // Date(YYYYMMDD) in decimal format for the first successful transfer in - // America/Los_Angeles timezone. If no successful transfer exists, the value - // is 0. - optional int32 first_successful_transfer_date = 6 - /* format = googlesql.format */; - // Date(YYYYMMDD) in decimal format for the previous successful transfer in - // America/Los_Angeles timezone. If no successful transfer exists, the value - // is 0. - optional int32 previous_successful_transfer_date = 7 - /* format = googlesql.format */; - // The cumulative number of transfers the device has completed. - // Exact transfer count stored on device, but when logging put the transfer - // count in buckets, initially we use buckets: 1, 2, 3, …, 10, 11+ - optional int32 lifetime_transfer_count = 8; - // The medium used for the connection. - optional int32 connection_medium = 14; - // The data usage of the user settings. - optional location.nearby.proto.sharing.DataUsage data_usage = 15; - } - - // EventType: CANCEL_CONNECTION - message CancelConnection { - optional int64 session_id = 1 /* type = ST_SESSION_ID */; - // 1-based number for transfer position. 1 if log is from receiver side. - optional int32 transfer_position = 2; - optional int32 concurrent_connections = 3; - } - - // EventType: CANCEL_SENDING_ATTACHMENTS - message CancelSendingAttachments {} - - // EventType: CANCEL_RECEIVING_ATTACHMENTS - message CancelReceivingAttachments {} - - // EventType: PROCESS_RECEIVED_ATTACHMENTS_END - message ProcessReceivedAttachmentsEnd { - optional int64 session_id = 1 /* type = ST_SESSION_ID */; - optional location.nearby.proto.sharing.ProcessReceivedAttachmentsStatus - status = 2; - } - - // EventType: OPEN_RECEIVED_ATTACHMENTS - message OpenReceivedAttachments { - optional AttachmentsInfo attachments_info = 3; - optional int64 session_id = 4 /* type = ST_SESSION_ID */; - } - - // EventType: LAUNCH_SETUP_ACTIVITY - message LaunchSetupActivity {} - - // EventType: ADD_CONTACT - message AddContact { - optional bool was_phone_added = 1; - optional bool was_email_added = 2; - } - - // EventType: REMOVE_CONTACT - message RemoveContact { - optional bool was_phone_removed = 1; - optional bool was_email_removed = 2; - } - - // EventType: FAST_SHARE_SERVER_RESPONSE - message FastShareServerResponse { - optional location.nearby.proto.sharing.ServerResponseState status = 1; - optional location.nearby.proto.sharing.ServerActionName name = 2; - optional int64 latency_millis = 3; - optional location.nearby.proto.sharing.SyncPurpose purpose = 4; - optional location.nearby.proto.sharing.ClientRole requester = 5; - optional location.nearby.proto.sharing.DeviceType device_type = 6; - } - - // EventType: SEND_START - message SendStart { - optional int64 session_id = 1 /* type = ST_SESSION_ID */; - // 1-based number for transfer position. - optional int32 transfer_position = 2; - optional int32 concurrent_connections = 3; - optional ShareTargetInfo share_target_info = 4; - } - - // EventType: ACCEPT_FAST_INITIALIZATION - message AcceptFastInitialization {} - - // EventType: LAUNCH_ACTIVITY - message LaunchActivity { - optional location.nearby.proto.sharing.ActivityName activity_name = 1; - // Elapsed time in milliseconds between startActivity and stopActivity. - optional int64 duration_millis = 2; - // The name of the package that launched the activity - optional string referrer_name = 3; - // Is previous transfer in progress. - optional bool previous_transfer_in_progress = 4; - // Whether user has opted in before. For SETUP_ACTIVITY (Opt-In half sheet) - // and SETTINGS_ACTIVITY (Settings page). b/202415050, b/203248230 - optional bool has_opted_in = 5; - // Indicate which UI interaction triggers the opt-in half sheet. Currently - // this only applies to SETUP_ACTIVITY - optional location.nearby.proto.sharing.ActivityName source_activity_name = - 6; - // Is the activity simply pausing or completely finishing. - optional bool is_finishing = 7; - } - - // EventType: DISMISS_PRIVACY_NOTIFICATION - message DismissPrivacyNotification {} - - // EventType: TAP_PRIVACY_NOTIFICATION - message TapPrivacyNotification {} - - // EventType: TAP_HELP - message TapHelp {} - - // EventType: TAP_FEEDBACK - message TapFeedback {} - - // EventType: ADD_QUICK_SETTINGS_TILE - message AddQuickSettingsTile {} - - // EventType: REMOVE_QUICK_SETTINGS_TILE - message RemoveQuickSettingsTile {} - - // EventType: LAUNCH_PHONE_CONSENT - message LaunchPhoneConsent {} - - // EventType: DISPLAY_PHONE_CONSENT - message DisplayPhoneConsent {} - - // EventType: TAP_QUICK_SETTINGS_TILE - message TapQuickSettingsTile {} - - // EventType: TAP_QUICK_SETTINGS_FILE_SHARE - message TapQuickSettingsFileShare {} - - // EventType: DISPLAY_PRIVACY_NOTIFICATION - message DisplayPrivacyNotification {} - - // EventType: DEFAULT_OPT_IN - message DefaultOptIn {} - - // EventType: SET_DEVICE_NAME - message SetDeviceName { - optional int32 device_name_size = 1; - } - - // EventType: REQUEST_SETTING_PERMISSIONS - message RequestSettingPermissions { - optional location.nearby.proto.sharing.PermissionRequestType - permission_type = 1; - optional location.nearby.proto.sharing.PermissionRequestResult - permission_request_result = 2; - } - - // EventType: LAUNCH_CONSENT - message LaunchConsent { - optional location.nearby.proto.sharing.ConsentType consent_type = 1; - optional location.nearby.proto.sharing.ConsentAcceptanceStatus status = 2; - } - - // EventType: INSTALL_APK_STATUS - message InstallAPKStatus { - repeated location.nearby.proto.sharing.InstallAPKStatus status = 1 - [packed = true]; - repeated location.nearby.proto.sharing.ApkSource source = 2 [packed = true]; - } - - // EventType: VERIFY_APK_STATUS - message VerifyAPKStatus { - repeated location.nearby.proto.sharing.VerifyAPKStatus status = 1 - [packed = true]; - repeated location.nearby.proto.sharing.ApkSource source = 2 [packed = true]; - } - - // EventType: TOGGLE_SHOW_NOTIFICATION - message ToggleShowNotification { - optional location.nearby.proto.sharing.ShowNotificationStatus - previous_status = 1; - optional location.nearby.proto.sharing.ShowNotificationStatus - current_status = 2; - } - - // EventType: DECRYPT_CERTIFICATE_FAILURE - message DecryptCertificateFailure { - optional location.nearby.proto.sharing.DecryptCertificateFailureStatus - status = 1; - } - - // EventType: SHOW_ALLOW_PERMISSION_AUTO_ACCESS - message ShowAllowPermissionAutoAccess { - // Auto permission UI activity name - // Shows the auto permission UI if the device lacks Wifi or Bluetooth - // permission and the user has not allowed Nearby Share to automatically - // enable these permissions. Once the user allows access, the UI will - // not be shown again. - // Currently, only the SHARE_SHEET_ACTIVITY and RECEIVE_SURFACE_ACTIVITY - // show the UI. - optional location.nearby.proto.sharing.ActivityName activity_name = 1; - // True if user allowed NS to auto enable Wifi/BT permissions during file - // transfer and NS will recover the permissions after transffer is complete. - optional bool allowed_auto_access = 2; - // True if the device lacks Wifi permission. - optional bool is_wifi_missing = 3; - // True if the device lacks Bluetooth permission. - optional bool is_bt_missing = 4; - } - - // EventType: TAP_QR_CODE - message TapQrCode {} - - // QR_CODE_LINK_SHOWN - message QrCodeLinkShown {} - - // EventType: FAST_INIT_DISCOVER_DEVICE - message FastInitDiscoverDevice { - reserved 1; - // The advertisement type is NOTIFY or SILENT. - optional location.nearby.proto.sharing.FastInitType fast_init_type = 2; - // The distance of the found nearby fast init advertisement. - optional location.nearby.proto.sharing.FastInitState fast_init_state = 3; - } - - // The metadata of a share target. - message ShareTargetInfo { - optional location.nearby.proto.sharing.DeviceType device_type = 1; - optional location.nearby.proto.sharing.OSType os_type = 2; - optional location.nearby.proto.sharing.DeviceRelationship - device_relationship = 3; - // Represents whether the share target has the same QR code as the local - // device. - // In sender side events, this returns whether the receiver represented by - // this ShareTargetInfo has scanned the QR code generated by this sender. - // In receiver side events, this returns whether the sender represented by - // this ShareTargetInfo is the one that generated the QR code scanned by - // this receiver. - optional bool has_matching_qr_code = 4; - - // Represents whether the share target is from external provider. - optional bool is_external = 5; - } - - // The metadata of attachments to be shared. - message AttachmentsInfo { - repeated TextAttachment text_attachment = 1; - repeated FileAttachment file_attachment = 2; - // The App required by sender to open the attachments. - optional string required_app = 3; - repeated WifiCredentialsAttachment wifi_credentials_attachment = 4; - repeated AppAttachment app_attachment = 5; - repeated StreamAttachment stream_attachment = 6; - repeated FolderAttachment folder_attachment = 7; - } - - message TextAttachment { - optional Type type = 1; - optional int64 size_bytes = 2; - // attachments are batched together by some source - optional int64 batch_id = 3 /* type = ST_SESSION_ID */; - optional location.nearby.proto.sharing.AttachmentSourceType source_type = 4; - - enum Type { - UNKNOWN_TEXT_TYPE = 0; - URL = 1; - ADDRESS = 2; - PHONE_NUMBER = 3; - } - } - - message FileAttachment { - optional Type type = 1; - optional int64 size_bytes = 2; - reserved 3; // optional string mime_type = 3 - optional int64 offset_bytes = 4; - // attachments are batched together by some source - optional int64 batch_id = 5 /* type = ST_SESSION_ID */; - optional location.nearby.proto.sharing.AttachmentSourceType source_type = 6; - - enum Type { - UNKNOWN_FILE_TYPE = 0; - IMAGE = 1; - VIDEO = 2; - ANDROID_APP = 3; - AUDIO = 4; - DOCUMENT = 5; - CONTACT_CARD = 6; - } - } - - message WifiCredentialsAttachment { - optional int32 security_type = 1; - // attachments are batched together by some source - optional int64 batch_id = 2 /* type = ST_SESSION_ID */; - optional location.nearby.proto.sharing.AttachmentSourceType source_type = 3; - } - - message AppAttachment { - optional string package_name = 1 /* type = ST_SOFTWARE_ID */; - // App size in bytes. - optional int64 size = 2; - // attachments are batched together by some source - optional int64 batch_id = 3 /* type = ST_SESSION_ID */; - optional location.nearby.proto.sharing.AttachmentSourceType source_type = 4; - } - - message StreamAttachment { - optional string package_name = 1 /* type = ST_SOFTWARE_ID */; - // attachments are batched together by some source - optional int64 batch_id = 2 /* type = ST_SESSION_ID */; - optional location.nearby.proto.sharing.AttachmentSourceType source_type = 3; - } - - message CloudAttachmentInfo { - optional location.nearby.proto.sharing.AttachmentTransmissionStatus status = - 1; - oneof CloudAttachment { - TextAttachment text_attachment = 2; - FileAttachment file_attachment = 3; - WifiCredentialsAttachment wifi_credentials_attachment = 4; - AppAttachment app_attachment = 5; - StreamAttachment stream_attachment = 6; - } - // The total bytes of all attachments transferred. - optional int64 transferred_bytes = 7; - // The duration from transfer start to transfer end. - optional int64 duration_millis = 8; - } - - message FolderAttachment {} - - // EventType: APP_CRASH - // Used only for Nearby Share Windows App now - message AppCrash { - optional location.nearby.proto.sharing.AppCrashReason crash_reason = 1; - } - - // EventType: SETUP_WIZARD - // The results of a setup wizard flow - message SetupWizard { - // The new visibility of the device. - optional location.nearby.proto.sharing.Visibility visibility = 1; - // The previous visibility of the device. - optional location.nearby.proto.sharing.Visibility previous_visibility = 2; - } - - message SendDesktopNotification { - reserved 2; - optional location.nearby.proto.sharing.DesktopNotification event = 1; - } - - message SendDesktopTransferEvent { - optional location.nearby.proto.sharing.DesktopTransferEventType event = 1; - } - - message ShowWaitingForAccept { - optional location.nearby.proto.sharing.ButtonStatus button_status = 1; - } - - message HighQualityMediumSetup { - optional ShareTargetInfo share_target_info = 1; - optional int64 session_id = 2 /* type = ST_SESSION_ID */; - optional int64 duration_millis = 3; - optional bool is_timeout = 4; - optional int32 original_quality = 5; - optional int32 connection_medium = 6; - optional int32 connection_mode = 7; - optional int32 instant_connection_result = 8; - } - - message RpcCallStatus { - enum RpcDirection { - UNKNOWN_RPC_DIRECTION = 0; - INCOMING = 1; - OUTGOING = 2; - } - - optional RpcDirection direction = 1; - // Name of RPC in . format. - optional string rpc_name = 2; - // Canonical error code of RPC. - optional int32 error_code = 3; - // Latency of RPC call in milliseconds. - optional int64 latency_millis = 4; - } - - // EventType: START_QR_CODE_SESSION - message StartQrCodeSession {} - - // EventType: QR_CODE_OPENED_IN_WEB_CLIENT - message QrCodeOpenedInWebClient { - enum ClientPlatform { - UNKNOWN_CLIENT_PLATFORM = 0; - // Used when the client platform is not one of the types below - GENERIC = 1; - ANDROID = 2; - IOS = 3; - CHROME_OS = 4; - WINDOWS = 5; - } - optional ClientPlatform client_platform = 1; - - // Whether the /qrcode page was opened in the browser again after the user - // clicked on the "Try again" button - optional bool is_retry = 2; - } - // EventType: HATS_JOINT_EVENT - message HatsJointEvent { - optional int64 flow_id = 1 /* type = ST_SESSION_ID */; - optional string hats_session_id = 2 - /* type = ST_SESSION_ID */; - } - - // EventType: RECEIVE_PREVIEWS - message ReceivePreviews { - optional int32 num_previews = 1; - } - - // EventType: CLOUD_CREATE_SHARING_REQUEST - message CloudCreateSharingRequest { - optional AttachmentsInfo attachments_info = 1; - optional location.nearby.proto.sharing.CloudCreateSharingResult result = 2; - // Time taken to download attachments from the Intent in milliseconds. - optional int64 attachment_download_latency_millis = 3; - // Time taken to generate and encrypt the preview thumbnail in milliseconds. - optional int64 preview_thumbnail_latency_millis = 4; - // Time taken to make the CreateSharing RPC call in milliseconds. - optional int64 rpc_latency_millis = 5; - } - - // EventType: CLOUD_REGISTER_RECEIVER used by QR code cloud web receiver - message CloudRegisterReceiver { - optional location.nearby.proto.sharing.CloudRegisterReceiverResult result = - 1; - } - - // EventType: CLOUD_UPLOAD_START used by QR code cloud web sender - // The cloud_sharing_id and flow_id are logged in the event metadata. - message CloudUploadStart { - optional AttachmentsInfo attachments_info = 1; - optional location.nearby.proto.sharing.CloudActionType action_type = 2; - } - - // EventType: CLOUD_UPLOAD_END used by QR code cloud web sender - // The cloud_sharing_id and flow_id are logged in the event metadata. - message CloudUploadEnd { - repeated CloudAttachmentInfo upload_infos = 1; - optional location.nearby.proto.sharing.CloudActionType action_type = 2; - } - - // EventType: CLOUD_DOWNLOAD_START used by QR code cloud web receiver - // The cloud_sharing_id and cloud_receiver_session_id are logged in the - // event_metadata into the anonymous logs. - message CloudDownloadStart { - optional AttachmentsInfo attachments_info = 1; - optional location.nearby.proto.sharing.CloudActionType action_type = 2; - } - - // EventType: CLOUD_DOWNLOAD_END used by QR code cloud web receiver - // The cloud_sharing_id and cloud_receiver_session_id are logged in the - // event_metadata into the anonymous logs. - message CloudDownloadEnd { - repeated CloudAttachmentInfo download_infos = 1; - optional location.nearby.proto.sharing.CloudActionType action_type = 2; - } - - // EventType: CLOUD_SHARING_RPC_RESULT - // Event logging the result of a Cloud Sharing RPC call. This event captures - // the type of RPC, its outcome, and performance metrics. - message CloudSharingRpcResult { - // The specific RPC method that was called. - optional string rpc_name = 1; - // The canonical gRPC status code (io.grpc.Status.Code) resulting from the - // call. - optional int32 status_code = 2; - // The total time taken for the RPC call to complete, in milliseconds. - optional int64 latency_millis = 3; - // The unique identifier for the cloud sharing session, if available at the - // time of the call. This helps correlate RPC events to a specific sharing - // session. - optional string cloud_sharing_id = 4; - } -} -// LINT.ThenChange(//depot/google3/logs/proto/location/nearby/nearby_client_log.proto) From 8bc556c4e71dd3ee913aebda597454ba5fc2c851 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 2 Jun 2026 14:01:21 -0700 Subject: [PATCH 135/151] internal PiperOrigin-RevId: 925564968 --- Package.swift | 12 +- .../implementation/mediums/webrtc/BUILD | 268 ------ .../implementation/mediums/webrtc/README.md | 17 - .../mediums/webrtc/connection_flow.cc | 585 ------------- .../mediums/webrtc/connection_flow.h | 250 ------ .../mediums/webrtc/connection_flow_test.cc | 445 ---------- .../mediums/webrtc/data_channel_listener.h | 42 - .../mediums/webrtc/fake_webrtc.cc | 41 - .../mediums/webrtc/fake_webrtc.h | 55 -- .../webrtc/local_ice_candidate_listener.h | 38 - .../webrtc/session_description_wrapper.h | 66 -- .../mediums/webrtc/signaling_frames.cc | 139 --- .../mediums/webrtc/signaling_frames.h | 57 -- .../mediums/webrtc/signaling_frames_test.cc | 198 ----- .../tachyon_express_signaling_messenger.cc | 340 -------- .../tachyon_express_signaling_messenger.h | 99 --- .../implementation/mediums/webrtc/webrtc.h | 110 --- .../mediums/webrtc/webrtc_bwu_handler.cc | 184 ---- .../mediums/webrtc/webrtc_bwu_handler.h | 85 -- .../mediums/webrtc/webrtc_bwu_handler_test.cc | 139 --- .../mediums/webrtc/webrtc_endpoint_channel.cc | 42 - .../mediums/webrtc/webrtc_endpoint_channel.h | 44 - .../mediums/webrtc/webrtc_impl.cc | 793 ------------------ .../mediums/webrtc/webrtc_impl.h | 253 ------ .../mediums/webrtc/webrtc_impl_test.cc | 651 -------------- .../mediums/webrtc/webrtc_medium_impl.cc | 87 -- .../mediums/webrtc/webrtc_medium_impl.h | 52 -- .../mediums/webrtc/webrtc_medium_impl_test.cc | 74 -- .../mediums/webrtc/webrtc_socket_impl.cc | 203 ----- .../mediums/webrtc/webrtc_socket_impl.h | 132 --- .../mediums/webrtc/webrtc_socket_impl_test.cc | 249 ------ internal/platform/implementation/g3/webrtc.cc | 10 +- internal/platform/implementation/g3/webrtc.h | 2 +- internal/platform/implementation/webrtc.h | 4 +- 34 files changed, 9 insertions(+), 5757 deletions(-) delete mode 100644 connections/implementation/mediums/webrtc/BUILD delete mode 100644 connections/implementation/mediums/webrtc/README.md delete mode 100644 connections/implementation/mediums/webrtc/connection_flow.cc delete mode 100644 connections/implementation/mediums/webrtc/connection_flow.h delete mode 100644 connections/implementation/mediums/webrtc/connection_flow_test.cc delete mode 100644 connections/implementation/mediums/webrtc/data_channel_listener.h delete mode 100644 connections/implementation/mediums/webrtc/fake_webrtc.cc delete mode 100644 connections/implementation/mediums/webrtc/fake_webrtc.h delete mode 100644 connections/implementation/mediums/webrtc/local_ice_candidate_listener.h delete mode 100644 connections/implementation/mediums/webrtc/session_description_wrapper.h delete mode 100644 connections/implementation/mediums/webrtc/signaling_frames.cc delete mode 100644 connections/implementation/mediums/webrtc/signaling_frames.h delete mode 100644 connections/implementation/mediums/webrtc/signaling_frames_test.cc delete mode 100644 connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.cc delete mode 100644 connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h delete mode 100644 connections/implementation/mediums/webrtc/webrtc.h delete mode 100644 connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc delete mode 100644 connections/implementation/mediums/webrtc/webrtc_bwu_handler.h delete mode 100644 connections/implementation/mediums/webrtc/webrtc_bwu_handler_test.cc delete mode 100644 connections/implementation/mediums/webrtc/webrtc_endpoint_channel.cc delete mode 100644 connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h delete mode 100644 connections/implementation/mediums/webrtc/webrtc_impl.cc delete mode 100644 connections/implementation/mediums/webrtc/webrtc_impl.h delete mode 100644 connections/implementation/mediums/webrtc/webrtc_impl_test.cc delete mode 100644 connections/implementation/mediums/webrtc/webrtc_medium_impl.cc delete mode 100644 connections/implementation/mediums/webrtc/webrtc_medium_impl.h delete mode 100644 connections/implementation/mediums/webrtc/webrtc_medium_impl_test.cc delete mode 100644 connections/implementation/mediums/webrtc/webrtc_socket_impl.cc delete mode 100644 connections/implementation/mediums/webrtc/webrtc_socket_impl.h delete mode 100644 connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc diff --git a/Package.swift b/Package.swift index 81150eaa..d96c9aa4 100644 --- a/Package.swift +++ b/Package.swift @@ -345,7 +345,6 @@ let package = Package( "internal/platform/implementation/apple/Mediums/WiFiCommon/BUILD", "internal/platform/implementation/BUILD", "internal/platform/BUILD", - "internal/analytics/BUILD", "internal/flags/BUILD", "internal/network/BUILD", "internal/rpc/BUILD", @@ -369,7 +368,6 @@ let package = Package( "connections/implementation/offline_frames_validator_test.cc", "connections/implementation/service_controller_router_test.cc", "connections/implementation/analytics/analytics_recorder_impl_test.cc", - "connections/implementation/analytics/throughput_recorder_test.cc", "connections/implementation/mediums/advertisements/data_element_test.cc", "connections/implementation/mediums/advertisements/dct_advertisement_test.cc", "connections/implementation/mediums/advertisements/advertisement_util_test.cc", @@ -434,7 +432,6 @@ let package = Package( "internal/encoding/base85_test.cc", "internal/data/leveldb_data_set_test.cc", "internal/flags/nearby_flags_test.cc", - "internal/proto/analytics/connections_log_test.cc", "internal/platform/feature_flags_test.cc", "internal/platform/file_test.cc", "internal/platform/cancelable_alarm_test.cc", @@ -499,7 +496,6 @@ let package = Package( "internal/network/http_client_impl_test.cc", "internal/network/http_status_code_test.cc", "internal/test/fake_clock_test.cc", - "internal/test/fake_webrtc.cc", "internal/test/fake_timer_test.cc", "internal/test/fake_device_info_test.cc", "internal/test/fake_task_runner_test.cc", @@ -521,15 +517,9 @@ let package = Package( "proto", "internal/data/leveldb_data_set_test.proto", // webrtc - "connections/implementation/webrtc_bwu_handler.cc", - "connections/implementation/webrtc_endpoint_channel.cc", - "connections/implementation/mediums/webrtc.cc", - "connections/implementation/mediums/webrtc", - "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.cc", - "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h", "internal/platform/implementation/apple/webrtc.h", "internal/platform/implementation/apple/webrtc.mm", - // This breaks the build, but seems to work fine without it? + // Only used in tests "internal/platform/medium_environment.cc", ], sources: [ diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD deleted file mode 100644 index 5b4f0b5b..00000000 --- a/connections/implementation/mediums/webrtc/BUILD +++ /dev/null @@ -1,268 +0,0 @@ -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -# Copyright 2020 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. -licenses(["notice"]) - -cc_library( - name = "webrtc", - hdrs = [ - "data_channel_listener.h", - "local_ice_candidate_listener.h", - "session_description_wrapper.h", - ], - deps = [ - "//connections/implementation/mediums:webrtc_socket", - "//internal/platform:base", - "//third_party/webrtc/files/stable/webrtc/api:jsep", - "@com_google_absl//absl/functional:any_invocable", - ], -) - -cc_library( - name = "connection_flow", - srcs = ["connection_flow.cc"], - hdrs = ["connection_flow.h"], - deps = [ - ":webrtc", - ":webrtc_medium", - ":webrtc_socket_impl", - "//connections/implementation/mediums:webrtc_socket", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:logging", - "//internal/platform:types", - "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", - "//third_party/webrtc/files/stable/webrtc/api:jsep", - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/files/stable/webrtc/api:rtc_error", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", - "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", - "//third_party/webrtc/files/stable/webrtc/rtc_base:refcount", - "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/memory", - "@com_google_absl//absl/time", - ], -) - -cc_library( - name = "signaling_frames", - srcs = ["signaling_frames.cc"], - hdrs = ["signaling_frames.h"], - deps = [ - "//connections/implementation/mediums:webrtc_peer_id", - "//internal/platform:base", - "//proto/mediums:web_rtc_signaling_frames_cc_proto", - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - ], -) - -cc_library( - name = "webrtc_socket_impl", - srcs = ["webrtc_socket_impl.cc"], - hdrs = ["webrtc_socket_impl.h"], - deps = [ - "//connections/implementation/mediums:webrtc_socket", - "//internal/platform:base", - "//internal/platform:logging", - "//internal/platform:types", - "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings:string_view", - ], -) - -cc_library( - name = "webrtc_medium", - hdrs = ["webrtc.h"], - deps = [ - "//internal/platform:base", - "//internal/platform/implementation:webrtc_platform", - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", - "@com_google_absl//absl/strings:string_view", - ], -) - -cc_library( - name = "webrtc_medium_impl", - srcs = ["webrtc_medium_impl.cc"], - hdrs = ["webrtc_medium_impl.h"], - visibility = [ - "//internal/platform/implementation:__subpackages__", - ], - deps = [ - ":tachyon_express_signaling_messenger", - "//internal/platform/implementation:webrtc_platform", - "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/files/stable/webrtc/api:rtc_error", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", - "//third_party/webrtc/files/stable/webrtc/rtc_base:threading", - "@com_google_absl//absl/strings:string_view", - ], -) - -cc_library( - name = "webrtc_impl", - srcs = [ - "webrtc_bwu_handler.cc", - "webrtc_endpoint_channel.cc", - "webrtc_impl.cc", - ], - hdrs = [ - "webrtc_bwu_handler.h", - "webrtc_endpoint_channel.h", - "webrtc_impl.h", - ], - visibility = [ - "//connections/implementation/mediums:__pkg__", - ], - deps = [ - ":connection_flow", - ":signaling_frames", - ":webrtc", - ":webrtc_medium", - "//connections:core_types", - "//connections/implementation:bwu_handler", - "//connections/implementation:client_proxy", - "//connections/implementation:endpoint_channel", - "//connections/implementation:offline_frames", - "//connections/implementation/mediums:webrtc", - "//connections/implementation/mediums:webrtc_peer_id", - "//connections/implementation/mediums:webrtc_socket", - "//connections/implementation/proto:offline_wire_formats_cc_proto", - "//internal/platform:base", - "//internal/platform:cancellation_flag", - "//internal/platform:logging", - "//internal/platform:types", - "//internal/platform/implementation:webrtc_platform", - "//proto/mediums:web_rtc_signaling_frames_cc_proto", - "//third_party/webrtc/files/stable/webrtc/api:jsep", - "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/base:nullability", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/container:flat_hash_set", - "@com_google_absl//absl/functional:bind_front", - "@com_google_absl//absl/time", - ], -) - -cc_library( - name = "tachyon_express_signaling_messenger", - srcs = ["tachyon_express_signaling_messenger.cc"], - hdrs = ["tachyon_express_signaling_messenger.h"], - deps = [ - "//internal/account", - "//internal/platform:base", - "//internal/platform:logging", - "//internal/platform:types", - "//internal/platform/implementation:webrtc_platform", - "//internal/proto:messaging_cc_grpc_proto", - "//internal/proto:tachyon_cc_proto", - "//internal/rpc:utils", - "//location/nearby/sharing/lib/account:account_manager", - "//third_party/gloop/util/random:mt_random", - "//third_party/grpc:gpr", - "//third_party/grpc:grpc++", - "//util/random:util", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/synchronization", - "@com_google_absl//absl/time", - ], -) - -cc_library( - name = "fake_webrtc", - testonly = True, - srcs = ["fake_webrtc.cc"], - hdrs = ["fake_webrtc.h"], - deps = [ - ":webrtc_medium", - "//internal/platform:cancellation_flag", - "@com_google_absl//absl/strings:string_view", - ], -) - -cc_test( - name = "webrtc_test", - timeout = "short", - srcs = [ - "connection_flow_test.cc", - "signaling_frames_test.cc", - "webrtc_bwu_handler_test.cc", - "webrtc_impl_test.cc", - "webrtc_socket_impl_test.cc", - ], - shard_count = 16, - tags = [ - "requires-net:external", - ], - deps = [ - ":connection_flow", - ":fake_webrtc", - ":signaling_frames", - ":webrtc", - ":webrtc_impl", - ":webrtc_medium", - ":webrtc_socket_impl", - "//connections/implementation:bwu_handler", - "//connections/implementation:client_proxy", - "//connections/implementation:endpoint_channel", - "//connections/implementation:offline_frames", - "//connections/implementation/mediums:webrtc", - "//connections/implementation/mediums:webrtc_peer_id", - "//connections/implementation/mediums:webrtc_socket", - "//internal/platform:base", - "//internal/platform:cancellation_flag", - "//internal/platform:logging", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:platform_impl", - "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", - "//third_party/webrtc/files/stable/webrtc/api:jsep", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", - "//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants", - "//third_party/webrtc/files/stable/webrtc/rtc_base:refcount", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings:string_view", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - "@com_google_protobuf//:protobuf", - ], -) - -cc_test( - name = "webrtc_medium_impl_test", - size = "small", - srcs = ["webrtc_medium_impl_test.cc"], - deps = [ - ":webrtc_medium_impl", - "//internal/platform/implementation:platform_impl", - "//internal/platform/implementation:webrtc_platform", - "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface", - "//third_party/webrtc/files/stable/webrtc/api:jsep", - "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", - "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/connections/implementation/mediums/webrtc/README.md b/connections/implementation/mediums/webrtc/README.md deleted file mode 100644 index 27ad4b1b..00000000 --- a/connections/implementation/mediums/webrtc/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# WebRtc support for Nearby Connections - -This directory contains the implementation to support WebRtc in the Nearby -Connection library. - -All dependencies on webrtc MUST be limited to targets in this directory. - -## To Enable WebRtc support - -To enabled WebRtc support undefine the ```NO_WEBRTC``` preprocessor symbol in -the file **connections/implementation/mediums/mediums.cc**. - -When building using bazel, pass the build flag -```--//:enable_webrtc=true``` to set the correct symbol. - -Make sure the binary is linked with an implementation of the -```WebRtcImplementationPlatform```. \ No newline at end of file diff --git a/connections/implementation/mediums/webrtc/connection_flow.cc b/connections/implementation/mediums/webrtc/connection_flow.cc deleted file mode 100644 index d8a2578d..00000000 --- a/connections/implementation/mediums/webrtc/connection_flow.cc +++ /dev/null @@ -1,585 +0,0 @@ -// Copyright 2020 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. - -#include "connections/implementation/mediums/webrtc/connection_flow.h" - -#include -#include -#include -#include - -#include "absl/memory/memory.h" -#include "absl/time/time.h" -#include "connections/implementation/mediums/webrtc/data_channel_listener.h" -#include "connections/implementation/mediums/webrtc/local_ice_candidate_listener.h" -#include "connections/implementation/mediums/webrtc/session_description_wrapper.h" -#include "connections/implementation/mediums/webrtc/webrtc.h" -#include "connections/implementation/mediums/webrtc/webrtc_socket_impl.h" -#include "internal/platform/exception.h" -#include "internal/platform/future.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex_lock.h" -#include "internal/platform/runnable.h" -#include "webrtc/api/data_channel_interface.h" -#include "webrtc/api/jsep.h" -#include "webrtc/api/peer_connection_interface.h" -#include "webrtc/api/rtc_error.h" -#include "webrtc/api/scoped_refptr.h" -#include "webrtc/api/set_local_description_observer_interface.h" -#include "webrtc/api/set_remote_description_observer_interface.h" -#include "webrtc/rtc_base/ref_counted_object.h" -#include "webrtc/rtc_base/thread.h" - -namespace nearby { -namespace connections { -namespace mediums { - -constexpr absl::Duration ConnectionFlow::kTimeout; -constexpr absl::Duration ConnectionFlow::kPeerConnectionTimeout; - -// This is the same as the nearby data channel name. -constexpr char kDataChannelName[] = "dataChannel"; - -class CreateSessionDescriptionObserverImpl - : public webrtc::CreateSessionDescriptionObserver { - public: - CreateSessionDescriptionObserverImpl( - ConnectionFlow* connection_flow, - Future settable_future, - ConnectionFlow::State expected_entry_state, - ConnectionFlow::State exit_state) - : connection_flow_{connection_flow}, - settable_future_{settable_future}, - expected_entry_state_{expected_entry_state}, - exit_state_{exit_state} {} - - // webrtc::CreateSessionDescriptionObserver - void OnSuccess(webrtc::SessionDescriptionInterface* desc) override { - if (connection_flow_->TransitionState(expected_entry_state_, exit_state_)) { - settable_future_.Set(SessionDescriptionWrapper{desc}); - } else { - settable_future_.SetException({Exception::kFailed}); - } - } - - void OnFailure(webrtc::RTCError error) override { - LOG(ERROR) << "Error when creating session description: " - << error.message(); - settable_future_.SetException({Exception::kFailed}); - } - - private: - ConnectionFlow* connection_flow_; - Future settable_future_; - ConnectionFlow::State expected_entry_state_; - ConnectionFlow::State exit_state_; -}; - -class SetDescriptionObserverBase { - public: - ExceptionOr GetResult(absl::Duration timeout) { - return settable_future_.Get(timeout); - } - - protected: - void OnSetDescriptionComplete(webrtc::RTCError error) { - // On success, |error.ok()| is true. - if (error.ok()) { - settable_future_.Set(true); - return; - } - settable_future_.SetException({Exception::kFailed}); - } - - private: - Future settable_future_; -}; - -class SetLocalDescriptionObserver - : public webrtc::SetLocalDescriptionObserverInterface, - public SetDescriptionObserverBase { - public: - void OnSetLocalDescriptionComplete(webrtc::RTCError error) override { - OnSetDescriptionComplete(error); - } -}; - -class SetRemoteDescriptionObserver - : public webrtc::SetRemoteDescriptionObserverInterface, - public SetDescriptionObserverBase { - public: - void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override { - OnSetDescriptionComplete(error); - } -}; - -using PeerConnectionState = - webrtc::PeerConnectionInterface::PeerConnectionState; - -std::unique_ptr ConnectionFlow::Create( - LocalIceCandidateListener local_ice_candidate_listener, - DataChannelListener data_channel_listener, - AdapterTypeListener adapter_type_listener, WebRtcMedium& webrtc_medium) { - auto connection_flow = absl::WrapUnique(new ConnectionFlow( - std::move(local_ice_candidate_listener), std::move(data_channel_listener), - std::move(adapter_type_listener))); - if (connection_flow->InitPeerConnection(webrtc_medium)) { - return connection_flow; - } - - return nullptr; -} - -ConnectionFlow::ConnectionFlow( - LocalIceCandidateListener local_ice_candidate_listener, - DataChannelListener data_channel_listener, - AdapterTypeListener adapter_type_listener) - : data_channel_listener_(std::move(data_channel_listener)), - local_ice_candidate_listener_(std::move(local_ice_candidate_listener)), - adapter_type_listener_(std::move(adapter_type_listener)) {} - -ConnectionFlow::~ConnectionFlow() { - LOG(INFO) << "~ConnectionFlow"; - RunOnSignalingThread([this] { CloseOnSignalingThread(); }); - shutdown_latch_.Await(); - LOG(INFO) << "~ConnectionFlow done"; -} - -SessionDescriptionWrapper ConnectionFlow::CreateOffer() { - CHECK(!IsRunningOnSignalingThread()); - Future success_future; - if (!RunOnSignalingThread([this, success_future] { - CreateOfferOnSignalingThread(success_future); - })) { - LOG(ERROR) << "Failed to create offer"; - return SessionDescriptionWrapper(); - } - ExceptionOr result = success_future.Get(kTimeout); - if (result.ok()) { - return std::move(result.result()); - } - LOG(ERROR) << "Failed to create offer: " << result.exception(); - return SessionDescriptionWrapper(); -} - -void ConnectionFlow::CreateOfferOnSignalingThread( - Future success_future) { - if (!TransitionState(State::kInitialized, State::kCreatingOffer)) { - success_future.SetException({Exception::kFailed}); - return; - } - webrtc::DataChannelInit data_channel_init; - data_channel_init.reliable = true; - auto pc = GetPeerConnection(); - auto result = - pc->CreateDataChannelOrError(kDataChannelName, &data_channel_init); - if (!result.ok()) { - success_future.SetException({Exception::kFailed}); - return; - } - CreateSocketFromDataChannel(result.MoveValue()); - - webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; - webrtc::scoped_refptr observer( - new webrtc::RefCountedObject( - this, success_future, State::kCreatingOffer, - State::kWaitingForAnswer)); - pc->CreateOffer(observer.get(), options); -} - -SessionDescriptionWrapper ConnectionFlow::CreateAnswer() { - CHECK(!IsRunningOnSignalingThread()); - Future success_future; - if (!RunOnSignalingThread([this, success_future] { - CreateAnswerOnSignalingThread(success_future); - })) { - LOG(ERROR) << "Failed to create answer"; - return SessionDescriptionWrapper(); - } - ExceptionOr result = success_future.Get(kTimeout); - if (result.ok()) { - return std::move(result.result()); - } - LOG(ERROR) << "Failed to create answer: " << result.exception(); - return SessionDescriptionWrapper(); -} - -void ConnectionFlow::CreateAnswerOnSignalingThread( - Future success_future) { - if (!TransitionState(State::kReceivedOffer, State::kCreatingAnswer)) { - success_future.SetException({Exception::kFailed}); - return; - } - webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; - webrtc::scoped_refptr observer( - new webrtc::RefCountedObject( - this, success_future, State::kCreatingAnswer, - State::kWaitingToConnect)); - auto pc = GetPeerConnection(); - pc->CreateAnswer(observer.get(), options); -} - -bool ConnectionFlow::SetLocalSessionDescription(SessionDescriptionWrapper sdp) { - CHECK(!IsRunningOnSignalingThread()); - if (!sdp.IsValid()) return false; - - webrtc::scoped_refptr observer( - new webrtc::RefCountedObject()); - - if (!RunOnSignalingThread([this, observer, sdp = std::move(sdp)]() mutable { - if (state_ == State::kEnded) { - observer->OnSetLocalDescriptionComplete( - webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE)); - return; - } - auto pc = GetPeerConnection(); - - pc->SetLocalDescription( - std::unique_ptr(sdp.Release()), - observer); - })) { - return false; - } - - ExceptionOr result = observer->GetResult(kTimeout); - bool success = result.ok() && result.result(); - if (!success) { - LOG(ERROR) << "Failed to set local session description: " - << result.exception(); - } - return success; -} - -bool ConnectionFlow::SetRemoteSessionDescription(SessionDescriptionWrapper sdp, - State expected_entry_state, - State exit_state) { - if (!sdp.IsValid()) return false; - - webrtc::scoped_refptr observer( - new webrtc::RefCountedObject()); - - if (!RunOnSignalingThread([this, observer, sdp = std::move(sdp), - expected_entry_state, exit_state]() mutable { - if (!TransitionState(expected_entry_state, exit_state)) { - observer->OnSetRemoteDescriptionComplete( - webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE)); - return; - } - auto pc = GetPeerConnection(); - - pc->SetRemoteDescription( - std::unique_ptr(sdp.Release()), - observer); - })) { - return false; - } - - ExceptionOr result = observer->GetResult(kTimeout); - bool success = result.ok() && result.result(); - if (!success) { - LOG(ERROR) << "Failed to set remote description: " << result.exception(); - } - return success; -} - -bool ConnectionFlow::OnOfferReceived(SessionDescriptionWrapper offer) { - CHECK(!IsRunningOnSignalingThread()); - return SetRemoteSessionDescription(std::move(offer), State::kInitialized, - State::kReceivedOffer); -} - -bool ConnectionFlow::OnAnswerReceived(SessionDescriptionWrapper answer) { - CHECK(!IsRunningOnSignalingThread()); - return SetRemoteSessionDescription( - std::move(answer), State::kWaitingForAnswer, State::kWaitingToConnect); -} - -bool ConnectionFlow::OnRemoteIceCandidatesReceived( - std::vector> ice_candidates) { - CHECK(!IsRunningOnSignalingThread()); - // We can't call RunOnSignalingThread because C++ wants to copy ice_candidates - // if we try. unique_ptr is not CopyConstructible and compilation fails. - auto pc = GetPeerConnection(); - - if (!pc) { - return false; - } - pc->signaling_thread()->PostTask( - [this, can_run_tasks = std::weak_ptr(can_run_tasks_), - candidates = std::move(ice_candidates)]() mutable { - // Don't run the task if the weak_ptr is no longer valid. - if (!can_run_tasks.lock()) { - return; - } - AddIceCandidatesOnSignalingThread(std::move(candidates)); - }); - return true; -} - -void ConnectionFlow::AddIceCandidatesOnSignalingThread( - std::vector> ice_candidates) { - CHECK(IsRunningOnSignalingThread()); - if (state_ == State::kEnded) { - LOG(WARNING) << "You cannot add ice candidates to a disconnected session."; - return; - } - if (state_ != State::kWaitingToConnect && state_ != State::kConnected) { - cached_remote_ice_candidates_.insert( - cached_remote_ice_candidates_.end(), - std::make_move_iterator(ice_candidates.begin()), - std::make_move_iterator(ice_candidates.end())); - return; - } - auto pc = GetPeerConnection(); - for (auto&& ice_candidate : ice_candidates) { - if (!pc->AddIceCandidate(ice_candidate.get())) { - LOG(WARNING) << "Unable to add remote ice candidate."; - } - } -} - -bool ConnectionFlow::CloseIfNotConnected() { - CHECK(!IsRunningOnSignalingThread()); - Future closed; - if (RunOnSignalingThread([this, closed]() mutable { - if (state_ == State::kConnected) { - closed.Set(false); - } else { - CloseOnSignalingThread(); - closed.Set(true); - } - })) { - auto result = closed.Get(); - return result.ok() && result.result(); - } - return true; -} - -bool ConnectionFlow::InitPeerConnection(WebRtcMedium& webrtc_medium) { - Future success_future; - // CreatePeerConnection callback may be invoked after ConnectionFlow lifetime - // has ended, in case of a timeout. Future is captured by value, and is safe - // to access, but it is not safe to access ConnectionFlow member variables - // unless the Future::Set() returns true. - webrtc_medium.CreatePeerConnection( - this, [this, success_future]( - webrtc::scoped_refptr - peer_connection) mutable { - if (!peer_connection) { - success_future.Set(false); - return; - } - - // If this fails, means we have already assigned something to - // success_future; it is either: - // 1) this is the 2nd call of this callback (and this is a bug), or - // 2) Get(timeout) has set the future value as exception already. - if (success_future.IsSet()) return; - MutexLock lock(&mutex_); - peer_connection_ = peer_connection; - signaling_thread_for_dcheck_only_ = - peer_connection_->signaling_thread(); - success_future.Set(true); - }); - - ExceptionOr result = success_future.Get(kPeerConnectionTimeout); - bool success = result.ok() && result.result(); - if (!success) { - shutdown_latch_.CountDown(); - LOG(ERROR) << "Failed to create peer connection: " << result.exception(); - } - return success; -} - -void ConnectionFlow::OnSignalingStable() { - if (state_ != State::kWaitingToConnect && state_ != State::kConnected) return; - auto pc = GetPeerConnection(); - for (auto&& ice_candidate : cached_remote_ice_candidates_) { - if (!pc->AddIceCandidate(ice_candidate.get())) { - LOG(WARNING) << "Unable to add remote ice candidate."; - } - } - cached_remote_ice_candidates_.clear(); -} - -void ConnectionFlow::CreateSocketFromDataChannel( - webrtc::scoped_refptr data_channel) { - LOG(INFO) << "Creating data channel socket"; - auto socket = std::make_shared("WebRtcSocket", - std::move(data_channel)); - socket_ = socket; - socket->SetSocketListener({ - .socket_ready_cb = {[this](WebRtcSocketImpl* socket) { - CHECK(IsRunningOnSignalingThread()); - if (!TransitionState(State::kWaitingToConnect, State::kConnected)) { - LOG(ERROR) << "Data channel socket is open but connection " - "flow was not in the required state"; - socket->Close(); - return; - } - // Pass socket wrapper by copy on purpose - data_channel_listener_.data_channel_open_cb(socket_); - }}, - .socket_closed_cb = - [this](WebRtcSocketImpl*) { - data_channel_listener_.data_channel_closed_cb(); - }, - }); -} - -void ConnectionFlow::OnIceCandidate(const webrtc::IceCandidate* candidate) { - CHECK(IsRunningOnSignalingThread()); - local_ice_candidate_listener_.local_ice_candidate_found_cb(candidate); -} - -void ConnectionFlow::OnSignalingChange( - webrtc::PeerConnectionInterface::SignalingState new_state) { - LOG(INFO) << "OnSignalingChange: " << new_state; - CHECK(IsRunningOnSignalingThread()); - if (new_state == webrtc::PeerConnectionInterface::SignalingState::kStable) { - OnSignalingStable(); - } -} - -void ConnectionFlow::OnDataChannel( - webrtc::scoped_refptr data_channel) { - LOG(INFO) << "OnDataChannel"; - CHECK(IsRunningOnSignalingThread()); - CreateSocketFromDataChannel(std::move(data_channel)); -} - -void ConnectionFlow::OnIceGatheringChange( - webrtc::PeerConnectionInterface::IceGatheringState new_state) { - LOG(INFO) << "OnIceGatheringChange: " << new_state; - CHECK(IsRunningOnSignalingThread()); -} - -void ConnectionFlow::OnConnectionChange( - webrtc::PeerConnectionInterface::PeerConnectionState new_state) { - LOG(INFO) << "OnConnectionChange: " << static_cast(new_state); - CHECK(IsRunningOnSignalingThread()); - if (new_state == PeerConnectionState::kClosed || - new_state == PeerConnectionState::kFailed || - new_state == PeerConnectionState::kDisconnected) { - LOG(INFO) << "Closing due to peer connection state change: " - << static_cast(new_state); - CloseOnSignalingThread(); - } -} - -void ConnectionFlow::OnRenegotiationNeeded() { - LOG(INFO) << "OnRenegotiationNeeded"; - CHECK(IsRunningOnSignalingThread()); -} - -void ConnectionFlow::OnIceSelectedCandidatePairChanged( - const webrtc::CandidatePairChangeEvent& event) { - LOG(INFO) << "OnIceSelectedCandidatePairChanged"; - CHECK(IsRunningOnSignalingThread()); - // TODO(edwinwu) - Implement the unit test for this. We should be able to get - // the adapter type from the PeerConnection. - adapter_type_listener_.adapter_type_changed_cb( - event.selected_candidate_pair.local_candidate().network_type()); -} - -bool ConnectionFlow::TransitionState(State current_state, State new_state) { - CHECK(IsRunningOnSignalingThread()); - if (current_state != state_) { - LOG(WARNING) << "Invalid state transition to " - << static_cast(new_state) << ": current state is " - << static_cast(state_) << " but expected " - << static_cast(current_state); - return false; - } - LOG(INFO) << "Transition: " << static_cast(state_) << "->" - << static_cast(new_state); - state_ = new_state; - return true; -} - -bool ConnectionFlow::CloseOnSignalingThread() { - if (state_ == State::kEnded) { - return false; - } - state_ = State::kEnded; - // Close the socket wrapper before terminating the PeerConnection - // since the teardown process of the PC may close threads that are - // otherwise depended upon by objects kept alive by the socket_wrapper. - if (socket_ && socket_->IsValid()) socket_->Close(); - - // This prevents other tasks from queuing on the signaling thread for this - // object. - auto pc = GetAndResetPeerConnection(); - - LOG(INFO) << "Closing WebRTC peer connection."; - // NOTE: Closing the peer connection will close the data channel and thus the - // socket implicitly. - if (pc) pc->Close(); - LOG(INFO) << "Closed WebRTC peer connection."; - // Prevent any already queued tasks from running on the signaling thread - can_run_tasks_.reset(); - // If anyone was waiting for shutdown to be done let them know. - shutdown_latch_.CountDown(); - return true; -} - -bool ConnectionFlow::RunOnSignalingThread(Runnable&& runnable) { - CHECK(!IsRunningOnSignalingThread()); - auto pc = GetPeerConnection(); - if (!pc) { - LOG(WARNING) << "Peer connection not available. Cannot schedule tasks."; - return false; - } - // We are off signaling thread, so we can't use peer connection's methods - // but we can access the signaling thread handle. - pc->signaling_thread()->PostTask( - [can_run_tasks = std::weak_ptr(can_run_tasks_), - task = std::move(runnable)]() mutable { - // Don't run the task if the weak_ptr is no longer valid. - // shared_ptr |can_run_tasks_| is destroyed on the same thread - // (signaling thread). This guarantees that if the weak_ptr is valid - // when this task starts, it will stay valid until the task ends. - if (!can_run_tasks.lock()) { - LOG(INFO) << "Peer connection already closed. Cannot run tasks."; - return; - } - task(); - }); - return true; -} - -bool ConnectionFlow::IsRunningOnSignalingThread() { - return signaling_thread_for_dcheck_only_ != nullptr && - signaling_thread_for_dcheck_only_ == webrtc::Thread::Current(); -} - -webrtc::scoped_refptr -ConnectionFlow::GetPeerConnection() { - // We must use a mutex to ensure that peer connection is - // fully initialized. - // We increase the peer_connection_'s refcount to keep it - // alive while we use it. - MutexLock lock(&mutex_); - return peer_connection_; -} - -webrtc::scoped_refptr -ConnectionFlow::GetAndResetPeerConnection() { - MutexLock lock(&mutex_); - return std::move(peer_connection_); -} - -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/webrtc/connection_flow.h b/connections/implementation/mediums/webrtc/connection_flow.h deleted file mode 100644 index 01c808c1..00000000 --- a/connections/implementation/mediums/webrtc/connection_flow.h +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_CONNECTION_FLOW_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_CONNECTION_FLOW_H_ - -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/functional/any_invocable.h" -#include "absl/time/time.h" -#include "connections/implementation/mediums/webrtc/data_channel_listener.h" -#include "connections/implementation/mediums/webrtc/local_ice_candidate_listener.h" -#include "connections/implementation/mediums/webrtc/session_description_wrapper.h" -#include "connections/implementation/mediums/webrtc/webrtc.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/future.h" -#include "internal/platform/listeners.h" -#include "internal/platform/mutex.h" -#include "internal/platform/runnable.h" -#include "webrtc/api/data_channel_interface.h" -#include "webrtc/api/jsep.h" -#include "webrtc/api/peer_connection_interface.h" -#include "webrtc/api/scoped_refptr.h" -#include "webrtc/rtc_base/network_constants.h" - -namespace nearby { -namespace connections { -namespace mediums { - -/** - * Flow for an offerer: - * - *

    - *
  • INITIALIZED: After construction. - *
  • CREATING_OFFER: After CreateOffer(). Local ice candidate collection - * begins. - *
  • WAITING_FOR_ANSWER: Until the remote peer sends their answer. - *
  • WAITING_TO_CONNECT: Until the data channel actually connects. Remote - * ice candidates should be added with OnRemoteIceCandidatesReceived as they are - * gathered. - *
  • CONNECTED: We successfully connected to the remote data - * channel. - *
  • ENDED: The final state that can occur from any of the previous - * states if we disconnect at any point in the flow. - *
- * - *

Flow for an answerer: - * - *

    - *
  • INITIALIZED: After construction. - *
  • RECEIVED_OFFER: After onOfferReceived(). - *
  • CREATING_ANSWER: After CreateAnswer(). Local ice candidate collection - * begins. - *
  • WAITING_TO_CONNECT: Until the data channel actually connects. - * Remote ice candidates should be added with OnRemoteIceCandidatesReceived as - * they are gathered. - *
  • CONNECTED: We successfully connected to the remote - * data channel. - *
  • ENDED: The final state that can occur from any of the - * previous states if we disconnect at any point in the flow. - *
- */ -class ConnectionFlow : public webrtc::PeerConnectionObserver { - public: - enum class State { - kInitialized, - kCreatingOffer, - kWaitingForAnswer, - kReceivedOffer, - kCreatingAnswer, - kWaitingToConnect, - kConnected, - kEnded, - }; - - struct AdapterTypeListener { - absl::AnyInvocable - adapter_type_changed_cb = DefaultCallback(); - }; - - // This method blocks on the creation of the peer connection object. - // Can be called on any thread but never called on signaling thread. - static std::unique_ptr Create( - LocalIceCandidateListener local_ice_candidate_listener, - DataChannelListener data_channel_listener, - AdapterTypeListener adapter_type_listener, WebRtcMedium& webrtc_medium); - ~ConnectionFlow() override; - - // Create the offer that will be sent to the remote. Mirrors the behaviour of - // PeerConnectionInterface::CreateOffer. - // Can be called on any thread but never called on signaling thread. - SessionDescriptionWrapper CreateOffer() ABSL_LOCKS_EXCLUDED(mutex_); - // Create the answer that will be sent to the remote. Mirrors the behaviour of - // PeerConnectionInterface::CreateAnswer. - // Can be called on any thread but never called on signaling thread. - SessionDescriptionWrapper CreateAnswer() ABSL_LOCKS_EXCLUDED(mutex_); - // Set the local session description. |sdp| was created via CreateOffer() - // or CreateAnswer(). - // Can be called on any thread but never called on signaling thread. - bool SetLocalSessionDescription(SessionDescriptionWrapper sdp) - ABSL_LOCKS_EXCLUDED(mutex_); - // Invoked when an offer was received from a remote; this will set the remote - // session description on the peer connection. Returns true if the offer was - // successfully set as remote session description. - // Can be called on any thread but never called on signaling thread. - bool OnOfferReceived(SessionDescriptionWrapper offer) - ABSL_LOCKS_EXCLUDED(mutex_); - // Invoked when an answer was received from a remote; this will set the remote - // session description on the peer connection. Returns true if the offer was - // successfully set as remote session description. - // Can be called on any thread but never called on signaling thread. - bool OnAnswerReceived(SessionDescriptionWrapper answer) - ABSL_LOCKS_EXCLUDED(mutex_); - // Invoked when an ice candidate was received from a remote; this will add the - // ice candidate to the peer connection if ready or cache it otherwise. - // Can be called on any thread but never called on signaling thread. - bool OnRemoteIceCandidatesReceived( - std::vector> ice_candidates) - ABSL_LOCKS_EXCLUDED(mutex_); - // Close the peer connection and data channel if not connected. - // Can be called on any thread but never called on signaling thread. - bool CloseIfNotConnected() ABSL_LOCKS_EXCLUDED(mutex_); - - // webrtc::PeerConnectionObserver: - // All methods called only on signaling thread. - void OnIceCandidate(const webrtc::IceCandidate* candidate) override; - void OnSignalingChange( - webrtc::PeerConnectionInterface::SignalingState new_state) override; - void OnDataChannel(webrtc::scoped_refptr - data_channel) override; - void OnIceGatheringChange( - webrtc::PeerConnectionInterface::IceGatheringState new_state) override; - void OnConnectionChange( - webrtc::PeerConnectionInterface::PeerConnectionState new_state) override; - void OnRenegotiationNeeded() override; - void OnIceSelectedCandidatePairChanged( - const webrtc::CandidatePairChangeEvent& event) override; - - // Public because it's used in tests too. - webrtc::scoped_refptr GetPeerConnection(); - - private: - ConnectionFlow(LocalIceCandidateListener local_ice_candidate_listener, - DataChannelListener data_channel_listener, - AdapterTypeListener adapter_type_listener); - - // Resets peer connection reference. Returns old value. - webrtc::scoped_refptr - GetAndResetPeerConnection(); - void CreateOfferOnSignalingThread( - Future success_future); - void CreateAnswerOnSignalingThread( - Future success_future); - void AddIceCandidatesOnSignalingThread( - std::vector> ice_candidates); - // Invoked when the peer connection indicates that signaling is stable. - void OnSignalingStable() ABSL_LOCKS_EXCLUDED(mutex_); - - void CreateSocketFromDataChannel( - webrtc::scoped_refptr data_channel); - - // TODO(bfranz): Consider whether this needs to be configurable per platform - static constexpr absl::Duration kTimeout = absl::Milliseconds(250); - static constexpr absl::Duration kPeerConnectionTimeout = - absl::Milliseconds(2500); - - bool InitPeerConnection(WebRtcMedium& webrtc_medium); - - bool TransitionState(State current_state, State new_state); - - bool SetRemoteSessionDescription(SessionDescriptionWrapper sdp, - State expected_entry_state, - State exit_state); - - bool CloseOnSignalingThread() ABSL_LOCKS_EXCLUDED(mutex_); - - bool RunOnSignalingThread(Runnable&& runnable); - bool IsRunningOnSignalingThread(); - - Mutex mutex_; - // Used to prevent the destructor from returning while the signaling thread is - // still running CloseOnSignalingThread() - CountDownLatch shutdown_latch_{1}; - - // State is used on signaling thread only. - State state_ = State::kInitialized; - // Used to communicate data channel events back to the caller of Create() - DataChannelListener data_channel_listener_; - - LocalIceCandidateListener local_ice_candidate_listener_; - // Peer connection can be used only on signaling thread. The only exception - // is accessing the signaling thread handle. Tasks posted on the - // signaling thread may outlive both |peer_connection_| and |this| objects. - // A mutex is required to access peer connection reference because peer - // connection object and the reference can be initialized on different - // threads - the reference could be initialized before peer connection's - // constructor has finished. - // |peer_connection_| is actually implemented by PeerConnectionProxy, which - // runs the real PeerConnection's methods on the correct thread (signaling or - // worker). If a proxy method is called on the correct thread, then the real - // method is called directly. Otherwise, a task is posted on the correct - // thread and the current thread is blocked until that task finishes. We - // choose to explicitly use |peer_connection_| on the signaling thread, - // because it allows us to do state management on the signaling thread too, - // simplifies locking, and we don't have to block the current thread for every - // peer connection call. - webrtc::scoped_refptr peer_connection_ - ABSL_GUARDED_BY(mutex_); - - // Used to hold a reference to the WebRtcSocket while the data channel is - // connecting. - std::shared_ptr socket_; - - std::vector> - cached_remote_ice_candidates_; - // This pointer is only for DCHECK() assertions. - // It allows us to check if we are running on signaling thread even - // after destroying |peer_connection_|. - const void* signaling_thread_for_dcheck_only_ = nullptr; - // This shared_ptr is reset on the signaling thread when ConnectionFlow is - // closed. This prevents us from running tasks on the signaling thread when - // peer connection is closed. The value stored in |can_run_tasks_| is not - // used. We are using std::shared_ptr instead of webrtc::WeakPtrFactory - // because the former is thread-safe. - std::shared_ptr can_run_tasks_ = std::make_shared(); - - AdapterTypeListener adapter_type_listener_; - - friend class CreateSessionDescriptionObserverImpl; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_CONNECTION_FLOW_H_ diff --git a/connections/implementation/mediums/webrtc/connection_flow_test.cc b/connections/implementation/mediums/webrtc/connection_flow_test.cc deleted file mode 100644 index 0145fb47..00000000 --- a/connections/implementation/mediums/webrtc/connection_flow_test.cc +++ /dev/null @@ -1,445 +0,0 @@ -// Copyright 2020 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. - -#include "connections/implementation/mediums/webrtc/connection_flow.h" - -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "connections/implementation/mediums/webrtc/data_channel_listener.h" -#include "connections/implementation/mediums/webrtc/local_ice_candidate_listener.h" -#include "connections/implementation/mediums/webrtc/session_description_wrapper.h" -#include "connections/implementation/mediums/webrtc/webrtc.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/exception.h" -#include "internal/platform/future.h" -#include "internal/platform/medium_environment.h" -#include "webrtc/api/jsep.h" -#include "webrtc/api/scoped_refptr.h" -#include "webrtc/rtc_base/network_constants.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace { - -class ConnectionFlowTest : public ::testing::Test { - protected: - ConnectionFlowTest() { - MediumEnvironment::Instance().Start({.webrtc_enabled = true}); - } - ~ConnectionFlowTest() override { MediumEnvironment::Instance().Stop(); } -}; - -std::unique_ptr CopyCandidate( - const webrtc::IceCandidate* candidate) { - return webrtc::CreateIceCandidate(candidate->sdp_mid(), - candidate->sdp_mline_index(), - candidate->candidate()); -} - -// TODO(bfranz) - Add test that deterministically sends answerer_ice_candidates -// before answer is sent. -TEST_F(ConnectionFlowTest, SuccessfulOfferAnswerFlow) { - WebRtcMedium webrtc_medium_offerer, webrtc_medium_answerer; - - Future message_received_future; - - Future> offerer_socket_future, - answerer_socket_future; - - std::unique_ptr offerer, answerer; - - // Send Ice Candidates immediately when you retrieve them - offerer = ConnectionFlow::Create( - {.local_ice_candidate_found_cb = - [&answerer](const webrtc::IceCandidate* candidate) { - std::vector> vec; - vec.push_back(CopyCandidate(candidate)); - // The callback might be alive while the objects in test are - // destroyed. - if (answerer) - answerer->OnRemoteIceCandidatesReceived(std::move(vec)); - }}, - {.data_channel_open_cb = - [&offerer_socket_future](std::shared_ptr socket) { - offerer_socket_future.Set(std::move(socket)); - }}, - {.adapter_type_changed_cb = - [](webrtc::AdapterType adapter_type) { - // Do nothing - }}, - webrtc_medium_offerer); - ASSERT_NE(offerer, nullptr); - answerer = ConnectionFlow::Create( - {.local_ice_candidate_found_cb = - [&offerer](const webrtc::IceCandidate* candidate) { - std::vector> vec; - vec.push_back(CopyCandidate(candidate)); - // The callback might be alive while the objects in test are - // destroyed. - if (offerer) - offerer->OnRemoteIceCandidatesReceived(std::move(vec)); - }}, - {.data_channel_open_cb = - [&answerer_socket_future](std::shared_ptr socket) { - answerer_socket_future.Set(std::move(socket)); - }}, - {.adapter_type_changed_cb = - [](webrtc::AdapterType adapter_type) { - // Do nothing - }}, - webrtc_medium_answerer); - ASSERT_NE(answerer, nullptr); - - // Create and send offer - SessionDescriptionWrapper offer = offerer->CreateOffer(); - ASSERT_TRUE(offer.IsValid()); - EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer); - EXPECT_TRUE(answerer->OnOfferReceived(offer)); - EXPECT_TRUE(offerer->SetLocalSessionDescription(std::move(offer))); - - // Create and send answer - SessionDescriptionWrapper answer = answerer->CreateAnswer(); - ASSERT_TRUE(answer.IsValid()); - EXPECT_EQ(answer.GetType(), webrtc::SdpType::kAnswer); - EXPECT_TRUE(offerer->OnAnswerReceived(answer)); - EXPECT_TRUE(answerer->SetLocalSessionDescription(std::move(answer))); - - // Retrieve Data Channels - ExceptionOr> offerer_socket = - offerer_socket_future.Get(absl::Seconds(1)); - EXPECT_TRUE(offerer_socket.ok()); - ExceptionOr> answerer_socket = - answerer_socket_future.Get(absl::Seconds(1)); - EXPECT_TRUE(answerer_socket.ok()); - - // Send message on data channel - absl::string_view message = "Test"; - offerer_socket.result()->GetOutputStream().Write(message); - ExceptionOr received_message = - answerer_socket.result()->GetInputStream().Read(4); - EXPECT_TRUE(received_message.ok()); - EXPECT_EQ(received_message.result(), ByteArray{message.data()}); -} - -TEST_F(ConnectionFlowTest, CreateAnswerBeforeOfferReceived) { - WebRtcMedium webrtc_medium; - - std::unique_ptr answerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), - ConnectionFlow::AdapterTypeListener(), webrtc_medium); - ASSERT_NE(answerer, nullptr); - - SessionDescriptionWrapper answer = answerer->CreateAnswer(); - EXPECT_FALSE(answer.IsValid()); -} - -TEST_F(ConnectionFlowTest, SetAnswerBeforeOffer) { - WebRtcMedium webrtc_medium_offerer, webrtc_medium_answerer; - - std::unique_ptr offerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), - ConnectionFlow::AdapterTypeListener(), webrtc_medium_offerer); - ASSERT_NE(offerer, nullptr); - std::unique_ptr answerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), - ConnectionFlow::AdapterTypeListener(), webrtc_medium_answerer); - ASSERT_NE(answerer, nullptr); - - SessionDescriptionWrapper offer = offerer->CreateOffer(); - ASSERT_TRUE(offer.IsValid()); - EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer); - // Did not set offer as local session description - EXPECT_TRUE(answerer->OnOfferReceived(offer)); - - SessionDescriptionWrapper answer = answerer->CreateAnswer(); - ASSERT_TRUE(answer.IsValid()); - EXPECT_EQ(answer.GetType(), webrtc::SdpType::kAnswer); - EXPECT_FALSE(offerer->OnAnswerReceived(answer)); -} - -TEST_F(ConnectionFlowTest, CannotCreateOfferAfterClose) { - WebRtcMedium webrtc_medium; - - std::unique_ptr offerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), - ConnectionFlow::AdapterTypeListener(), webrtc_medium); - ASSERT_NE(offerer, nullptr); - - EXPECT_TRUE(offerer->CloseIfNotConnected()); - - EXPECT_FALSE(offerer->CreateOffer().IsValid()); -} - -TEST_F(ConnectionFlowTest, CannotSetSessionDescriptionAfterClose) { - WebRtcMedium webrtc_medium; - - std::unique_ptr offerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), - ConnectionFlow::AdapterTypeListener(), webrtc_medium); - ASSERT_NE(offerer, nullptr); - - SessionDescriptionWrapper offer = offerer->CreateOffer(); - ASSERT_TRUE(offer.IsValid()); - EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer); - - EXPECT_TRUE(offerer->CloseIfNotConnected()); - - EXPECT_FALSE(offerer->SetLocalSessionDescription(offer)); -} - -TEST_F(ConnectionFlowTest, CannotReceiveOfferAfterClose) { - WebRtcMedium webrtc_medium_offerer, webrtc_medium_answerer; - - std::unique_ptr offerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), - ConnectionFlow::AdapterTypeListener(), webrtc_medium_offerer); - ASSERT_NE(offerer, nullptr); - std::unique_ptr answerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), - ConnectionFlow::AdapterTypeListener(), webrtc_medium_answerer); - ASSERT_NE(answerer, nullptr); - - EXPECT_TRUE(answerer->CloseIfNotConnected()); - - SessionDescriptionWrapper offer = offerer->CreateOffer(); - ASSERT_TRUE(offer.IsValid()); - EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer); - - EXPECT_FALSE(answerer->OnOfferReceived(offer)); -} - -TEST_F(ConnectionFlowTest, NullPeerConnection) { - MediumEnvironment::Instance().SetUseValidPeerConnection( - /*use_valid_peer_connection=*/false); - - WebRtcMedium medium; - std::unique_ptr answerer = - ConnectionFlow::Create(LocalIceCandidateListener(), DataChannelListener(), - ConnectionFlow::AdapterTypeListener(), medium); - EXPECT_EQ(answerer, nullptr); -} - -TEST_F(ConnectionFlowTest, PeerConnectionTimeout) { - MediumEnvironment::Instance().SetUseValidPeerConnection( - /*use_valid_peer_connection=*/true); - WebRtcMedium medium1; - std::unique_ptr flow1 = - ConnectionFlow::Create(LocalIceCandidateListener(), DataChannelListener(), - ConnectionFlow::AdapterTypeListener(), medium1); - EXPECT_NE(flow1, nullptr); - - // Attempt to trigger the 2.5s peer connection timeout. - MediumEnvironment::Instance().SetPeerConnectionLatency(absl::Seconds(5)); - WebRtcMedium medium2; - std::unique_ptr flow2 = - ConnectionFlow::Create(LocalIceCandidateListener(), DataChannelListener(), - ConnectionFlow::AdapterTypeListener(), medium2); - EXPECT_EQ(flow2, nullptr); -} - -TEST_F(ConnectionFlowTest, TerminateAnswerer) { - WebRtcMedium webrtc_medium_offerer, webrtc_medium_answerer; - - Future message_received_future; - - Future> offerer_socket_future, - answerer_socket_future; - - std::unique_ptr offerer, answerer; - - // Send Ice Candidates immediately when you retrieve them - offerer = ConnectionFlow::Create( - {.local_ice_candidate_found_cb = - [&answerer](const webrtc::IceCandidate* candidate) { - std::vector> vec; - vec.push_back(CopyCandidate(candidate)); - // The callback might be alive while the objects in test are - // destroyed. - if (answerer) - answerer->OnRemoteIceCandidatesReceived(std::move(vec)); - }}, - {.data_channel_open_cb = - [&offerer_socket_future](std::shared_ptr socket) { - offerer_socket_future.Set(std::move(socket)); - }}, - {.adapter_type_changed_cb = - [](webrtc::AdapterType adapter_type) { - // Do nothing - }}, - webrtc_medium_offerer); - ASSERT_NE(offerer, nullptr); - answerer = ConnectionFlow::Create( - {.local_ice_candidate_found_cb = - [&offerer](const webrtc::IceCandidate* candidate) { - std::vector> vec; - vec.push_back(CopyCandidate(candidate)); - // The callback might be alive while the objects in test are - // destroyed. - if (offerer) - offerer->OnRemoteIceCandidatesReceived(std::move(vec)); - }}, - {.data_channel_open_cb = - [&answerer_socket_future](std::shared_ptr wrapper) { - answerer_socket_future.Set(std::move(wrapper)); - }}, - {.adapter_type_changed_cb = - [](webrtc::AdapterType adapter_type) { - EXPECT_GE(adapter_type, webrtc::ADAPTER_TYPE_UNKNOWN); - EXPECT_LE(adapter_type, webrtc::ADAPTER_TYPE_CELLULAR_5G); - }}, - webrtc_medium_answerer); - ASSERT_NE(answerer, nullptr); - - // Create and send offer - SessionDescriptionWrapper offer = offerer->CreateOffer(); - ASSERT_TRUE(offer.IsValid()); - EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer); - EXPECT_TRUE(answerer->OnOfferReceived(offer)); - EXPECT_TRUE(offerer->SetLocalSessionDescription(std::move(offer))); - - // Create and send answer - SessionDescriptionWrapper answer = answerer->CreateAnswer(); - ASSERT_TRUE(answer.IsValid()); - EXPECT_EQ(answer.GetType(), webrtc::SdpType::kAnswer); - EXPECT_TRUE(offerer->OnAnswerReceived(answer)); - EXPECT_TRUE(answerer->SetLocalSessionDescription(std::move(answer))); - - // Retrieve Data Channels - ExceptionOr> offerer_socket = - offerer_socket_future.Get(absl::Seconds(1)); - EXPECT_TRUE(offerer_socket.ok()); - ExceptionOr> answerer_socket = - answerer_socket_future.Get(absl::Seconds(1)); - EXPECT_TRUE(offerer_socket.ok()); - - CountDownLatch latch(1); - auto pc = answerer->GetPeerConnection(); - pc->signaling_thread()->PostTask([pc, latch]() mutable { - pc->Close(); - latch.CountDown(); - }); - latch.Await(); - - // Send message on data channel - absl::string_view message = "Test"; - offerer_socket.result()->GetOutputStream().Write(message); - ExceptionOr received_message = - answerer_socket.result()->GetInputStream().Read(4); - EXPECT_TRUE(received_message.GetResult().Empty()); -} - -TEST_F(ConnectionFlowTest, TerminateOfferer) { - WebRtcMedium webrtc_medium_offerer, webrtc_medium_answerer; - - Future message_received_future; - - Future> offerer_socket_future, - answerer_socket_future; - - std::unique_ptr offerer, answerer; - - // Send Ice Candidates immediately when you retrieve them - offerer = ConnectionFlow::Create( - {.local_ice_candidate_found_cb = - [&answerer](const webrtc::IceCandidate* candidate) { - std::vector> vec; - vec.push_back(CopyCandidate(candidate)); - // The callback might be alive while the objects in test are - // destroyed. - if (answerer) - answerer->OnRemoteIceCandidatesReceived(std::move(vec)); - }}, - {.data_channel_open_cb = - [&offerer_socket_future](std::shared_ptr socket) { - offerer_socket_future.Set(std::move(socket)); - }}, - {.adapter_type_changed_cb = - [](webrtc::AdapterType adapter_type) { - EXPECT_GE(adapter_type, webrtc::ADAPTER_TYPE_UNKNOWN); - EXPECT_LE(adapter_type, webrtc::ADAPTER_TYPE_CELLULAR_5G); - }}, - webrtc_medium_offerer); - ASSERT_NE(offerer, nullptr); - answerer = ConnectionFlow::Create( - {.local_ice_candidate_found_cb = - [&offerer](const webrtc::IceCandidate* candidate) { - std::vector> vec; - vec.push_back(CopyCandidate(candidate)); - // The callback might be alive while the objects in test are - // destroyed. - if (offerer) - offerer->OnRemoteIceCandidatesReceived(std::move(vec)); - }}, - {.data_channel_open_cb = - [&answerer_socket_future](std::shared_ptr wrapper) { - answerer_socket_future.Set(std::move(wrapper)); - }}, - {.adapter_type_changed_cb = - [](webrtc::AdapterType adapter_type) { - EXPECT_GE(adapter_type, webrtc::ADAPTER_TYPE_UNKNOWN); - EXPECT_LE(adapter_type, webrtc::ADAPTER_TYPE_CELLULAR_5G); - }}, - webrtc_medium_answerer); - ASSERT_NE(answerer, nullptr); - - // Create and send offer - SessionDescriptionWrapper offer = offerer->CreateOffer(); - ASSERT_TRUE(offer.IsValid()); - EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer); - EXPECT_TRUE(answerer->OnOfferReceived(offer)); - EXPECT_TRUE(offerer->SetLocalSessionDescription(std::move(offer))); - - // Create and send answer - SessionDescriptionWrapper answer = answerer->CreateAnswer(); - ASSERT_TRUE(answer.IsValid()); - EXPECT_EQ(answer.GetType(), webrtc::SdpType::kAnswer); - EXPECT_TRUE(offerer->OnAnswerReceived(answer)); - EXPECT_TRUE(answerer->SetLocalSessionDescription(std::move(answer))); - - // Retrieve Data Channels - ExceptionOr> offerer_socket = - offerer_socket_future.Get(absl::Seconds(1)); - EXPECT_TRUE(offerer_socket.ok()); - ExceptionOr> answerer_socket = - answerer_socket_future.Get(absl::Seconds(1)); - EXPECT_TRUE(offerer_socket.ok()); - - CountDownLatch latch(1); - auto pc = offerer->GetPeerConnection(); - pc->signaling_thread()->PostTask([pc, latch]() mutable { - pc->Close(); - latch.CountDown(); - }); - latch.Await(); - - // Send message on data channel - absl::string_view message = "Test"; - offerer_socket.result()->GetOutputStream().Write(message); - ExceptionOr received_message = - answerer_socket.result()->GetInputStream().Read(4); - EXPECT_TRUE(received_message.GetResult().Empty()); -} - -} // namespace -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/webrtc/data_channel_listener.h b/connections/implementation/mediums/webrtc/data_channel_listener.h deleted file mode 100644 index cb4e39b3..00000000 --- a/connections/implementation/mediums/webrtc/data_channel_listener.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_ - -#include - -#include "absl/functional/any_invocable.h" -#include "connections/implementation/mediums/webrtc_socket.h" - -namespace nearby { -namespace connections { -namespace mediums { - -// Callbacks from the data channel. -struct DataChannelListener { - // Called when the data channel is open and the socket wrapper is ready to - // read and write. - absl::AnyInvocable)> data_channel_open_cb = - [](std::shared_ptr) {}; - - // Called when the data channel is closed. - absl::AnyInvocable data_channel_closed_cb = []() {}; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_ diff --git a/connections/implementation/mediums/webrtc/fake_webrtc.cc b/connections/implementation/mediums/webrtc/fake_webrtc.cc deleted file mode 100644 index 6f829d94..00000000 --- a/connections/implementation/mediums/webrtc/fake_webrtc.cc +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2023 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. - -#include "connections/implementation/mediums/webrtc/fake_webrtc.h" - -#include - -#include "absl/strings/string_view.h" -#include "connections/implementation/mediums/webrtc/webrtc.h" -#include "internal/platform/cancellation_flag.h" - -namespace nearby::connections::mediums { - -FakeWebRtcMedium::FakeWebRtcMedium(CancellationFlag* flag) - : WebRtcMedium(), flag_(flag) {} - -FakeWebRtcMedium::~FakeWebRtcMedium() = default; - -std::unique_ptr -FakeWebRtcMedium::GetSignalingMessenger( - absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint) { - if (cancel_during_get_signaling_messenger_) { - flag_->Cancel(); - } - - return WebRtcMedium::GetSignalingMessenger(self_id, location_hint); -} - -} // namespace nearby::connections::mediums diff --git a/connections/implementation/mediums/webrtc/fake_webrtc.h b/connections/implementation/mediums/webrtc/fake_webrtc.h deleted file mode 100644 index 65f9e3f5..00000000 --- a/connections/implementation/mediums/webrtc/fake_webrtc.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2023 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 CORE_INTERNAL_MEDIUMS_WEBRTC_FAKE_WEBRTC_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_FAKE_WEBRTC_H_ - -#include - -#include "absl/strings/string_view.h" -#include "connections/implementation/mediums/webrtc/webrtc.h" -#include "internal/platform/cancellation_flag.h" - -namespace nearby::connections::mediums { - -class FakeWebRtcMedium : public WebRtcMedium { - public: - explicit FakeWebRtcMedium(CancellationFlag* flag); - FakeWebRtcMedium(FakeWebRtcMedium&&) = delete; - FakeWebRtcMedium& operator=(FakeWebRtcMedium&&) = delete; - ~FakeWebRtcMedium() override; - - // WebRtcMedium: - bool IsValid() const override { return is_valid_; } - - std::unique_ptr GetSignalingMessenger( - absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint) - override; - - void TriggerCancellationDuringGetSignalingMessenger() { - cancel_during_get_signaling_messenger_ = true; - } - - void SetIsValid(bool is_valid) { is_valid_ = is_valid; } - - private: - CancellationFlag* flag_ = nullptr; - bool is_valid_ = true; - bool cancel_during_get_signaling_messenger_ = false; -}; - -} // namespace nearby::connections::mediums - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_FAKE_WEBRTC_H_ diff --git a/connections/implementation/mediums/webrtc/local_ice_candidate_listener.h b/connections/implementation/mediums/webrtc/local_ice_candidate_listener.h deleted file mode 100644 index a3b10fd0..00000000 --- a/connections/implementation/mediums/webrtc/local_ice_candidate_listener.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_LOCAL_ICE_CANDIDATE_LISTENER_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_LOCAL_ICE_CANDIDATE_LISTENER_H_ - -#include "absl/functional/any_invocable.h" -#include "internal/platform/listeners.h" -#include "webrtc/api/jsep.h" - -namespace nearby { -namespace connections { -namespace mediums { - -// Callbacks from local ice candidate collection. -struct LocalIceCandidateListener { - // Called when a new local ice candidate has been found. - absl::AnyInvocable - local_ice_candidate_found_cb = - nearby::DefaultCallback(); -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_LOCAL_ICE_CANDIDATE_LISTENER_H_ diff --git a/connections/implementation/mediums/webrtc/session_description_wrapper.h b/connections/implementation/mediums/webrtc/session_description_wrapper.h deleted file mode 100644 index a099b175..00000000 --- a/connections/implementation/mediums/webrtc/session_description_wrapper.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_SESSION_DESCRIPTION_WRAPPER_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_SESSION_DESCRIPTION_WRAPPER_H_ - -#include -#include -#include "webrtc/api/jsep.h" - -// Wrapper object around SessionDescriptionInterface*. -// This object owns the SessionDescriptionInterface* unless Release() has been -// called. -class SessionDescriptionWrapper { - public: - SessionDescriptionWrapper() = default; - explicit SessionDescriptionWrapper(webrtc::SessionDescriptionInterface* sdp) - : impl_(sdp) {} - - // Copy constructor that performs a deep copy, i.e. creates a new - // SessionDescriptionInterface. - SessionDescriptionWrapper(const SessionDescriptionWrapper& sdp) { - if (sdp.IsValid()) { - impl_ = webrtc::CreateSessionDescription(sdp.GetType(), sdp.ToString()); - } - } - - SessionDescriptionWrapper(SessionDescriptionWrapper&&) = default; - SessionDescriptionWrapper& operator=(SessionDescriptionWrapper&&) = default; - - // Release the ownership of the SessionDescriptionInterface*. - webrtc::SessionDescriptionInterface* Release() { return impl_.release(); } - - // Returns a string representation of the sdp. Only call this, if IsValid() is - // true. - std::string ToString() const { - std::string str; - impl_->ToString(&str); - return str; - } - - // Returns the SdpType of the SessionDescriptionInterface. Only call this, if - // IsValid() is true. - webrtc::SdpType GetType() const { return impl_->GetType(); } - - const webrtc::SessionDescriptionInterface& GetSdp() { return *impl_; } - - // Return whether this object currently holds a SessionDescriptionInterface. - bool IsValid() const { return impl_ != nullptr; } - - private: - std::unique_ptr impl_; -}; - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_SESSION_DESCRIPTION_WRAPPER_H_ diff --git a/connections/implementation/mediums/webrtc/signaling_frames.cc b/connections/implementation/mediums/webrtc/signaling_frames.cc deleted file mode 100644 index b59f8c7d..00000000 --- a/connections/implementation/mediums/webrtc/signaling_frames.cc +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2020 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. - -#include -#include -#include -#include - -#include "connections/implementation/mediums/webrtc/signaling_frames.h" -#include "connections/implementation/mediums/webrtc_peer_id.h" -#include "internal/platform/byte_array.h" -#include "webrtc/api/jsep.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace webrtc_frames { -using WebRtcSignalingFrame = ::location::nearby::mediums::WebRtcSignalingFrame; - -namespace { - -ByteArray FrameToByteArray(const WebRtcSignalingFrame& signaling_frame) { - std::string message; - signaling_frame.SerializeToString(&message); - return ByteArray(message.c_str(), message.size()); -} - -void SetSenderId(const WebrtcPeerId& sender_id, WebRtcSignalingFrame& frame) { - frame.mutable_sender_id()->set_id(sender_id.GetId()); -} - -std::unique_ptr DecodeIceCandidate( - location::nearby::mediums::IceCandidate ice_candidate_proto) { - webrtc::SdpParseError error; - return std::unique_ptr(webrtc::CreateIceCandidate( - ice_candidate_proto.sdp_mid(), ice_candidate_proto.sdp_m_line_index(), - ice_candidate_proto.sdp(), &error)); -} - -} // namespace - -ByteArray EncodeReadyForSignalingPoke(const WebrtcPeerId& sender_id) { - WebRtcSignalingFrame signaling_frame; - signaling_frame.set_type(WebRtcSignalingFrame::READY_FOR_SIGNALING_POKE_TYPE); - SetSenderId(sender_id, signaling_frame); - signaling_frame.set_allocated_ready_for_signaling_poke( - new location::nearby::mediums::ReadyForSignalingPoke()); - return FrameToByteArray(std::move(signaling_frame)); -} - -ByteArray EncodeOffer(const WebrtcPeerId& sender_id, - const webrtc::SessionDescriptionInterface& offer) { - WebRtcSignalingFrame signaling_frame; - signaling_frame.set_type(WebRtcSignalingFrame::OFFER_TYPE); - SetSenderId(sender_id, signaling_frame); - std::string offer_str; - offer.ToString(&offer_str); - signaling_frame.mutable_offer() - ->mutable_session_description() - ->set_description(offer_str); - return FrameToByteArray(std::move(signaling_frame)); -} - -ByteArray EncodeAnswer(const WebrtcPeerId& sender_id, - const webrtc::SessionDescriptionInterface& answer) { - WebRtcSignalingFrame signaling_frame; - signaling_frame.set_type(WebRtcSignalingFrame::ANSWER_TYPE); - SetSenderId(sender_id, signaling_frame); - std::string answer_str; - answer.ToString(&answer_str); - signaling_frame.mutable_answer() - ->mutable_session_description() - ->set_description(answer_str); - return FrameToByteArray(std::move(signaling_frame)); -} - -ByteArray EncodeIceCandidates( - const WebrtcPeerId& sender_id, - const std::vector& - ice_candidates) { - WebRtcSignalingFrame signaling_frame; - signaling_frame.set_type(WebRtcSignalingFrame::ICE_CANDIDATES_TYPE); - SetSenderId(sender_id, signaling_frame); - for (const auto& ice_candidate : ice_candidates) { - *signaling_frame.mutable_ice_candidates()->add_ice_candidates() = - ice_candidate; - } - return FrameToByteArray(std::move(signaling_frame)); -} - -std::unique_ptr DecodeOffer( - const WebRtcSignalingFrame& frame) { - return webrtc::CreateSessionDescription( - webrtc::SdpType::kOffer, - frame.offer().session_description().description()); -} - -std::unique_ptr DecodeAnswer( - const WebRtcSignalingFrame& frame) { - return webrtc::CreateSessionDescription( - webrtc::SdpType::kAnswer, - frame.answer().session_description().description()); -} - -std::vector> DecodeIceCandidates( - const WebRtcSignalingFrame& frame) { - std::vector> ice_candidates; - for (const auto& candidate : frame.ice_candidates().ice_candidates()) { - ice_candidates.push_back(DecodeIceCandidate(candidate)); - } - return ice_candidates; -} - -location::nearby::mediums::IceCandidate EncodeIceCandidate( - const webrtc::IceCandidate& ice_candidate) { - std::string sdp; - ice_candidate.ToString(&sdp); - location::nearby::mediums::IceCandidate ice_candidate_proto; - ice_candidate_proto.set_sdp(sdp); - ice_candidate_proto.set_sdp_mid(ice_candidate.sdp_mid()); - ice_candidate_proto.set_sdp_m_line_index(ice_candidate.sdp_mline_index()); - return ice_candidate_proto; -} - -} // namespace webrtc_frames -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/webrtc/signaling_frames.h b/connections/implementation/mediums/webrtc/signaling_frames.h deleted file mode 100644 index c6579463..00000000 --- a/connections/implementation/mediums/webrtc/signaling_frames.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_SIGNALING_FRAMES_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_SIGNALING_FRAMES_H_ - -#include -#include - -#include "connections/implementation/mediums/webrtc_peer_id.h" -#include "internal/platform/byte_array.h" -#include "proto/mediums/web_rtc_signaling_frames.pb.h" -#include "webrtc/api/jsep.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace webrtc_frames { - -ByteArray EncodeReadyForSignalingPoke(const WebrtcPeerId& sender_id); - -ByteArray EncodeOffer(const WebrtcPeerId& sender_id, - const webrtc::SessionDescriptionInterface& offer); -ByteArray EncodeAnswer(const WebrtcPeerId& sender_id, - const webrtc::SessionDescriptionInterface& answer); - -ByteArray EncodeIceCandidates( - const WebrtcPeerId& sender_id, - const std::vector& ice_candidates); -location::nearby::mediums::IceCandidate EncodeIceCandidate( - const webrtc::IceCandidate& ice_candidate); - -std::unique_ptr DecodeOffer( - const location::nearby::mediums::WebRtcSignalingFrame& frame); -std::unique_ptr DecodeAnswer( - const location::nearby::mediums::WebRtcSignalingFrame& frame); - -std::vector> DecodeIceCandidates( - const location::nearby::mediums::WebRtcSignalingFrame& frame); - -} // namespace webrtc_frames -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_SIGNALING_FRAMES_H_ diff --git a/connections/implementation/mediums/webrtc/signaling_frames_test.cc b/connections/implementation/mediums/webrtc/signaling_frames_test.cc deleted file mode 100644 index de5f92bb..00000000 --- a/connections/implementation/mediums/webrtc/signaling_frames_test.cc +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright 2020 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. - -#include "connections/implementation/mediums/webrtc/signaling_frames.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "connections/implementation/mediums/webrtc_peer_id.h" -#include "google/protobuf/text_format.h" -#include "webrtc/api/jsep.h" - -namespace nearby { -namespace connections { -namespace mediums { -namespace webrtc_frames { - -namespace { - -using ::location::nearby::mediums::IceCandidate; -using ::location::nearby::mediums::WebRtcSignalingFrame; -const char kSampleSdp[] = - "v=0\r\no=- 7859371131 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 " - "0\r\na=msid-semantic: WMS\r\n"; - -const char kIceCandidateSdp1[] = - "a=candidate:1 1 UDP 2130706431 10.0.1.1 8998 typ host"; -const char kIceCandidateSdp2[] = - "a=candidate:2 1 UDP 1694498815 192.0.2.3 45664 typ srflx raddr"; - -const char kIceSdpMid[] = "data"; -const int kIceSdpMLineIndex = 0; - -const char kOfferProto[] = R"( - sender_id { id: "abc" } - type: OFFER_TYPE - offer { - session_description { - description: "v=0\r\no=- 7859371131 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=msid-semantic: WMS\r\n" - } - } - )"; - -const char kAnswerProto[] = R"( - sender_id { id: "abc" } - type: ANSWER_TYPE - answer { - session_description { - description: "v=0\r\no=- 7859371131 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=msid-semantic: WMS\r\n" - } - } - )"; - -const char kIceCandidatesProto[] = R"( - sender_id { id: "abc" } - type: ICE_CANDIDATES_TYPE - ice_candidates { - ice_candidates { - sdp: "candidate:1 1 udp 2130706431 10.0.1.1 8998 typ host generation 0" - sdp_mid: "data" - sdp_m_line_index: 0 - } - ice_candidates { - sdp: "candidate:2 1 udp 1694498815 192.0.2.3 45664 typ srflx generation 0" - sdp_mid: "data" - sdp_m_line_index: 0 - } - } - )"; -} // namespace - -TEST(SignalingFramesTest, SignalingPoke) { - WebrtcPeerId sender_id("abc"); - ByteArray encoded_poke = EncodeReadyForSignalingPoke(sender_id); - - WebRtcSignalingFrame frame; - frame.ParseFromString(std::string(encoded_poke.data(), encoded_poke.size())); - - EXPECT_THAT(frame, protobuf_matchers::EqualsProto(R"pb( - sender_id { id: "abc" } - type: READY_FOR_SIGNALING_POKE_TYPE - ready_for_signaling_poke {} - )pb")); -} - -TEST(SignalingFramesTest, EncodeValidOffer) { - WebrtcPeerId sender_id("abc"); - std::unique_ptr offer = - webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, kSampleSdp); - ByteArray encoded_offer = EncodeOffer(sender_id, *offer); - - WebRtcSignalingFrame frame; - frame.ParseFromString( - std::string(encoded_offer.data(), encoded_offer.size())); - - EXPECT_THAT(frame, protobuf_matchers::EqualsProto(kOfferProto)); -} - -TEST(SignaingFramesTest, DecodeValidOffer) { - WebRtcSignalingFrame frame; - proto2::TextFormat::ParseFromString(kOfferProto, &frame); - std::unique_ptr decoded_offer = - DecodeOffer(frame); - - EXPECT_EQ(webrtc::SdpType::kOffer, decoded_offer->GetType()); - std::string description; - decoded_offer->ToString(&description); - EXPECT_EQ(kSampleSdp, description); -} - -TEST(SignalingFramesTest, EncodeValidAnswer) { - WebrtcPeerId sender_id("abc"); - std::unique_ptr answer( - webrtc::CreateSessionDescription(webrtc::SdpType::kAnswer, kSampleSdp)); - ByteArray encoded_answer = EncodeAnswer(sender_id, *answer); - - WebRtcSignalingFrame frame; - frame.ParseFromString( - std::string(encoded_answer.data(), encoded_answer.size())); - - EXPECT_THAT(frame, protobuf_matchers::EqualsProto(kAnswerProto)); -} - -TEST(SignalingFramesTest, DecodeValidAnswer) { - WebRtcSignalingFrame frame; - proto2::TextFormat::ParseFromString(kAnswerProto, &frame); - std::unique_ptr decoded_answer = - DecodeAnswer(frame); - - EXPECT_EQ(webrtc::SdpType::kAnswer, decoded_answer->GetType()); - std::string description; - decoded_answer->ToString(&description); - EXPECT_EQ(kSampleSdp, description); -} - -TEST(SignalingFramesTest, EncodeValidIceCandidates) { - WebrtcPeerId sender_id("abc"); - webrtc::SdpParseError error; - - std::vector> ice_candidates; - ice_candidates.emplace_back(webrtc::CreateIceCandidate( - kIceSdpMid, kIceSdpMLineIndex, kIceCandidateSdp1, &error)); - ice_candidates.emplace_back(webrtc::CreateIceCandidate( - kIceSdpMid, kIceSdpMLineIndex, kIceCandidateSdp2, &error)); - std::vector encoded_candidates_vec; - for (const auto& ice_candidate : ice_candidates) { - encoded_candidates_vec.push_back(EncodeIceCandidate(*ice_candidate)); - } - ByteArray encoded_candidates = - EncodeIceCandidates(sender_id, encoded_candidates_vec); - - WebRtcSignalingFrame frame; - frame.ParseFromString( - std::string(encoded_candidates.data(), encoded_candidates.size())); - - EXPECT_THAT(frame, protobuf_matchers::EqualsProto(kIceCandidatesProto)); -} - -TEST(SignalingFramesTest, DecodeValidIceCandidates) { - webrtc::SdpParseError error; - std::vector> ice_candidates; - ice_candidates.emplace_back(webrtc::CreateIceCandidate( - kIceSdpMid, kIceSdpMLineIndex, kIceCandidateSdp1, &error)); - ice_candidates.emplace_back(webrtc::CreateIceCandidate( - kIceSdpMid, kIceSdpMLineIndex, kIceCandidateSdp2, &error)); - - WebRtcSignalingFrame frame; - proto2::TextFormat::ParseFromString(kIceCandidatesProto, &frame); - std::vector> decoded_candidates = - DecodeIceCandidates(frame); - - ASSERT_EQ(2u, decoded_candidates.size()); - for (int i = 0; i < static_cast(decoded_candidates.size()); i++) { - EXPECT_TRUE(ice_candidates[i]->candidate().IsEquivalent( - decoded_candidates[i]->candidate())); - EXPECT_EQ(ice_candidates[i]->sdp_mid(), decoded_candidates[i]->sdp_mid()); - EXPECT_EQ(ice_candidates[i]->sdp_mline_index(), - decoded_candidates[i]->sdp_mline_index()); - } -} - -} // namespace webrtc_frames -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.cc b/connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.cc deleted file mode 100644 index 9e6efa79..00000000 --- a/connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.cc +++ /dev/null @@ -1,340 +0,0 @@ -// 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. - -#include "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h" - -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "absl/synchronization/mutex.h" -#include "absl/time/time.h" -#include "third_party/gloop/util/random/mt_random.h" -#include "third_party/grpc/include/grpc/support/time.h" -#include "third_party/grpc/include/grpcpp/channel.h" -#include "third_party/grpc/include/grpcpp/client_context.h" -#include "third_party/grpc/include/grpcpp/create_channel.h" -#include "third_party/grpc/include/grpcpp/security/credentials.h" -#include "third_party/grpc/include/grpcpp/support/client_callback.h" -#include "third_party/grpc/include/grpcpp/support/status.h" -#include "internal/account/account_manager_impl.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/logging.h" -#include "internal/proto/messaging.grpc.pb.h" -#include "internal/proto/tachyon.proto.h" -#include "internal/proto/tachyon_common.proto.h" -#include "internal/proto/tachyon_enums.proto.h" -#include "internal/rpc/utils.h" -#include "util/random/util.h" - -namespace nearby::connections::mediums { - -namespace { -using ::google::internal::communications::instantmessaging::v1::ClientInfo; -using ::google::internal::communications::instantmessaging::v1::Id; -using ::google::internal::communications::instantmessaging::v1:: - LocationStandard; -using ::google::internal::communications::instantmessaging::v1:: - ReceiveMessagesResponse; -using ::google::internal::communications::instantmessaging::v1::RequestHeader; -using ::google::internal::communications::instantmessaging::v1:: - SendMessageExpressRequest; -using ::google::internal::communications::instantmessaging::v1:: - SendMessageExpressResponse; - -constexpr absl::string_view kApp = "Nearby"; -constexpr absl::string_view kTachyonAddress = - "instantmessaging-pa.googleapis.com:443"; - -// It is unclear to me where these magic numbers are from but they are used -// across both the Android and CrOS implementations. -// See: -// https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/nearby_sharing/tachyon_ice_config_fetcher.cc;l=53 -constexpr int kMajorVersion = 1; -constexpr int kMinorVersion = 24; -constexpr int kPointVersion = 0; - -void InitId(Id& id, absl::string_view id_str, - const location::nearby::connections::LocationHint& location_hint) { - id.set_id(id_str); - id.set_app(kApp); - id.set_type(google::internal::communications::instantmessaging::v1::IdType:: - NEARBY_ID); - auto* request_location_hint = id.mutable_location_hint(); - request_location_hint->set_location(location_hint.location()); - if (location_hint.format() == - location::nearby::connections::LocationStandard::E164_CALLING) { - request_location_hint->set_format(LocationStandard::E164_CALLING); - } else if (location_hint.format() == - location::nearby::connections::LocationStandard:: - ISO_3166_1_ALPHA_2) { - request_location_hint->set_format(LocationStandard::ISO_3166_1_ALPHA_2); - } else { - request_location_hint->set_format(LocationStandard::UNKNOWN); - } -} - -void InitRequestHeader( - RequestHeader& header, absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint) { - ClientInfo* client_info = header.mutable_client_info(); - client_info->set_platform_type(google::internal::communications:: - instantmessaging::v1::Platform::DESKTOP); - - client_info->set_major(kMajorVersion); - client_info->set_minor(kMinorVersion); - client_info->set_point(kPointVersion); - - client_info->set_api_version( - google::internal::communications::instantmessaging::v1::ApiVersion::V4); - - // Generate a random message identifier. - MTRandom rand; - header.set_request_id(util_random::RandomString(&rand, /*length=*/13, - util::random::kWebsafe64)); - header.set_app(kApp); - - InitId(*header.mutable_requester_id(), self_id, location_hint); -} - -} // namespace - -bool TachyonExpressSignalingMessenger::ReceiveMessagesReader::Start( - google::internal::communications::instantmessaging::v1::grpc::Messaging:: - StubInterface* stub, - absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint, - absl::string_view access_token, - absl::AnyInvocable on_fast_path_ready_callback, - absl::AnyInvocable on_inbox_message_callback, - absl::AnyInvocable on_complete_callback) { - { - absl::MutexLock lock(mutex_); - if (is_receiving_messages_) { - return false; - } - is_receiving_messages_ = true; - } - - on_fast_path_ready_callback_ = std::move(on_fast_path_ready_callback); - on_inbox_message_callback_ = std::move(on_inbox_message_callback); - on_complete_callback_ = std::move(on_complete_callback); - const std::shared_ptr call_creds = - grpc::AccessTokenCredentials(std::string(access_token)); - context_.set_credentials(call_creds); - gpr_timespec deadline = gpr_now(GPR_CLOCK_MONOTONIC); - timespec timespec = absl::ToTimespec(absl::Seconds(30)); - deadline.tv_sec += timespec.tv_sec; - deadline.tv_nsec += timespec.tv_nsec; - context_.set_deadline(deadline); - - InitRequestHeader(*request_.mutable_header(), self_id, location_hint); - stub->async()->ReceiveMessagesExpress(&context_, &request_, this); - StartRead(&response_); - StartCall(); - return true; -} - -void TachyonExpressSignalingMessenger::ReceiveMessagesReader::OnReadDone( - bool ok) { - { - absl::MutexLock lock(mutex_); - if (!is_receiving_messages_) { - return; - } - } - if (ok) { - switch (response_.body_case()) { - case ReceiveMessagesResponse::kFastPathReady: - on_fast_path_ready_callback_(); - break; - case ReceiveMessagesResponse::kInboxMessage: - on_inbox_message_callback_( - ByteArray(response_.inbox_message().message())); - break; - default: - break; - } - StartRead(&response_); - } -} - -void TachyonExpressSignalingMessenger::ReceiveMessagesReader::OnDone( - const grpc::Status& s) { - { - absl::MutexLock lock(mutex_); - if (!is_receiving_messages_) { - return; - } - } - if (!s.ok()) { - LOG(ERROR) << "ReceiveMessagesExpress failed: " - << rpc::GrpcStatusToAbslStatus(s); - } - on_complete_callback_(s.ok()); -} - -void TachyonExpressSignalingMessenger::ReceiveMessagesReader::TryCancel() { - { - absl::MutexLock lock(mutex_); - if (!is_receiving_messages_) { - return; - } - is_receiving_messages_ = false; - } - context_.TryCancel(); -} - -TachyonExpressSignalingMessenger::TachyonExpressSignalingMessenger( - absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint) - : self_id_(self_id), - location_hint_(location_hint), - account_manager_(AccountManagerImpl::Factory::instance()) { - std::shared_ptr channel = - grpc::CreateChannel(std::string(kTachyonAddress), - grpc::SslCredentials(grpc::SslCredentialsOptions())); - messaging_stub_ = google::internal::communications::instantmessaging::v1:: - grpc::Messaging::NewStub(channel); -} - -struct StartState { - CountDownLatch latch{1}; - bool success = false; -}; - -bool TachyonExpressSignalingMessenger::StartReceivingMessages( - OnSignalingMessageCallback on_message_callback, - OnSignalingCompleteCallback on_complete_callback) { - auto state = std::make_shared(); - - account_manager_->GetAccessToken( - [this, state, on_message_callback = std::move(on_message_callback), - on_complete_callback = std::move(on_complete_callback)]( - absl::StatusOr token) mutable { - if (!token.ok()) { - state->success = false; - state->latch.CountDown(); - return; - } - auto reader = std::make_shared(); - - reader_ = reader; - - std::weak_ptr weak_state = state; - - bool started = reader->Start( - messaging_stub_.get(), self_id_, location_hint_, token.value(), - /*on_fast_path_ready_callback=*/ - [state] { - LOG(INFO) << "Received fast path ready message from tachyon."; - state->success = true; - state->latch.CountDown(); - }, - std::move(on_message_callback), - [reader, weak_state, - cb = std::move(on_complete_callback)](bool s) mutable { - LOG(INFO) << "Finished receiving messages from tachyon."; - cb(s); - if (auto state = weak_state.lock()) { - state->success = false; - state->latch.CountDown(); - } - }); - - if (!started) { - state->success = false; - state->latch.CountDown(); - } - }); - state->latch.Await(); - if (state->success) { - LOG(INFO) << "Receiving messages from tachyon."; - } else { - LOG(ERROR) << "Failed to start receiving messages from tachyon."; - reader_.reset(); - } - return state->success; -} - -void TachyonExpressSignalingMessenger::StopReceivingMessages() { - if (reader_) { - reader_->TryCancel(); - reader_.reset(); - } -} - -bool TachyonExpressSignalingMessenger::SendMessage(absl::string_view peer_id, - const ByteArray& message) { - auto rpc_state = - std::make_shared>(); - - InitRequestHeader(*rpc_state->request.mutable_header(), self_id_, - location_hint_); - InitId(*rpc_state->request.mutable_dest_id(), peer_id, location_hint_); - - auto* request_message = rpc_state->request.mutable_message(); - request_message->set_message(message.string_data()); - request_message->set_message_type( - google::internal::communications::instantmessaging::v1::InboxMessage:: - BASIC); - request_message->set_message_class( - google::internal::communications::instantmessaging::v1::InboxMessage:: - EPHEMERAL); - MTRandom rand; - request_message->set_message_id(util_random::RandomString( - &rand, /*length=*/13, util::random::kWebsafe64)); - - CountDownLatch latch(1); - bool success = false; - account_manager_->GetAccessToken( - [this, &latch, &success, rpc_state](absl::StatusOr token) { - if (!token.ok()) { - success = false; - latch.CountDown(); - return; - } - - const std::shared_ptr call_creds = - grpc::AccessTokenCredentials(token.value()); - rpc_state->context.set_credentials(call_creds); - gpr_timespec deadline = gpr_now(GPR_CLOCK_MONOTONIC); - timespec timespec = absl::ToTimespec(absl::Seconds(30)); - deadline.tv_sec += timespec.tv_sec; - deadline.tv_nsec += timespec.tv_nsec; - rpc_state->context.set_deadline(deadline); - - // `rpc_state` is captured to ensure its lifetime is valid until the - // callback is executed. - messaging_stub_->async()->SendMessageExpress( - &rpc_state->context, &rpc_state->request, &rpc_state->response, - [&success, &latch, rpc_state](grpc::Status status) { - if (!status.ok()) { - LOG(ERROR) << "SendMessageExpress failed: " - << rpc::GrpcStatusToAbslStatus(status); - } - success = status.ok(); - latch.CountDown(); - }); - }); - latch.Await(); - return success; -} - -} // namespace nearby::connections::mediums diff --git a/connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h b/connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h deleted file mode 100644 index 47c6f59c..00000000 --- a/connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h +++ /dev/null @@ -1,99 +0,0 @@ -// 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 CORE_INTERNAL_MEDIUMS_WEBRTC_TACHYON_MESSAGING_CLIENT_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_TACHYON_MESSAGING_CLIENT_H_ - -#include -#include - -#include "location/nearby/sharing/lib/account/account_manager.h" -#include "absl/base/thread_annotations.h" -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "absl/synchronization/mutex.h" -#include "third_party/grpc/include/grpcpp/client_context.h" -#include "third_party/grpc/include/grpcpp/support/client_callback.h" -#include "third_party/grpc/include/grpcpp/support/status.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/implementation/webrtc.h" -#include "internal/proto/messaging.grpc.pb.h" - -namespace nearby::connections::mediums { - -// Interface for the messaging Tachyon service. See -// third_party/nearby/internal/proto/messaging.proto -class TachyonExpressSignalingMessenger : public api::WebRtcSignalingMessenger { - public: - explicit TachyonExpressSignalingMessenger( - absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint); - - class ReceiveMessagesReader - : public grpc::ClientReadReactor< - google::internal::communications::instantmessaging::v1:: - ReceiveMessagesResponse> { - public: - ReceiveMessagesReader() = default; - - void OnReadDone(bool ok) override; - void OnDone(const grpc::Status& s) override; - - bool Start( - google::internal::communications::instantmessaging::v1::grpc:: - Messaging::StubInterface* stub, - absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint, - absl::string_view access_token, - absl::AnyInvocable on_fast_path_ready_callback, - absl::AnyInvocable on_inbox_message_callback, - absl::AnyInvocable on_complete_callback); - void TryCancel(); - - private: - grpc::ClientContext context_; - google::internal::communications::instantmessaging::v1:: - ReceiveMessagesExpressRequest request_; - google::internal::communications::instantmessaging::v1:: - ReceiveMessagesResponse response_; - absl::AnyInvocable on_fast_path_ready_callback_; - absl::AnyInvocable on_inbox_message_callback_; - absl::AnyInvocable on_complete_callback_; - - absl::Mutex mutex_; - bool is_receiving_messages_ ABSL_GUARDED_BY(mutex_) = false; - }; - - bool SendMessage(absl::string_view peer_id, - const ByteArray& message) override; - - bool StartReceivingMessages( - OnSignalingMessageCallback on_message_callback, - OnSignalingCompleteCallback on_complete_callback) override; - - void StopReceivingMessages() override; - - private: - std::string self_id_; - location::nearby::connections::LocationHint location_hint_; - std::unique_ptr - messaging_stub_; - nearby::sharing::AccountManager* const account_manager_; - std::shared_ptr reader_ = nullptr; -}; - -} // namespace nearby::connections::mediums - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_TACHYON_MESSAGING_CLIENT_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc.h b/connections/implementation/mediums/webrtc/webrtc.h deleted file mode 100644 index 6490f5de..00000000 --- a/connections/implementation/mediums/webrtc/webrtc.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_H_ - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/implementation/webrtc.h" -#include "internal/platform/implementation/webrtc_platform.h" -#include "webrtc/api/peer_connection_interface.h" -#include "webrtc/rtc_base/network_constants.h" - -namespace nearby::connections::mediums { - -class WebRtcSignalingMessenger { - public: - using OnSignalingMessageCallback = - api::WebRtcSignalingMessenger::OnSignalingMessageCallback; - using OnSignalingCompleteCallback = - api::WebRtcSignalingMessenger::OnSignalingCompleteCallback; - - explicit WebRtcSignalingMessenger( - std::unique_ptr messenger) - : impl_(std::move(messenger)) {} - virtual ~WebRtcSignalingMessenger() = default; - WebRtcSignalingMessenger(WebRtcSignalingMessenger&&) = default; - WebRtcSignalingMessenger operator=(WebRtcSignalingMessenger&&) = delete; - - virtual bool SendMessage(absl::string_view peer_id, - const ByteArray& message) { - return impl_->SendMessage(peer_id, message); - } - - virtual bool StartReceivingMessages( - OnSignalingMessageCallback on_message_callback, - OnSignalingCompleteCallback on_complete_callback) { - return impl_->StartReceivingMessages(std::move(on_message_callback), - std::move(on_complete_callback)); - } - - virtual void StopReceivingMessages() { impl_->StopReceivingMessages(); } - - virtual bool IsValid() const { return impl_ != nullptr; } - - private: - std::unique_ptr impl_; -}; - -class WebRtcMedium { - public: - WebRtcMedium() - : impl_(api::WebRtcImplementationPlatform::CreateWebRtcMedium()) {} - virtual ~WebRtcMedium() = default; - WebRtcMedium(WebRtcMedium&&) = default; - WebRtcMedium& operator=(WebRtcMedium&&) = delete; - - void SetNonCellular(bool non_cellular) { non_cellular_ = non_cellular; } - - // Creates and returns a new webrtc::PeerConnectionInterface object via - // |callback|. - void CreatePeerConnection( - webrtc::PeerConnectionObserver* observer, - api::WebRtcMedium::PeerConnectionCallback callback) { - if (FeatureFlags::GetInstance() - .GetFlags() - .support_web_rtc_non_cellular_medium && - non_cellular_) { - std::optional options; - options->network_ignore_mask |= webrtc::ADAPTER_TYPE_CELLULAR; - impl_->CreatePeerConnection(options, observer, std::move(callback)); - } else { - impl_->CreatePeerConnection(observer, std::move(callback)); - } - } - - // Returns a signaling messenger for sending WebRTC signaling messages. - virtual std::unique_ptr GetSignalingMessenger( - absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint) { - return std::make_unique( - impl_->GetSignalingMessenger(self_id, location_hint)); - } - - virtual bool IsValid() const { return impl_ != nullptr; } - - private: - std::unique_ptr impl_; - bool non_cellular_ = false; -}; - -} // namespace nearby::connections::mediums - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc deleted file mode 100644 index 1b2dac5d..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_bwu_handler.cc +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2020 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. - -#include "connections/implementation/mediums/webrtc/webrtc_bwu_handler.h" - -#include -#include -#include - -#include "absl/base/nullability.h" -#include "absl/functional/bind_front.h" -#include "connections/implementation/base_bwu_handler.h" -#include "connections/implementation/client_proxy.h" -#include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/webrtc.h" -#include "connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h" -#include "connections/implementation/mediums/webrtc_peer_id.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "connections/implementation/offline_frames.h" -#include "connections/implementation/proto/offline_wire_formats.pb.h" -#include "internal/platform/cancellation_flag.h" -#include "internal/platform/expected.h" -#include "internal/platform/implementation/webrtc_platform.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace connections { - -namespace { -using ::location::nearby::connections::BandwidthUpgradeNegotiationFrame; -using ::location::nearby::connections::LocationHint; -using ::location::nearby::connections::LocationStandard; -using ::location::nearby::proto::connections::OperationResultCode; - -LocationHint BuildLocationHint(const std::string& location) { - LocationHint location_hint; - location_hint.set_format(LocationStandard::UNKNOWN); - - if (!location.empty()) { - location_hint.set_location(location); - if (location.at(0) == '+') { - location_hint.set_format(LocationStandard::E164_CALLING); - } else { - location_hint.set_format(LocationStandard::ISO_3166_1_ALPHA_2); - } - } - return location_hint; -} - -} // namespace - -WebrtcBwuHandler::WebrtcIncomingSocket::WebrtcIncomingSocket( - const std::string& name, std::shared_ptr socket) - : name_(name), socket_(std::move(socket)) {} - -void WebrtcBwuHandler::WebrtcIncomingSocket::Close() { socket_->Close(); } - -std::string WebrtcBwuHandler::WebrtcIncomingSocket::ToString() { return name_; } - -WebrtcBwuHandler::WebrtcBwuHandler( - mediums::WebRtc* absl_nonnull webrtc_medium, - IncomingConnectionCallback incoming_connection_callback) - : BaseBwuHandler(std::move(incoming_connection_callback)), - webrtc_(*webrtc_medium) {} - -// Called by BWU target. Retrieves a new medium info from incoming message, -// and establishes connection over WebRTC using this info. -ErrorOr> -WebrtcBwuHandler::CreateUpgradedEndpointChannel( - ClientProxy* client, const std::string& service_id, - const std::string& endpoint_id, - const BandwidthUpgradeNegotiationFrame::UpgradePathInfo& - upgrade_path_info) { - const BandwidthUpgradeNegotiationFrame::UpgradePathInfo::WebRtcCredentials& - web_rtc_credentials = upgrade_path_info.web_rtc_credentials(); - mediums::WebrtcPeerId peer_id(web_rtc_credentials.peer_id()); - - LocationHint location_hint; - location_hint.set_format(LocationStandard::UNKNOWN); - if (web_rtc_credentials.has_location_hint()) { - location_hint = web_rtc_credentials.location_hint(); - } - LOG(INFO) << "WebRtcBwuHandler is attempting to connect to remote peer " - << peer_id.GetId() << ", location hint " - << location_hint.location(); - - std::shared_ptr cancellation_flag = - client->GetCancellationFlag(endpoint_id); - ErrorOr> socket_result = - webrtc_.Connect(service_id, peer_id, location_hint, - cancellation_flag.get(), client->GetWebRtcNonCellular()); - if (socket_result.has_error()) { - LOG(ERROR) << "WebRtcBwuHandler failed to connect to remote peer (" - << peer_id.GetId() << ") on endpoint " << endpoint_id - << ", aborting upgrade."; - return {Error(socket_result.error().operation_result_code().value())}; - } - - LOG(INFO) << "WebRtcBwuHandler successfully connected to remote " - "peer (" - << peer_id.GetId() << ") while upgrading endpoint " << endpoint_id; - - // Create a new WebRtcEndpointChannel. - auto channel = std::make_unique( - service_id, /*channel_name=*/service_id, socket_result.value()); - if (channel == nullptr) { - socket_result.value()->Close(); - LOG(ERROR) << "WebRtcBwuHandler failed to create new EndpointChannel for " - "outgoing socket, aborting upgrade."; - return {Error( - OperationResultCode::NEARBY_WEB_RTC_ENDPOINT_CHANNEL_CREATION_FAILURE)}; - } - - return {std::move(channel)}; -} - -void WebrtcBwuHandler::HandleRevertInitiatorStateForService( - const std::string& upgrade_service_id) { - webrtc_.StopAcceptingConnections(upgrade_service_id); - LOG(INFO) << "WebrtcBwuHandler successfully reverted state for service " - << upgrade_service_id; -} - -// Called by BWU initiator. Set up WebRTC upgraded medium for this endpoint, -// and returns a upgrade path info (PeerId, LocationHint) for remote party to -// perform discovery. -std::string WebrtcBwuHandler::HandleInitializeUpgradedMediumForEndpoint( - ClientProxy* client, const std::string& upgrade_service_id, - const std::string& endpoint_id) { - LocationHint location_hint = BuildLocationHint( - api::WebRtcImplementationPlatform::GetDefaultCountryCode()); - - mediums::WebrtcPeerId self_id{mediums::WebrtcPeerId::FromRandom()}; - if (!webrtc_.IsAcceptingConnections(upgrade_service_id)) { - if (!webrtc_.StartAcceptingConnections( - upgrade_service_id, self_id, location_hint, - absl::bind_front(&WebrtcBwuHandler::OnIncomingWebrtcConnection, - this, client), - client->GetWebRtcNonCellular())) { - LOG(ERROR) << "WebRtcBwuHandler couldn't initiate the WEB_RTC " - "upgrade for endpoint " - << endpoint_id - << " because it failed to start listening for " - "incoming WebRTC connections."; - return {}; - } - LOG(INFO) << "WebRtcBwuHandler successfully started listening for " - "incoming WebRTC connections while upgrading endpoint " - << endpoint_id; - } - - return parser::ForBwuWebrtcPathAvailable(self_id.GetId(), location_hint); -} - -// Accept Connection Callback. -// Notifies that the remote party called WebRtc::Connect() -// for this socket. -void WebrtcBwuHandler::OnIncomingWebrtcConnection( - ClientProxy* client, const std::string& upgrade_service_id, - std::shared_ptr socket) { - auto channel = std::make_unique( - upgrade_service_id, /*channel_name=*/upgrade_service_id, socket); - auto webrtc_socket = std::make_unique( - upgrade_service_id, std::move(socket)); - std::unique_ptr connection( - new IncomingSocketConnection{std::move(webrtc_socket), - std::move(channel)}); - - NotifyOnIncomingConnection(client, std::move(connection)); -} - -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/webrtc/webrtc_bwu_handler.h b/connections/implementation/mediums/webrtc/webrtc_bwu_handler.h deleted file mode 100644 index f7429a44..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_bwu_handler.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_BWU_HANDLER_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_BWU_HANDLER_H_ - -#include -#include - -#include "absl/base/nullability.h" -#include "connections/implementation/base_bwu_handler.h" -#include "connections/implementation/bwu_handler.h" -#include "connections/implementation/client_proxy.h" -#include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/webrtc.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "connections/medium_selector.h" -#include "internal/platform/expected.h" - -namespace nearby { -namespace connections { - -// Defines the set of methods that need to be implemented to handle the -// per-Medium-specific operations needed to upgrade an EndpointChannel. -class WebrtcBwuHandler : public BaseBwuHandler { - public: - WebrtcBwuHandler( - mediums::WebRtc* absl_nonnull webrtc_medium, - IncomingConnectionCallback incoming_connection_callback); - - private: - class WebrtcIncomingSocket : public BwuHandler::IncomingSocket { - public: - explicit WebrtcIncomingSocket( - const std::string& name, std::shared_ptr socket); - - std::string ToString() override; - void Close() override; - - private: - std::string name_; - std::shared_ptr socket_; - }; - - // BwuHandler implementation: - ErrorOr> CreateUpgradedEndpointChannel( - ClientProxy* client, const std::string& service_id, - const std::string& endpoint_id, - const location::nearby::connections::BandwidthUpgradeNegotiationFrame:: - UpgradePathInfo& upgrade_path_info) final; - location::nearby::proto::connections::Medium GetUpgradeMedium() const final { - return Medium::WEB_RTC; - } - void OnEndpointDisconnect(ClientProxy* client, - const std::string& endpoint_id) final {} - - // BaseBwuHandler implementation: - std::string HandleInitializeUpgradedMediumForEndpoint( - ClientProxy* client, const std::string& upgrade_service_id, - const std::string& endpoint_id) final; - void HandleRevertInitiatorStateForService( - const std::string& upgrade_service_id) final; - - void OnIncomingWebrtcConnection( - ClientProxy* client, const std::string& upgrade_service_id, - std::shared_ptr socket); - - mediums::WebRtc& webrtc_; -}; - -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_BWU_HANDLER_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_bwu_handler_test.cc b/connections/implementation/mediums/webrtc/webrtc_bwu_handler_test.cc deleted file mode 100644 index fc407a65..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_bwu_handler_test.cc +++ /dev/null @@ -1,139 +0,0 @@ - -// Copyright 2026 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. -#include "connections/implementation/mediums/webrtc/webrtc_bwu_handler.h" - -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/time/time.h" -#include "connections/implementation/bwu_handler.h" -#include "connections/implementation/client_proxy.h" -#include "connections/implementation/endpoint_channel.h" -#include "connections/implementation/mediums/webrtc/webrtc_impl.h" -#include "connections/implementation/offline_frames.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/exception.h" -#include "internal/platform/expected.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/logging.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" -namespace nearby { -namespace connections { -namespace { -using ::location::nearby::connections::OfflineFrame; -using ::location::nearby::proto::connections::OperationResultCode; -constexpr absl::Duration kWaitDuration = absl::Milliseconds(5000); -class WebrtcBwuTest : public ::testing::Test { - protected: - WebrtcBwuTest() { - original_flags_ = FeatureFlags::GetInstance().GetFlags(); - env_.Start({.webrtc_enabled = true}); - } - ~WebrtcBwuTest() override { - FeatureFlags::GetMutableInstanceForTesting().SetFlags(original_flags_); - env_.Stop(); - } - void RunCreateEndpointChannelTest(bool enable_cancellation); - MediumEnvironment& env_{MediumEnvironment::Instance()}; - FeatureFlags::Flags original_flags_; -}; -void WebrtcBwuTest::RunCreateEndpointChannelTest(bool enable_cancellation) { - FeatureFlags::Flags flags = original_flags_; - flags.enable_cancellation_flag = enable_cancellation; - FeatureFlags::GetMutableInstanceForTesting().SetFlags(flags); - CountDownLatch start_latch(1); - CountDownLatch accept_latch(1); - CountDownLatch end_latch(1); - ClientProxy client_1, client_2; - auto webrtc_1 = std::make_unique(); - auto webrtc_2 = std::make_unique(); - ExceptionOr upgrade_frame; - std::unique_ptr handler_1 = std::make_unique( - webrtc_1.get(), - [&](ClientProxy* client, - std::unique_ptr connection) { - LOG(INFO) << "Handler 1 callback triggered"; - accept_latch.CountDown(); - }); - std::unique_ptr handler_2 = std::make_unique( - webrtc_2.get(), - [&](ClientProxy* client, - std::unique_ptr connection) { - LOG(INFO) << "Handler 2 callback triggered"; - }); - // Server starts advertising. - SingleThreadExecutor server_executor; - server_executor.Execute([&]() { - std::string upgrade_frame_bytes = - handler_1->InitializeUpgradedMediumForEndpoint( - &client_1, /*upgrade_service_id=*/"A", /*endpoint_id=*/"1"); - EXPECT_FALSE(upgrade_frame_bytes.empty()); - upgrade_frame = parser::FromBytes(upgrade_frame_bytes); - start_latch.CountDown(); - }); - // Client connects. - EXPECT_TRUE(start_latch.Await(kWaitDuration).result()); - if (enable_cancellation) { - client_2.AddCancellationFlag(/*endpoint_id=*/"1"); - client_2.GetCancellationFlag(/*endpoint_id=*/"1")->Cancel(); - } - SingleThreadExecutor client_executor; - client_executor.Execute([&]() { - auto bwu_frame = - upgrade_frame.result().v1().bandwidth_upgrade_negotiation(); - auto result = handler_2->CreateUpgradedEndpointChannel( - &client_2, /*service_id=*/"A", - /*endpoint_id=*/"1", bwu_frame.upgrade_path_info()); - if (!enable_cancellation) { - ASSERT_TRUE(result.has_value()); - std::unique_ptr new_channel = std::move(result.value()); - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_EQ(new_channel->GetMedium(), - location::nearby::proto::connections::Medium::WEB_RTC); - } else { - EXPECT_FALSE(result.has_value()); - EXPECT_TRUE(result.has_error()); - EXPECT_EQ(result.error().operation_result_code(), - OperationResultCode:: - CLIENT_CANCELLATION_CANCEL_WEB_RTC_OUTGOING_CONNECTION); - accept_latch.CountDown(); - } - handler_1->RevertResponderState(/*service_id=*/"A"); - end_latch.CountDown(); - }); - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(end_latch.Await(kWaitDuration).result()); -} -TEST_F(WebrtcBwuTest, CanCreateBwuHandler) { - auto webrtc = std::make_unique(); - std::unique_ptr handler = std::make_unique( - webrtc.get(), - [](ClientProxy* client, - std::unique_ptr connection) {}); - EXPECT_EQ(handler->GetUpgradeMedium(), - location::nearby::proto::connections::Medium::WEB_RTC); -} -TEST_F(WebrtcBwuTest, CreateEndpointChannel_WithCancellation) { - RunCreateEndpointChannelTest(true); -} -TEST_F(WebrtcBwuTest, CreateEndpointChannel_NoCancellation) { - RunCreateEndpointChannelTest(false); -} -} // namespace -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/webrtc/webrtc_endpoint_channel.cc b/connections/implementation/mediums/webrtc/webrtc_endpoint_channel.cc deleted file mode 100644 index bf939ea5..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_endpoint_channel.cc +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2020 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. - -#include "connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h" - -#include -#include -#include - -#include "connections/implementation/base_endpoint_channel.h" -#include "connections/implementation/mediums/webrtc_socket.h" - -namespace nearby { -namespace connections { - -WebRtcEndpointChannel::WebRtcEndpointChannel( - const std::string& service_id, const std::string& channel_name, - std::shared_ptr socket) - : BaseEndpointChannel(service_id, channel_name, &socket->GetInputStream(), - &socket->GetOutputStream()), - webrtc_socket_(std::move(socket)) {} - -location::nearby::proto::connections::Medium WebRtcEndpointChannel::GetMedium() - const { - return location::nearby::proto::connections::Medium::WEB_RTC; -} - -void WebRtcEndpointChannel::CloseImpl() { webrtc_socket_->Close(); } - -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h b/connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h deleted file mode 100644 index 6ceff1c6..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_endpoint_channel.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_ENDPOINT_CHANNEL_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_ENDPOINT_CHANNEL_H_ - -#include -#include - -#include "connections/implementation/base_endpoint_channel.h" -#include "connections/implementation/mediums/webrtc_socket.h" - -namespace nearby { -namespace connections { - -class WebRtcEndpointChannel final : public BaseEndpointChannel { - public: - WebRtcEndpointChannel(const std::string& service_id, - const std::string& channel_name, - std::shared_ptr socket); - - location::nearby::proto::connections::Medium GetMedium() const override; - - private: - void CloseImpl() override; - - std::shared_ptr webrtc_socket_; -}; - -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.cc b/connections/implementation/mediums/webrtc/webrtc_impl.cc deleted file mode 100644 index 9732aac9..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_impl.cc +++ /dev/null @@ -1,793 +0,0 @@ -// Copyright 2020 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. - -#include "connections/implementation/mediums/webrtc/webrtc_impl.h" - -#include -#include -#include -#include -#include - -#include "absl/container/flat_hash_set.h" -#include "absl/functional/bind_front.h" -#include "absl/time/time.h" -#include "connections/implementation/bwu_handler.h" -#include "connections/implementation/mediums/webrtc/connection_flow.h" -#include "connections/implementation/mediums/webrtc/session_description_wrapper.h" -#include "connections/implementation/mediums/webrtc/signaling_frames.h" -#include "connections/implementation/mediums/webrtc/webrtc.h" -#include "connections/implementation/mediums/webrtc/webrtc_bwu_handler.h" -#include "connections/implementation/mediums/webrtc_peer_id.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/cancelable_alarm.h" -#include "internal/platform/cancellation_flag.h" -#include "internal/platform/cancellation_flag_listener.h" -#include "internal/platform/exception.h" -#include "internal/platform/expected.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/future.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex_lock.h" -#include "internal/platform/runnable.h" -#include "webrtc/api/jsep.h" -#include "webrtc/rtc_base/network_constants.h" - -namespace nearby { -namespace connections { -namespace mediums { - -namespace { -using ::location::nearby::connections::LocationHint; -using ::location::nearby::proto::connections::OperationResultCode; - -// The maximum amount of time to wait to connect to a data channel via WebRTC. -constexpr absl::Duration kDataChannelTimeout = absl::Seconds(10); - -// Delay between restarting signaling messenger to receive messages. -constexpr absl::Duration kRestartReceiveMessagesDuration = absl::Seconds(60); - -} // namespace - -WebRtcImpl::WebRtcImpl() : WebRtcImpl(std::make_unique()) {} - -WebRtcImpl::WebRtcImpl(std::unique_ptr medium) - : medium_(std::move(medium)) {} - -WebRtcImpl::~WebRtcImpl() { - // This ensures that all pending callbacks are run before we reset the medium - // and we are not accepting new runnables. - single_thread_executor_.Shutdown(); - - // Stop accepting all connections - absl::flat_hash_set service_ids; - for (auto& item : accepting_connections_info_) { - service_ids.emplace(item.first); - } - for (const auto& service_id : service_ids) { - StopAcceptingConnections(service_id); - } -} - -bool WebRtcImpl::IsAvailable() { return medium_->IsValid(); } - -bool WebRtcImpl::IsAcceptingConnections(const std::string& service_id) { - MutexLock lock(&mutex_); - return IsAcceptingConnectionsLocked(service_id); -} - -bool WebRtcImpl::IsAcceptingConnectionsLocked(const std::string& service_id) { - return accepting_connections_info_.contains(service_id); -} - -bool WebRtcImpl::StartAcceptingConnections(const std::string& service_id, - const WebrtcPeerId& self_peer_id, - const LocationHint& location_hint, - AcceptedConnectionCallback callback, - bool non_cellular) { - MutexLock lock(&mutex_); - if (!IsAvailable()) { - LOG(WARNING) << "Cannot start accepting WebRTC connections because " - "WebRTC is not available."; - return false; - } - - if (IsAcceptingConnectionsLocked(service_id)) { - LOG(WARNING) << "Cannot start accepting WebRTC connections because service " - << service_id << "is already accepting WebRTC connections."; - return false; - } - - // We'll track our state here, so that we're separated from the other services - // who may be also using WebRTC. - AcceptingConnectionsInfo info = AcceptingConnectionsInfo(); - info.self_peer_id = self_peer_id; - info.accepted_connection_callback = std::move(callback); - - medium_->SetNonCellular(non_cellular); - - // Create a new SignalingMessenger so that we can communicate w/ Tachyon. - info.signaling_messenger = - medium_->GetSignalingMessenger(self_peer_id.GetId(), location_hint); - if (!info.signaling_messenger->IsValid()) { - return false; - } - - // This registers ourselves w/ Tachyon, creating a room from the PeerId. - // This allows a remote device to message us over Tachyon. - if (!info.signaling_messenger->StartReceivingMessages( - absl::bind_front(&WebRtcImpl::OnSignalingMessage, this, service_id), - absl::bind_front(&WebRtcImpl::OnSignalingComplete, this, - service_id))) { - info.signaling_messenger.reset(); - return false; - } - - // We'll automatically disconnect from Tachyon after 60sec. When this alarm - // fires, we'll recreate our room so we continue to receive messages. - info.restart_tachyon_receive_messages_alarm = - std::make_unique( - "restart_receiving_messages_webrtc", - std::bind(&WebRtcImpl::ProcessRestartTachyonReceiveMessages, this, - service_id), - kRestartReceiveMessagesDuration, &single_thread_executor_); - - // Now that we're set up to receive messages, we'll save our state and return - // a successful result. - accepting_connections_info_.emplace(service_id, std::move(info)); - LOG(INFO) << "Started listening for WebRTC connections as " - << self_peer_id.GetId() << " on service " << service_id; - return true; -} - -void WebRtcImpl::StopAcceptingConnections(const std::string& service_id) { - MutexLock lock(&mutex_); - if (!IsAcceptingConnectionsLocked(service_id)) { - LOG(WARNING) << "Cannot stop accepting WebRTC connections because service " - << service_id << "is not accepting WebRTC connections."; - return; - } - - // Grab our info from the map. - auto& info = accepting_connections_info_.find(service_id)->second; - - // Stop receiving messages from Tachyon. - info.signaling_messenger->StopReceivingMessages(); - info.signaling_messenger.reset(); - - // Cancel the scheduled alarm. - if (info.restart_tachyon_receive_messages_alarm && - info.restart_tachyon_receive_messages_alarm->IsValid()) { - info.restart_tachyon_receive_messages_alarm->Cancel(); - info.restart_tachyon_receive_messages_alarm.reset(); - } - - // If we had any in-progress connections that haven't materialized into full - // DataChannels yet, it's time to shut them down since they can't reach us - // anymore. - absl::flat_hash_set peer_ids; - for (auto& item : connection_flows_) { - peer_ids.emplace(item.first); - } - for (const auto& peer_id : peer_ids) { - const auto& entry = connection_flows_.find(peer_id); - // Skip outgoing connections in this step. Start/StopAcceptingConnections - // only deals with incoming connections. - if (requesting_connections_info_.contains(peer_id)) { - continue; - } - - // Skip fully connected connections in this step. If the connection was - // formed while we were accepting connections, then it will stay alive until - // it's explicitly closed. - if (!entry->second->CloseIfNotConnected()) { - continue; - } - - connection_flows_.erase(peer_id); - } - - // Clean up our state. We're now no longer listening for connections. - accepting_connections_info_.erase(service_id); - LOG(INFO) << "Stopped listening for WebRTC connections for service " - << service_id; -} - -ErrorOr> WebRtcImpl::Connect( - const std::string& service_id, const WebrtcPeerId& remote_peer_id, - const LocationHint& location_hint, CancellationFlag* cancellation_flag, - bool non_cellular) { - service_id_to_connect_attempts_count_map_[service_id] = 1; - medium_->SetNonCellular(non_cellular); - ErrorOr> wrapper_result = { - Error(OperationResultCode::DETAIL_UNKNOWN)}; - while (service_id_to_connect_attempts_count_map_[service_id] <= - kConnectAttemptsLimit) { - if (cancellation_flag->Cancelled()) { - LOG(WARNING) << "Attempt #" - << service_id_to_connect_attempts_count_map_[service_id] - << ": Cannot Connect with WebRtc due to cancel."; - return { - Error(OperationResultCode:: - CLIENT_CANCELLATION_CANCEL_WEB_RTC_OUTGOING_CONNECTION)}; - } - - LOG(INFO) << "Attempt #" - << service_id_to_connect_attempts_count_map_[service_id] - << ": Beginning connection."; - wrapper_result = AttemptToConnect(service_id, remote_peer_id, location_hint, - cancellation_flag); - if (wrapper_result.has_value()) { - return std::move(wrapper_result.value()); - } - - service_id_to_connect_attempts_count_map_[service_id]++; - } - - LOG(WARNING) << "Giving up after " << kConnectAttemptsLimit << " attempts"; - return {Error(wrapper_result.error().operation_result_code().value())}; -} - -ErrorOr> WebRtcImpl::AttemptToConnect( - const std::string& service_id, const WebrtcPeerId& remote_peer_id, - const LocationHint& location_hint, CancellationFlag* cancellation_flag) { - ConnectionRequestInfo info = ConnectionRequestInfo(); - info.self_peer_id = WebrtcPeerId::FromRandom(); - Future> socket_future = info.socket_future; - - // `listener` will go out of scope at the end of `AttemptToConnect`, and this - // is expected. This `listener` is tied to `socket_future` which we block on - // within this stack call, and will not go out of scope until the attempt - // is complete. - CancellationFlagListener listener( - cancellation_flag, [this, &service_id, &socket_future]() { - LOG(WARNING) << "Attempt # " - << service_id_to_connect_attempts_count_map_[service_id] - << " to connect with WebRtc stopped due to cancel."; - socket_future.SetException({Exception::kFailed}); - }); - - { - MutexLock lock(&mutex_); - if (!IsAvailable()) { - LOG(WARNING) << "Cannot connect to WebRTC peer " << remote_peer_id.GetId() - << " because WebRTC is not available."; - return { - Error(OperationResultCode::MEDIUM_UNAVAILABLE_WEB_RTC_NOT_AVAILABLE)}; - } - - // Create a new ConnectionFlow for this connection attempt. - std::unique_ptr connection_flow = - CreateConnectionFlow(service_id, remote_peer_id); - if (!connection_flow) { - LOG(INFO) << "Cannot connect to WebRTC peer " << remote_peer_id.GetId() - << " because we failed to create a ConnectionFlow."; - return {Error(OperationResultCode::NEARBY_WEB_RTC_CONNECTION_FLOW_NULL)}; - } - - // Create a new SignalingMessenger so that we can communicate over Tachyon. - info.signaling_messenger = medium_->GetSignalingMessenger( - info.self_peer_id.GetId(), location_hint); - if (!info.signaling_messenger->IsValid()) { - LOG(INFO) << "Cannot connect to WebRTC peer " << remote_peer_id.GetId() - << " because we failed to create a SignalingMessenger."; - return { - Error(OperationResultCode:: - MISCELLEANEOUS_WEB_RTC_TACHYON_SIGNALING_MESSENGER_NULL)}; - } - - // This registers ourselves w/ Tachyon, creating a room from the PeerId. - // This allows a remote device to message us over Tachyon. - auto signaling_complete_callback = [socket_future](bool success) mutable { - if (!success) { - socket_future.SetException({Exception::kFailed}); - } - }; - if (!info.signaling_messenger->StartReceivingMessages( - absl::bind_front(&WebRtcImpl::OnSignalingMessage, this, service_id), - signaling_complete_callback)) { - LOG(INFO) - << "Cannot connect to WebRTC peer " << remote_peer_id.GetId() - << " because we failed to start receiving messages over Tachyon."; - info.signaling_messenger.reset(); - return {Error(OperationResultCode:: - MISCELLEANEOUS_WEB_RTC_FAILED_TO_RECEIVE_MESSAGE)}; - } - - // Poke the remote device. This will cause them to send us an Offer. - if (!info.signaling_messenger->SendMessage( - remote_peer_id.GetId(), - webrtc_frames::EncodeReadyForSignalingPoke(info.self_peer_id))) { - LOG(INFO) << "Cannot connect to WebRTC peer " << remote_peer_id.GetId() - << " because we failed to poke the peer over Tachyon."; - info.signaling_messenger.reset(); - return {Error(OperationResultCode:: - CONNECTIVITY_WEB_RTC_CONNECT_TO_TACHYON_FAILURE)}; - } - - // Create a new ConnectionRequest entry. This map will be used later to look - // up state as we negotiate the connection over Tachyon. - requesting_connections_info_.emplace(remote_peer_id.GetId(), - std::move(info)); - connection_flows_.emplace(remote_peer_id.GetId(), - std::move(connection_flow)); - } - - // Wait for the connection to go through. Don't hold the mutex here so that - // we're not blocking necessary operations. - ExceptionOr> socket_result = - socket_future.Get(kDataChannelTimeout); - - { - MutexLock lock(&mutex_); - - // Reclaim our info, since we had released ownership while talking to - // Tachyon. - auto& info = - requesting_connections_info_.find(remote_peer_id.GetId())->second; - - // Verify that the connection went through. - if (!socket_result.ok()) { - LOG(INFO) << "Failed to connect to WebRTC peer " - << remote_peer_id.GetId(); - RemoveConnectionFlow(remote_peer_id); - info.signaling_messenger.reset(); - requesting_connections_info_.erase(remote_peer_id.GetId()); - return {Error(OperationResultCode:: - CONNECTIVITY_WEB_RTC_CLIENT_SOCKET_CREATION_FAILURE)}; - } - - // Clean up our ConnectionRequest. - info.signaling_messenger.reset(); - requesting_connections_info_.erase(remote_peer_id.GetId()); - - // Return the result. - return socket_result.GetResult(); - } -} - -void WebRtcImpl::ProcessLocalIceCandidate( - const std::string& service_id, const WebrtcPeerId& remote_peer_id, - const location::nearby::mediums::IceCandidate ice_candidate) { - MutexLock lock(&mutex_); - - // Check first if we have an outgoing request w/ this peer. As this request is - // tied to a specific peer, it takes precedence. - const auto& connection_request_entry = - requesting_connections_info_.find(remote_peer_id.GetId()); - if (connection_request_entry != requesting_connections_info_.end()) { - // Pass the ice candidate to the remote side. - if (!connection_request_entry->second.signaling_messenger->SendMessage( - remote_peer_id.GetId(), - webrtc_frames::EncodeIceCandidates( - connection_request_entry->second.self_peer_id, - {ice_candidate}))) { - LOG(INFO) << "Failed to send ice candidate to " << remote_peer_id.GetId(); - } - - LOG(INFO) << "Sent ice candidate to " << remote_peer_id.GetId(); - return; - } - - // Check next if we're expecting incoming connection requests. - const auto& accepting_connection_entry = - accepting_connections_info_.find(service_id); - if (accepting_connection_entry != accepting_connections_info_.end()) { - // Pass the ice candidate to the remote side. - // TODO(xlythe) Consider not blocking here, since this can eat into the - // connection time - if (!accepting_connection_entry->second.signaling_messenger->SendMessage( - remote_peer_id.GetId(), - webrtc_frames::EncodeIceCandidates( - accepting_connection_entry->second.self_peer_id, - {ice_candidate}))) { - LOG(INFO) << "Failed to send ice candidate to " << remote_peer_id.GetId(); - } - - LOG(INFO) << "Sent ice candidate to " << remote_peer_id.GetId(); - return; - } - - LOG(INFO) << "Skipping restart listening for tachyon inbox messages " - "since we are not accepting connections for service " - << service_id; -} - -void WebRtcImpl::OnSignalingMessage(const std::string& service_id, - const ByteArray& message) { - OffloadFromThread("rtc-on-signaling-message", [this, service_id, message]() { - ProcessTachyonInboxMessage(service_id, message); - }); -} - -void WebRtcImpl::OnSignalingComplete(const std::string& service_id, - bool success) { - LOG(INFO) << "Signaling completed with status: " << success; - if (success) { - return; - } - - OffloadFromThread("rtc-on-signaling-complete", [this, service_id]() { - MutexLock lock(&mutex_); - const auto& info_entry = accepting_connections_info_.find(service_id); - if (info_entry == accepting_connections_info_.end()) { - return; - } - - if (info_entry->second.restart_accept_connections_count < - kRestartAcceptConnectionsLimit) { - ++info_entry->second.restart_accept_connections_count; - } else { - return; - } - - RestartTachyonReceiveMessages(service_id); - }); -} - -void WebRtcImpl::ProcessTachyonInboxMessage(const std::string& service_id, - const ByteArray& message) { - MutexLock lock(&mutex_); - - // Attempt to parse the incoming message as a WebRtcSignalingFrame. - location::nearby::mediums::WebRtcSignalingFrame frame; - if (!frame.ParseFromString(std::string(message))) { - LOG(WARNING) << "Failed to parse signaling message."; - return; - } - - // Ensure that the frame is valid (no missing fields). - if (!frame.has_sender_id()) { - LOG(WARNING) << "Invalid WebRTC frame: Sender ID is missing."; - return; - } - WebrtcPeerId remote_peer_id = WebrtcPeerId(frame.sender_id().id()); - - // Depending on the message type, we'll respond as appropriate. - if (requesting_connections_info_.contains(remote_peer_id.GetId())) { - // This is from a peer we have an outgoing connection request with, so we'll - // only process the Answer path. - if (frame.has_offer()) { - ReceiveOffer(remote_peer_id, - SessionDescriptionWrapper( - webrtc_frames::DecodeOffer(frame).release())); - SendAnswer(remote_peer_id); - } else if (frame.has_ice_candidates()) { - ReceiveIceCandidates(remote_peer_id, - webrtc_frames::DecodeIceCandidates(frame)); - } else { - LOG(INFO) << "Received unknown WebRTC frame: ignoring."; - } - } else if (IsAcceptingConnectionsLocked(service_id)) { - // We don't have an outgoing connection request with this peer, but we are - // accepting incoming requests so we'll only process the Offer path. - if (frame.has_ready_for_signaling_poke()) { - SendOffer(service_id, remote_peer_id); - } else if (frame.has_answer()) { - ReceiveAnswer(remote_peer_id, - SessionDescriptionWrapper( - webrtc_frames::DecodeAnswer(frame).release())); - } else if (frame.has_ice_candidates()) { - ReceiveIceCandidates(remote_peer_id, - webrtc_frames::DecodeIceCandidates(frame)); - } else { - LOG(INFO) << "Received unknown WebRTC frame: ignoring."; - } - } else { - LOG(INFO) - << "Ignoring Tachyon message since we are not accepting connections."; - } -} - -void WebRtcImpl::SendOffer(const std::string& service_id, - const WebrtcPeerId& remote_peer_id) { - std::unique_ptr connection_flow = - CreateConnectionFlow(service_id, remote_peer_id); - if (!connection_flow) { - LOG(INFO) << "Unable to send offer. Failed to create a ConnectionFlow."; - return; - } - - SessionDescriptionWrapper offer = connection_flow->CreateOffer(); - if (!offer.IsValid()) { - LOG(INFO) << "Unable to send offer. Failed to create our offer locally."; - RemoveConnectionFlow(remote_peer_id); - return; - } - - const webrtc::SessionDescriptionInterface& sdp = offer.GetSdp(); - if (!connection_flow->SetLocalSessionDescription(offer)) { - LOG(INFO) << "Unable to send offer. Failed to register our offer locally."; - RemoveConnectionFlow(remote_peer_id); - return; - } - - // Grab our info from the map. - auto& info = accepting_connections_info_.find(service_id)->second; - - // Pass the offer to the remote side. - if (!info.signaling_messenger->SendMessage( - remote_peer_id.GetId(), - webrtc_frames::EncodeOffer(info.self_peer_id, sdp))) { - LOG(INFO) - << "Unable to send offer. Failed to write the offer to the remote peer " - << remote_peer_id.GetId(); - RemoveConnectionFlow(remote_peer_id); - return; - } - - // Store the ConnectionFlow so that other methods can use it later. - connection_flows_.emplace(remote_peer_id.GetId(), std::move(connection_flow)); - LOG(INFO) << "Sent offer to " << remote_peer_id.GetId(); -} - -void WebRtcImpl::ReceiveOffer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper offer) { - const auto& entry = connection_flows_.find(remote_peer_id.GetId()); - if (entry == connection_flows_.end()) { - LOG(INFO) << "Unable to receive offer. Failed to create a ConnectionFlow."; - return; - } - - if (!entry->second->OnOfferReceived(offer)) { - LOG(INFO) << "Unable to receive offer. Failed to process the offer."; - RemoveConnectionFlow(remote_peer_id); - } -} - -void WebRtcImpl::SendAnswer(const WebrtcPeerId& remote_peer_id) { - const auto& entry = connection_flows_.find(remote_peer_id.GetId()); - if (entry == connection_flows_.end()) { - LOG(INFO) << "Unable to send answer. Failed to create a ConnectionFlow."; - return; - } - - SessionDescriptionWrapper answer = entry->second->CreateAnswer(); - if (!answer.IsValid()) { - LOG(INFO) << "Unable to send answer. Failed to create our answer locally."; - RemoveConnectionFlow(remote_peer_id); - return; - } - - const webrtc::SessionDescriptionInterface& sdp = answer.GetSdp(); - if (!entry->second->SetLocalSessionDescription(answer)) { - LOG(INFO) - << "Unable to send answer. Failed to register our answer locally."; - RemoveConnectionFlow(remote_peer_id); - return; - } - - // Grab our info from the map. - const auto& connection_request_entry = - requesting_connections_info_.find(remote_peer_id.GetId()); - if (connection_request_entry == requesting_connections_info_.end()) { - LOG(INFO) << "Unable to send answer. Failed to find an outgoing " - "connection request."; - RemoveConnectionFlow(remote_peer_id); - return; - } - - // Pass the answer to the remote side. - if (!connection_request_entry->second.signaling_messenger->SendMessage( - remote_peer_id.GetId(), - webrtc_frames::EncodeAnswer( - connection_request_entry->second.self_peer_id, sdp))) { - LOG(INFO) - << "Unable to send answer. Failed to write the answer to the remote " - "peer " - << remote_peer_id.GetId(); - RemoveConnectionFlow(remote_peer_id); - return; - } - - LOG(INFO) << "Sent answer to " << remote_peer_id.GetId(); -} - -void WebRtcImpl::ReceiveAnswer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper answer) { - const auto& entry = connection_flows_.find(remote_peer_id.GetId()); - if (entry == connection_flows_.end()) { - LOG(INFO) << "Unable to receive answer. Failed to create a ConnectionFlow."; - return; - } - - if (!entry->second->OnAnswerReceived(answer)) { - LOG(INFO) << "Unable to receive answer. Failed to process the answer."; - RemoveConnectionFlow(remote_peer_id); - } -} - -void WebRtcImpl::ReceiveIceCandidates( - const WebrtcPeerId& remote_peer_id, - std::vector> ice_candidates) { - const auto& entry = connection_flows_.find(remote_peer_id.GetId()); - if (entry == connection_flows_.end()) { - LOG(INFO) << "Unable to receive ice candidates. Failed to create a " - "ConnectionFlow."; - return; - } - - entry->second->OnRemoteIceCandidatesReceived(std::move(ice_candidates)); -} - -void WebRtcImpl::ProcessRestartTachyonReceiveMessages( - const std::string& service_id) { - MutexLock lock(&mutex_); - RestartTachyonReceiveMessages(service_id); -} - -void WebRtcImpl::RestartTachyonReceiveMessages(const std::string& service_id) { - if (!IsAcceptingConnectionsLocked(service_id)) { - LOG(INFO) - << "Skipping restart listening for tachyon inbox messages since we are " - "not accepting connections for service " - << service_id; - return; - } - - // Grab our info from the map. - auto& info = accepting_connections_info_.find(service_id)->second; - - // Ensure we've disconnected from Tachyon. - info.signaling_messenger->StopReceivingMessages(); - - // Attempt to re-register. - if (!info.signaling_messenger->StartReceivingMessages( - absl::bind_front(&WebRtcImpl::OnSignalingMessage, this, service_id), - absl::bind_front(&WebRtcImpl::OnSignalingComplete, this, - service_id))) { - LOG(WARNING) - << "Failed to restart listening for tachyon inbox messages for " - "service " - << service_id << " since we failed to reach Tachyon."; - return; - } - - LOG(INFO) << "Successfully restarted listening for tachyon inbox " - "messages on service " - << service_id; -} - -void WebRtcImpl::ProcessDataChannelOpen( - const std::string& service_id, const WebrtcPeerId& remote_peer_id, - std::shared_ptr socket_wrapper) { - MutexLock lock(&mutex_); - - // Notify the client of the newly formed socket. - const auto& connection_request_entry = - requesting_connections_info_.find(remote_peer_id.GetId()); - if (connection_request_entry != requesting_connections_info_.end()) { - connection_request_entry->second.socket_future.Set(socket_wrapper); - return; - } - - const auto& accepting_connection_entry = - accepting_connections_info_.find(service_id); - if (accepting_connection_entry != accepting_connections_info_.end() && - accepting_connection_entry->second.accepted_connection_callback) { - accepting_connection_entry->second.accepted_connection_callback( - service_id, socket_wrapper); - return; - } - - // No one to handle the newly created DataChannel, so we'll just close it. - socket_wrapper->Close(); - LOG(INFO) << "Ignoring new DataChannel because we are not accepting " - "connections for service " - << service_id; -} - -void WebRtcImpl::ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) { - MutexLock lock(&mutex_); - LOG(INFO) << "Data channel has closed, removing connection flow for peer " - << remote_peer_id.GetId(); - - RemoveConnectionFlow(remote_peer_id); -} - -std::unique_ptr WebRtcImpl::CreateConnectionFlow( - const std::string& service_id, const WebrtcPeerId& remote_peer_id) { - RemoveConnectionFlow(remote_peer_id); - - return ConnectionFlow::Create( - {.local_ice_candidate_found_cb = - {[this, service_id, - remote_peer_id](const webrtc::IceCandidate* ice_candidate) { - // Note: We need to encode the ice candidate here, before we jump - // off the thread. Otherwise, it gets destroyed and we can't read - // it later. - location::nearby::mediums::IceCandidate encoded_ice_candidate = - webrtc_frames::EncodeIceCandidate(*ice_candidate); - OffloadFromThread( - "rtc-ice-candidates", - [this, service_id, remote_peer_id, encoded_ice_candidate]() { - ProcessLocalIceCandidate(service_id, remote_peer_id, - encoded_ice_candidate); - }); - }}}, - { - .data_channel_open_cb = {[this, service_id, remote_peer_id]( - std::shared_ptr - socket_wrapper) { - OffloadFromThread( - "rtc-channel-created", - [this, service_id, remote_peer_id, socket_wrapper]() { - ProcessDataChannelOpen(service_id, remote_peer_id, - socket_wrapper); - }); - }}, - .data_channel_closed_cb = {[this, remote_peer_id]() { - OffloadFromThread("rtc-channel-closed", [this, remote_peer_id]() { - ProcessDataChannelClosed(remote_peer_id); - }); - }}, - }, - { - .adapter_type_changed_cb = {[this](webrtc::AdapterType adapter_type) { - OffloadFromThread("rtc-adapter-type-changed", - [this, adapter_type]() { - if (FeatureFlags::GetInstance() - .GetFlags() - .support_web_rtc_non_cellular_medium) { - AdapterTypeChangedHandler(adapter_type); - } - }); - }}, - }, - *medium_); -} - -void WebRtcImpl::AdapterTypeChangedHandler(webrtc::AdapterType adapter_type) { - MutexLock lock(&mutex_); - is_using_cellular_ = adapter_type == webrtc::ADAPTER_TYPE_CELLULAR || - adapter_type == webrtc::ADAPTER_TYPE_CELLULAR_2G || - adapter_type == webrtc::ADAPTER_TYPE_CELLULAR_3G || - adapter_type == webrtc::ADAPTER_TYPE_CELLULAR_4G || - adapter_type == webrtc::ADAPTER_TYPE_CELLULAR_5G; -} - -void WebRtcImpl::RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) { - if (!connection_flows_.erase(remote_peer_id.GetId())) { - return; - } - - // If we had an outgoing connection request w/ this peer, report the failure - // to the future that's being waited on. - const auto& connection_request_entry = - requesting_connections_info_.find(remote_peer_id.GetId()); - if (connection_request_entry != requesting_connections_info_.end()) { - connection_request_entry->second.socket_future.SetException( - {Exception::kFailed}); - } -} - -void WebRtcImpl::OffloadFromThread(const std::string& name, Runnable runnable) { - single_thread_executor_.Execute(name, std::move(runnable)); -} - -bool WebRtcImpl::IsUsingCellular() { - MutexLock lock(&mutex_); - return is_using_cellular_; -} - -std::unique_ptr WebRtcImpl::CreateBwuHandler( - BwuHandler::IncomingConnectionCallback incoming_connection_callback) { - return std::make_unique( - this, std::move(incoming_connection_callback)); -} - -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/webrtc/webrtc_impl.h b/connections/implementation/mediums/webrtc/webrtc_impl.h deleted file mode 100644 index 92d9d5b4..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_impl.h +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_ - -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/container/flat_hash_map.h" -#include "connections/implementation/bwu_handler.h" -#include "connections/implementation/mediums/webrtc.h" -#include "connections/implementation/mediums/webrtc/connection_flow.h" -#include "connections/implementation/mediums/webrtc/session_description_wrapper.h" -#include "connections/implementation/mediums/webrtc/webrtc.h" -#include "connections/implementation/mediums/webrtc_peer_id.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/cancelable_alarm.h" -#include "internal/platform/cancellation_flag.h" -#include "internal/platform/expected.h" -#include "internal/platform/future.h" -#include "internal/platform/mutex.h" -#include "internal/platform/runnable.h" -#include "internal/platform/scheduled_executor.h" -#include "proto/mediums/web_rtc_signaling_frames.pb.h" -#include "webrtc/api/jsep.h" -#include "webrtc/rtc_base/network_constants.h" - -namespace nearby { -namespace connections { -namespace mediums { - -// Entry point for connecting a data channel between two devices via WebRtc. -class WebRtcImpl : public WebRtc { - public: - WebRtcImpl(); - ~WebRtcImpl() override; - - // Overrides for WebRtc: - bool IsAvailable() override; - bool IsAcceptingConnections(const std::string& service_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - bool StartAcceptingConnections( - const std::string& service_id, const WebrtcPeerId& self_peer_id, - const location::nearby::connections::LocationHint& location_hint, - AcceptedConnectionCallback callback, bool non_cellular) override - ABSL_LOCKS_EXCLUDED(mutex_); - void StopAcceptingConnections(const std::string& service_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - ErrorOr> Connect( - const std::string& service_id, const WebrtcPeerId& peer_id, - const location::nearby::connections::LocationHint& location_hint, - CancellationFlag* cancellation_flag, bool non_cellular) override - ABSL_LOCKS_EXCLUDED(mutex_); - bool IsUsingCellular() override ABSL_LOCKS_EXCLUDED(mutex_); - std::unique_ptr CreateBwuHandler( - BwuHandler::IncomingConnectionCallback incoming_connection_callback) - override; - - protected: - // Use for unit tests only to inject a WebRtcMedium. - explicit WebRtcImpl(std::unique_ptr medium); - - // Used in unit tests to determine how many calls to `AttemptToConnect` - // occured during a call to `Connect`, per service id. - std::map service_id_to_connect_attempts_count_map_; - - private: - static constexpr int kConnectAttemptsLimit = 3; - static constexpr int kRestartAcceptConnectionsLimit = 3; - - enum class Role { - kNone = 0, - kOfferer = 1, - kAnswerer = 2, - }; - - struct AcceptingConnectionsInfo { - // The self_peer_id is generated from the BT/WiFi advertisements and allows - // the scanner to message us over Tachyon. - WebrtcPeerId self_peer_id; - - // The registered callback. When there's an incoming connection, this - // callback is notified. - AcceptedConnectionCallback accepted_connection_callback; - - // Allows us to communicate with the Tachyon web server. - std::unique_ptr signaling_messenger; - - // Restarts the tachyon inbox receives messages streaming rpc if the - // streaming rpc times out. The streaming rpc times out after 60s while - // advertising. Non-null when listening for WebRTC connections as an - // offerer. - std::unique_ptr restart_tachyon_receive_messages_alarm; - - // Tracks the number of times we've restarted receiving messages after a - // failure. We limit the number to prevent endless restarts if we are - // repeatedly unable to communicate with Tachyon. - int restart_accept_connections_count = 0; - }; - - struct ConnectionRequestInfo { - // The self_peer_id is randomly generated and allows the advertiser to - // message us over Tachyon. - WebrtcPeerId self_peer_id; - - // Allows us to communicate with the Tachyon web server. - std::unique_ptr signaling_messenger; - - // The pending DataChannel future. Our client will be blocked on this while - // they wait for us to set up the channel over Tachyon. - Future> socket_future; - }; - - // Attempt to initiates a WebRtc connection with peer device identified by - // |peer_id|. - // Runs on @MainThread. - ErrorOr> AttemptToConnect( - const std::string& service_id, const WebrtcPeerId& peer_id, - const location::nearby::connections::LocationHint& location_hint, - CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns if the device is accepting connection with specific service id. - // Runs on @MainThread. - bool IsAcceptingConnectionsLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Receives a message from the signaling messenger. - void OnSignalingMessage(const std::string& service_id, - const ByteArray& message); - - // Decides whether to restart receiving messages. - void OnSignalingComplete(const std::string& service_id, bool success); - - // Runs on |single_thread_executor_|. - void ProcessTachyonInboxMessage(const std::string& service_id, - const ByteArray& message) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void SendOffer(const std::string& service_id, - const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ReceiveOffer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper offer) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void SendAnswer(const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ReceiveAnswer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper answer) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ReceiveIceCandidates( - const WebrtcPeerId& remote_peer_id, - std::vector> ice_candidates) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - std::unique_ptr CreateConnectionFlow( - const std::string& service_id, const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - std::unique_ptr GetConnectionFlow( - const WebrtcPeerId& remote_peer_id) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessDataChannelOpen(const std::string& service_id, - const WebrtcPeerId& remote_peer_id, - std::shared_ptr socket_wrapper) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessLocalIceCandidate( - const std::string& service_id, const WebrtcPeerId& remote_peer_id, - location::nearby::mediums::IceCandidate ice_candidate) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessRestartTachyonReceiveMessages(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void RestartTachyonReceiveMessages(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void AdapterTypeChangedHandler(webrtc::AdapterType adapter_type) - ABSL_LOCKS_EXCLUDED(mutex_); - - void OffloadFromThread(const std::string& name, Runnable runnable); - - Mutex mutex_; - - std::unique_ptr medium_; - - // The single thread we throw the potentially blocking work on to. - ScheduledExecutor single_thread_executor_; - - // A map of ServiceID -> State for all services that are listening for - // incoming connections. - absl::flat_hash_map - accepting_connections_info_ ABSL_GUARDED_BY(mutex_); - - // A map of a remote PeerId -> State for pending connection requests. As - // messages from Tachyon come in, this lets us look up the connection request - // info to handle the interaction. - absl::flat_hash_map - requesting_connections_info_ ABSL_GUARDED_BY(mutex_); - - // A map of a remote PeerId -> ConnectionFlow. For each connection, we create - // a unique ConnectionFlow. - absl::flat_hash_map> - connection_flows_ ABSL_GUARDED_BY(mutex_); - - bool is_using_cellular_ ABSL_GUARDED_BY(mutex_) = true; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_impl_test.cc b/connections/implementation/mediums/webrtc/webrtc_impl_test.cc deleted file mode 100644 index 6b50243b..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_impl_test.cc +++ /dev/null @@ -1,651 +0,0 @@ -// Copyright 2020 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. - -#include "connections/implementation/mediums/webrtc/webrtc_impl.h" - -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "connections/implementation/mediums/webrtc.h" -#include "connections/implementation/mediums/webrtc/fake_webrtc.h" -#include "connections/implementation/mediums/webrtc/webrtc.h" -#include "connections/implementation/mediums/webrtc_peer_id.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/cancellation_flag.h" -#include "internal/platform/exception.h" -#include "internal/platform/expected.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/future.h" -#include "internal/platform/medium_environment.h" - -namespace nearby { -namespace connections { -namespace mediums { - -namespace { - -using FeatureFlags = FeatureFlags::Flags; -using ::location::nearby::connections::LocationHint; - -struct WebRtcTestParams { - FeatureFlags feature_flags; - bool non_cellular; -}; - -class TestWebRtc : public WebRtcImpl { - public: - explicit TestWebRtc(std::unique_ptr medium) - : WebRtcImpl(std::move(medium)) {} - - int connect_attempts_count(std::string service_id) { - return service_id_to_connect_attempts_count_map_[service_id]; - } -}; - -class WebRtcTest : public ::testing::TestWithParam { - protected: - using MockAcceptedCallback = testing::MockFunction socket)>; - - MediumEnvironment& env_{MediumEnvironment::Instance()}; -}; - -// Tests the flow when the two devices exchange SDP messages and connect to each -// other but the signaling channel is closed before sending the data. -TEST_P(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) { - env_.Start({.webrtc_enabled = true}); - WebRtcTestParams params = GetParam(); - env_.SetFeatureFlags(params.feature_flags); - WebRtcImpl receiver, sender; - std::shared_ptr receiver_socket; - const WebrtcPeerId self_id("self_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future connected; - absl::string_view message("message xyz"); - - receiver.StartAcceptingConnections( - service_id, self_id, location_hint, - [&receiver_socket, connected]( - const std::string& service_id, - std::shared_ptr wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket->IsValid()); - }, - params.non_cellular); - - CancellationFlag flag; - ErrorOr> sender_socket_result = sender.Connect( - service_id, self_id, location_hint, &flag, params.non_cellular); - ASSERT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value()->IsValid()); - - ExceptionOr devices_connected = connected.Get(); - ASSERT_TRUE(devices_connected.ok()); - EXPECT_TRUE(devices_connected.result()); - - // Only shuts down signaling channel. - receiver.StopAcceptingConnections(service_id); - - sender_socket_result.value()->GetOutputStream().Write(message); - ExceptionOr received_msg = - receiver_socket->GetInputStream().Read(/*size=*/32); - ASSERT_TRUE(received_msg.ok()); - EXPECT_EQ(message, received_msg.result().AsStringView()); - env_.Stop(); -} - -TEST_P(WebRtcTest, CanCancelConnect) { - env_.Start({.webrtc_enabled = true}); - WebRtcTestParams params = GetParam(); - env_.SetFeatureFlags(params.feature_flags); - WebRtcImpl receiver, sender; - std::shared_ptr receiver_socket; - const WebrtcPeerId self_id("self_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future connected; - absl::string_view message("message"); - - receiver.StartAcceptingConnections( - service_id, self_id, location_hint, - [&receiver_socket, connected]( - const std::string& service_id, - std::shared_ptr wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket->IsValid()); - }, - params.non_cellular); - - CancellationFlag flag(true); - ErrorOr> sender_socket_result = sender.Connect( - service_id, self_id, location_hint, &flag, params.non_cellular); - // If FeatureFlag is disabled, Cancelled is false as no-op. - if (!params.feature_flags.enable_cancellation_flag) { - ASSERT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value()->IsValid()); - - ExceptionOr devices_connected = connected.Get(); - ASSERT_TRUE(devices_connected.ok()); - EXPECT_TRUE(devices_connected.result()); - - sender_socket_result.value()->GetOutputStream().Write(message); - ExceptionOr received_msg = - receiver_socket->GetInputStream().Read(/*size=*/32); - ASSERT_TRUE(received_msg.ok()); - EXPECT_EQ(message, received_msg.result().AsStringView()); - - receiver_socket->Close(); - } else { - EXPECT_TRUE(sender_socket_result.has_error()); - } - env_.Stop(); -} - -// Basic test to check that device is accepting connections when initialized. -TEST_P(WebRtcTest, NotAcceptingConnections) { - env_.Start({.webrtc_enabled = true}); - WebRtcImpl webrtc; - ASSERT_TRUE(webrtc.IsAvailable()); - EXPECT_FALSE(webrtc.IsAcceptingConnections(std::string{})); - env_.Stop(); -} - -// Tests the flow when the device tries to accept connections twice. In this -// case, only the first call is successful and subsequent calls fail. -TEST_P(WebRtcTest, StartAcceptingConnectionTwice) { - env_.Start({.webrtc_enabled = true}); - WebRtcTestParams params = GetParam(); - testing::StrictMock mock_accepted_callback_; - WebRtcImpl webrtc; - WebrtcPeerId self_id("peer_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint{}; - - ASSERT_TRUE(webrtc.IsAvailable()); - ASSERT_TRUE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - mock_accepted_callback_.AsStdFunction(), params.non_cellular)); - EXPECT_FALSE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - mock_accepted_callback_.AsStdFunction(), params.non_cellular)); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - EXPECT_FALSE(webrtc.IsAcceptingConnections(std::string{})); - env_.Stop(); -} - -// Tests the flow when the device tries to connect but there is no peer -// accepting connections at the given peer ID. -TEST_P(WebRtcTest, Connect_NoPeer) { - env_.Start({.webrtc_enabled = true}); - WebRtcTestParams params = GetParam(); - WebRtcImpl webrtc; - WebrtcPeerId peer_id("peer_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - - ASSERT_TRUE(webrtc.IsAvailable()); - CancellationFlag flag; - ErrorOr> wrapper_1_result = webrtc.Connect( - service_id, peer_id, location_hint, &flag, params.non_cellular); - EXPECT_TRUE(wrapper_1_result.has_error()); - - EXPECT_TRUE(webrtc.StartAcceptingConnections( - service_id, peer_id, location_hint, nullptr, params.non_cellular)); - env_.Stop(); -} - -// Tests the flow when the device calls Connect() after calling -// StartAcceptingConnections() without StopAcceptingConnections(). -TEST_P(WebRtcTest, StartAcceptingConnection_ThenConnect) { - env_.Start({.webrtc_enabled = true}); - testing::StrictMock mock_accepted_callback_; - WebRtcTestParams params = GetParam(); - WebRtcImpl webrtc; - WebrtcPeerId self_id("peer_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - - ASSERT_TRUE(webrtc.IsAvailable()); - ASSERT_TRUE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - mock_accepted_callback_.AsStdFunction(), params.non_cellular)); - CancellationFlag flag; - ErrorOr> wrapper_result = - webrtc.Connect(service_id, WebrtcPeerId("random_peer_id"), location_hint, - &flag, params.non_cellular); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - EXPECT_TRUE(wrapper_result.has_error()); - EXPECT_FALSE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - mock_accepted_callback_.AsStdFunction(), params.non_cellular)); - env_.Stop(); -} - -// Tests the flow when the device calls StartAcceptingConnections but the medium -// is closed before a peer device can connect to it. -TEST_P(WebRtcTest, StartAndStopAcceptingConnections) { - env_.Start({.webrtc_enabled = true}); - testing::StrictMock mock_accepted_callback_; - WebRtcTestParams params = GetParam(); - WebRtcImpl webrtc; - WebrtcPeerId self_id("peer_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - - ASSERT_TRUE(webrtc.IsAvailable()); - ASSERT_TRUE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - mock_accepted_callback_.AsStdFunction(), params.non_cellular)); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - webrtc.StopAcceptingConnections(service_id); - EXPECT_FALSE(webrtc.IsAcceptingConnections(service_id)); - env_.Stop(); -} - -// Tests the flow when the device tries to connect to two different peers -// without disconnecting in between. -TEST_P(WebRtcTest, ConnectTwice) { - env_.Start({.webrtc_enabled = true}); - WebRtcImpl receiver, sender, device_c; - std::shared_ptr receiver_socket; - WebRtcTestParams params = GetParam(); - const WebrtcPeerId self_id("self_id"), other_id("other_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future connected; - absl::string_view message("message xyz"); - - receiver.StartAcceptingConnections( - service_id, self_id, location_hint, - [&receiver_socket, connected]( - const std::string& service_id, - std::shared_ptr wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket->IsValid()); - }, - params.non_cellular); - - device_c.StartAcceptingConnections( - service_id, other_id, location_hint, - [](const std::string& service_id, std::shared_ptr wrapper) { - }, - params.non_cellular); - - CancellationFlag flag; - ErrorOr> sender_socket_result = sender.Connect( - service_id, self_id, location_hint, &flag, params.non_cellular); - ASSERT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value()->IsValid()); - - ExceptionOr devices_connected = connected.Get(); - ASSERT_TRUE(devices_connected.ok()); - EXPECT_TRUE(devices_connected.result()); - - ErrorOr> socket_result = sender.Connect( - service_id, other_id, location_hint, &flag, params.non_cellular); - EXPECT_TRUE(socket_result.has_value()); - EXPECT_TRUE(socket_result.value()->IsValid()); - socket_result.value()->Close(); - - EXPECT_TRUE(receiver_socket->IsValid()); - ASSERT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value()->IsValid()); - - sender_socket_result.value()->GetOutputStream().Write(message); - ExceptionOr received_msg = - receiver_socket->GetInputStream().Read(/*size=*/32); - ASSERT_TRUE(received_msg.ok()); - EXPECT_EQ(message, received_msg.result().AsStringView()); - - receiver_socket->Close(); - env_.Stop(); -} - -// Tests the flow when the two devices exchange SDP messages and connect to each -// other but disconnect before being able to send/receive the actual data. -TEST_P(WebRtcTest, ConnectBothDevicesAndAbort) { - env_.Start({.webrtc_enabled = true}); - WebRtcImpl receiver, sender; - std::shared_ptr receiver_socket, sender_socket; - WebRtcTestParams params = GetParam(); - const WebrtcPeerId self_id("self_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future connected; - - receiver.StartAcceptingConnections( - service_id, self_id, location_hint, - [&receiver_socket, connected]( - const std::string& service_id, - std::shared_ptr wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket->IsValid()); - }, - params.non_cellular); - - CancellationFlag flag; - ErrorOr> sender_socket_result = sender.Connect( - service_id, self_id, location_hint, &flag, params.non_cellular); - ASSERT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value()->IsValid()); - - ExceptionOr devices_connected = connected.Get(); - ASSERT_TRUE(devices_connected.ok()); - EXPECT_TRUE(devices_connected.result()); - - receiver_socket->Close(); - env_.Stop(); -} - -// Tests the flow when the two devices exchange SDP messages and connect to each -// other and the actual data is exchanged successfully between the devices. -TEST_P(WebRtcTest, ConnectBothDevicesAndSendData) { - env_.Start({.webrtc_enabled = true}); - WebRtcImpl receiver, sender; - std::shared_ptr receiver_socket; - WebRtcTestParams params = GetParam(); - const WebrtcPeerId self_id("self_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future connected; - absl::string_view message("message"); - - receiver.StartAcceptingConnections( - service_id, self_id, location_hint, - [&receiver_socket, connected]( - const std::string& service_id, - std::shared_ptr wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket->IsValid()); - }, - params.non_cellular); - - CancellationFlag flag; - ErrorOr> sender_socket_result = sender.Connect( - service_id, self_id, location_hint, &flag, params.non_cellular); - ASSERT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value()->IsValid()); - - ExceptionOr devices_connected = connected.Get(); - ASSERT_TRUE(devices_connected.ok()); - EXPECT_TRUE(devices_connected.result()); - - sender_socket_result.value()->GetOutputStream().Write(message); - ExceptionOr received_msg = - receiver_socket->GetInputStream().Read(/*size=*/32); - ASSERT_TRUE(received_msg.ok()); - EXPECT_EQ(message, received_msg.result().AsStringView()); - - receiver_socket->Close(); - env_.Stop(); -} - -TEST_P(WebRtcTest, Connect_NullPeerConnection) { - env_.Start({.webrtc_enabled = true}); - WebRtcTestParams params = GetParam(); - testing::StrictMock mock_accepted_callback_; - env_.SetUseValidPeerConnection( - /*use_valid_peer_connection=*/false); - - WebRtcImpl webrtc; - const std::string service_id("NearbySharing"); - WebrtcPeerId self_id("peer_id"); - LocationHint location_hint; - - ASSERT_TRUE(webrtc.IsAvailable()); - CancellationFlag flag; - ErrorOr> wrapper_result = - webrtc.Connect(service_id, WebrtcPeerId("random_peer_id"), location_hint, - &flag, params.non_cellular); - EXPECT_TRUE(wrapper_result.has_error()); - env_.Stop(); -} - -// Tests the flow when the device calls StartAcceptingConnections and the -// receive messages stream fails. -TEST_P(WebRtcTest, ContinueAcceptingConnectionsOnComplete) { - env_.Start({.webrtc_enabled = true}); - testing::StrictMock mock_accepted_callback_; - WebRtcTestParams params = GetParam(); - WebRtcImpl webrtc; - WebrtcPeerId self_id("peer_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - - ASSERT_TRUE(webrtc.IsAvailable()); - ASSERT_TRUE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - mock_accepted_callback_.AsStdFunction(), params.non_cellular)); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - - // Simulate a failure in receiving messages stream, WebRtc should restart - // accepting connections. - env_.SendWebRtcSignalingComplete(self_id.GetId(), - /*success=*/false); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - - // And a "success" message should not cause accepting connections to stop. - env_.SendWebRtcSignalingComplete(self_id.GetId(), - /*success=*/true); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - - webrtc.StopAcceptingConnections(service_id); - EXPECT_FALSE(webrtc.IsAcceptingConnections(service_id)); - env_.Stop(); -} - -// Tests when a CancellationFlag is cancelled during an attempt to -// `WebRtc::AttemptToConnect` triggered by `WebRtc::Connect`. -TEST_P(WebRtcTest, CancelDuringConnect) { - env_.Start({.webrtc_enabled = true}); - WebRtcTestParams params = GetParam(); - - // Enable cancellation flags. - env_.SetFeatureFlags(FeatureFlags{ - .enable_cancellation_flag = true, - }); - - std::shared_ptr receiver_socket, sender_socket; - const WebrtcPeerId self_id("self_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future connected; - - CancellationFlag receiver_flag; - std::unique_ptr receiver = std::make_unique( - std::make_unique(&receiver_flag)); - - CancellationFlag sender_flag; - std::unique_ptr sender_medium = - std::make_unique(&sender_flag); - FakeWebRtcMedium* fake_sender_medium = - static_cast(sender_medium.get()); - auto sender = std::make_unique(std::move(sender_medium)); - - // Calls `CancellationFlag::Cancel` during a call to `GetSignalingMessenger` - // to simulate the cancellation occuring during an `AttemptToConnect`. - fake_sender_medium->TriggerCancellationDuringGetSignalingMessenger(); - - receiver->StartAcceptingConnections( - service_id, self_id, location_hint, - [&receiver_socket, connected]( - const std::string& service_id, - std::shared_ptr wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket->IsValid()); - }, - params.non_cellular); - - ErrorOr> sender_socket_result = sender->Connect( - service_id, self_id, location_hint, &sender_flag, params.non_cellular); - - // Since the flag was cancelled during the initial `AttemptToConnect`, except - // only one attempt instead of the usual three, because the cancellation flag - // should short-circuit the lengthy connection attempts during shutdown. - // Because of the way the iteration happens, the check for is cancelled - // happens after the counter has already been incremented, but before the - // attempt actually occurs. - EXPECT_TRUE(sender_socket_result.has_error()); - EXPECT_EQ(2, sender->connect_attempts_count(service_id)); - - env_.Stop(); -} - -// Tests when a CancellationFlag is cancelled before `WebRtc::Connect` is -// called. -TEST_P(WebRtcTest, CancelBeforeConnect) { - env_.Start({.webrtc_enabled = true}); - WebRtcTestParams params = GetParam(); - - // Enable cancellation flags. - env_.SetFeatureFlags(FeatureFlags{ - .enable_cancellation_flag = true, - }); - - std::shared_ptr receiver_socket; - const WebrtcPeerId self_id("self_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future connected; - - CancellationFlag receiver_flag; - std::unique_ptr receiver = std::make_unique( - std::make_unique(&receiver_flag)); - - CancellationFlag sender_flag(true); - auto sender = std::make_unique( - std::make_unique(&sender_flag)); - - receiver->StartAcceptingConnections( - service_id, self_id, location_hint, - [&receiver_socket, connected]( - const std::string& service_id, - std::shared_ptr wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket->IsValid()); - }, - params.non_cellular); - - ErrorOr> sender_socket_result = sender->Connect( - service_id, self_id, location_hint, &sender_flag, params.non_cellular); - - // Expect an invalid socket from stopping during the first attempt to connect, - // because `Connect` returned immediatley when it checked for cancellation. - EXPECT_TRUE(sender_socket_result.has_error()); - EXPECT_EQ(1, sender->connect_attempts_count(service_id)); - - env_.Stop(); -} - -// Tests when a CancellationFlag is cancelled during an attempt to -// `WebRtc::AttemptToConnect` triggered by `WebRtc::Connect` when multiple -// `WebRTC::Connect` calls are in flight for multiple service ids. -TEST_P(WebRtcTest, CancelDuringConnect_MultipleConnect) { - env_.Start({.webrtc_enabled = true}); - WebRtcTestParams params = GetParam(); - - // Enable cancellation flags. - env_.SetFeatureFlags(FeatureFlags{ - .enable_cancellation_flag = true, - }); - - std::shared_ptr receiver_socket; - const WebrtcPeerId self_id("self_id"); - const std::string ns_service_id("NearbySharing"); - const std::string ph_service_id("PhoneHub"); - LocationHint location_hint; - Future connected; - - CancellationFlag receiver_flag; - std::unique_ptr receiver = std::make_unique( - std::make_unique(&receiver_flag)); - - CancellationFlag flag; - auto sender_medium = std::make_unique(&flag); - FakeWebRtcMedium* fake_sender_medium = sender_medium.get(); - auto sender = std::make_unique(std::move(sender_medium)); - - receiver->StartAcceptingConnections( - ns_service_id, self_id, location_hint, - [&receiver_socket, connected]( - const std::string& ns_service_id, - std::shared_ptr wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket->IsValid()); - }, - params.non_cellular); - - // Simulate a successful connect for the endpoint of NearbySharing. - ErrorOr> sender_socket_result = sender->Connect( - ns_service_id, self_id, location_hint, &flag, params.non_cellular); - ASSERT_TRUE(sender_socket_result.has_value()); - EXPECT_TRUE(sender_socket_result.value()->IsValid()); - - // Calls `CancellationFlag::Cancel` during a call to `GetSignalingMessenger` - // to simulate the cancellation occuring during an `AttemptToConnect` for the - // endpoint of Phone Hub. - fake_sender_medium->TriggerCancellationDuringGetSignalingMessenger(); - sender_socket_result = sender->Connect(ph_service_id, self_id, location_hint, - &flag, params.non_cellular); - EXPECT_TRUE(sender_socket_result.has_error()); - - // Since the flag was cancelled during the initial `AttemptToConnect`, except - // only one attempt instead of the usual three, because the cancellation flag - // should short-circuit the lengthy connection attempts during shutdown. - // Because of the way the iteration happens, the check for is cancelled - // happens after the counter has already been incremented, but before the - // attempt actually occurs. For the successful connect, expect only one - // attempt. - EXPECT_EQ(1, sender->connect_attempts_count(ns_service_id)); - EXPECT_EQ(2, sender->connect_attempts_count(ph_service_id)); - - env_.Stop(); -} - -INSTANTIATE_TEST_SUITE_P(ParametrisedWebRtcTest, WebRtcTest, - testing::ValuesIn({ - {.feature_flags = - FeatureFlags{ - .enable_cancellation_flag = true, - }, - .non_cellular = true}, - {.feature_flags = - FeatureFlags{ - .enable_cancellation_flag = true, - }, - .non_cellular = false}, - {.feature_flags = - FeatureFlags{ - .enable_cancellation_flag = false, - }, - .non_cellular = true}, - {.feature_flags = - FeatureFlags{ - .enable_cancellation_flag = false, - }, - .non_cellular = false}, - })); - -} // namespace - -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/webrtc/webrtc_medium_impl.cc b/connections/implementation/mediums/webrtc/webrtc_medium_impl.cc deleted file mode 100644 index 8c5a2237..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_medium_impl.cc +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2023 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. - -#include "connections/implementation/mediums/webrtc/webrtc_medium_impl.h" - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "connections/implementation/mediums/webrtc/tachyon_express_signaling_messenger.h" -#include "internal/platform/implementation/webrtc.h" -#include "webrtc/api/create_modular_peer_connection_factory.h" -#include "webrtc/api/peer_connection_interface.h" -#include "webrtc/api/rtc_error.h" -#include "webrtc/api/scoped_refptr.h" -#include "webrtc/rtc_base/thread.h" - -namespace nearby::connections::mediums { - -void WebRtcMediumImpl::CreatePeerConnection( - webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) { - CreatePeerConnection(std::nullopt, observer, std::move(callback)); -} - -void WebRtcMediumImpl::CreatePeerConnection( - std::optional options, - webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) { - webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; - rtc_config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; - // TODO: b/261663238 - Add the TURN servers and go beyond the default servers. - webrtc::PeerConnectionInterface::IceServer ice_server; - ice_server.urls.emplace_back("stun:stun.l.google.com:19302"); - ice_server.urls.emplace_back("stun:stun1.l.google.com:19302"); - ice_server.urls.emplace_back("stun:stun2.l.google.com:19302"); - ice_server.urls.emplace_back("stun:stun3.l.google.com:19302"); - ice_server.urls.emplace_back("stun:stun4.l.google.com:19302"); - rtc_config.servers.push_back(ice_server); - - std::unique_ptr signaling_thread = webrtc::Thread::Create(); - signaling_thread->SetName("signaling_thread", nullptr); - if (!signaling_thread->Start()) { - callback(/*peer_connection=*/nullptr); - return; - } - - webrtc::PeerConnectionDependencies dependencies(observer); - webrtc::PeerConnectionFactoryDependencies factory_dependencies; - factory_dependencies.signaling_thread = signaling_thread.release(); - - webrtc::scoped_refptr - peer_connection_factory = webrtc::CreateModularPeerConnectionFactory( - std::move(factory_dependencies)); - if (options.has_value()) { - peer_connection_factory->SetOptions(options.value()); - } - webrtc::RTCErrorOr> - peer_connection_or_error = - peer_connection_factory->CreatePeerConnectionOrError( - rtc_config, std::move(dependencies)); - if (peer_connection_or_error.ok()) { - callback(peer_connection_or_error.MoveValue()); - } else { - callback(/*peer_connection=*/nullptr); - } -} - -std::unique_ptr -WebRtcMediumImpl::GetSignalingMessenger( - absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint) { - return std::make_unique(self_id, - location_hint); -} - -} // namespace nearby::connections::mediums diff --git a/connections/implementation/mediums/webrtc/webrtc_medium_impl.h b/connections/implementation/mediums/webrtc/webrtc_medium_impl.h deleted file mode 100644 index 7eb5ff1b..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_medium_impl.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_MEDIUM_IMPL_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_MEDIUM_IMPL_H_ - -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/webrtc.h" -#include "webrtc/api/peer_connection_interface.h" - -namespace nearby::connections::mediums { - -class WebRtcMediumImpl : public api::WebRtcMedium { - public: - ~WebRtcMediumImpl() override = default; - - // Creates and returns a new webrtc::PeerConnectionInterface object via - // |callback|. - void CreatePeerConnection(webrtc::PeerConnectionObserver* observer, - PeerConnectionCallback callback) override; - - // Creates and returns a new webrtc::PeerConnectionInterface object via - // |callback| with |PeerConnectionFactoryInterface::Options|. - void CreatePeerConnection( - std::optional options, - webrtc::PeerConnectionObserver* observer, - PeerConnectionCallback callback) override; - - // Returns a signaling messenger for sending WebRTC signaling messages. - std::unique_ptr GetSignalingMessenger( - absl::string_view self_id, - const location::nearby::connections::LocationHint& location_hint) - override; -}; - -} // namespace nearby::connections::mediums - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_MEDIUM_IMPL_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_medium_impl_test.cc b/connections/implementation/mediums/webrtc/webrtc_medium_impl_test.cc deleted file mode 100644 index c52cee0a..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_medium_impl_test.cc +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2023 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. - -#include "connections/implementation/mediums/webrtc/webrtc_medium_impl.h" - -#include -#include -#include - -#include "gtest/gtest.h" -#include "internal/platform/implementation/webrtc.h" -#include "webrtc/api/data_channel_interface.h" -#include "webrtc/api/jsep.h" -#include "webrtc/api/peer_connection_interface.h" -#include "webrtc/api/scoped_refptr.h" - -namespace nearby::connections::mediums { - -class MockPeerConnectionObserver : public webrtc::PeerConnectionObserver { - public: - void OnSignalingChange( - webrtc::PeerConnectionInterface::SignalingState new_state) override {} - - void OnDataChannel(webrtc::scoped_refptr - data_channel) override {} - - void OnIceGatheringChange( - webrtc::PeerConnectionInterface::IceGatheringState new_state) override {} - - void OnIceCandidate(const webrtc::IceCandidate* candidate) override {} -}; - -location::nearby::connections::LocationHint GetCountryCodeLocationHint( - const std::string& country_code) { - auto location_hint = location::nearby::connections::LocationHint(); - location_hint.set_location(country_code); - location_hint.set_format( - location::nearby::connections::LocationStandard::ISO_3166_1_ALPHA_2); - return location_hint; -} - -TEST(WebrtcMediumImplTest, CreatePeerConnectionSucceeds) { - auto observer = std::make_unique(); - WebRtcMediumImpl medium; - medium.CreatePeerConnection( - std::nullopt, observer.get(), - [](webrtc::scoped_refptr - peer_connection) mutable { - if (!peer_connection) { - FAIL() << "Peer connection should have been non-null"; - return; - } - }); -} - -TEST(WebrtcMediumImplTest, GetSignalingMessengerSucceeds) { - WebRtcMediumImpl medium; - std::unique_ptr messenger = - medium.GetSignalingMessenger("US", GetCountryCodeLocationHint("US")); - EXPECT_TRUE(messenger); -} - -} // namespace nearby::connections::mediums diff --git a/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc b/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc deleted file mode 100644 index ff8a3a03..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_socket_impl.cc +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2020 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. - -#include "connections/implementation/mediums/webrtc/webrtc_socket_impl.h" - -#include -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/exception.h" -#include "internal/platform/input_stream.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex_lock.h" -#include "internal/platform/output_stream.h" -#include "internal/platform/pipe.h" -#include "internal/platform/runnable.h" -#include "webrtc/api/data_channel_interface.h" -#include "webrtc/api/scoped_refptr.h" - -namespace nearby { -namespace connections { -namespace mediums { - -// OutputStreamImpl -Exception WebRtcSocketImpl::OutputStreamImpl::Write(absl::string_view data) { - if (data.size() > kMaxDataSize) { - LOG(WARNING) << "Sending data larger than 1MB"; - return {Exception::kIo}; - } - - socket_->BlockUntilSufficientSpaceInBuffer(data.size()); - - if (socket_->IsClosed()) { - LOG(WARNING) << "Tried sending message while socket is closed"; - return {Exception::kIo}; - } - - if (!socket_->SendMessage(ByteArray::FromStringView(data))) { - LOG(INFO) << "Unable to write data to socket."; - return {Exception::kIo}; - } - return {Exception::kSuccess}; -} - -Exception WebRtcSocketImpl::OutputStreamImpl::Flush() { - // Java implementation is empty. - return {Exception::kSuccess}; -} - -Exception WebRtcSocketImpl::OutputStreamImpl::Close() { - socket_->Close(); - return {Exception::kSuccess}; -} - -// WebRtcSocket -WebRtcSocketImpl::WebRtcSocketImpl( - const std::string& name, - webrtc::scoped_refptr data_channel) - : name_(name), data_channel_(std::move(data_channel)) { - LOG(INFO) << "WebRtcSocket::WebRtcSocket(" << name_ << ") this: " << this; - std::tie(pipe_input_, pipe_output_) = CreatePipe(); - data_channel_->RegisterObserver(this); -} - -WebRtcSocketImpl::~WebRtcSocketImpl() { - LOG(INFO) << "WebRtcSocket::~WebRtcSocket(" << name_ << ") this: " << this; - - if (!IsClosed()) { - data_channel_->UnregisterObserver(); - Close(); - } - - LOG(INFO) << "WebRtcSocket::~WebRtcSocket(" << name_ << ") this: " << this - << " done"; -} - -InputStream& WebRtcSocketImpl::GetInputStream() { return *pipe_input_; } - -OutputStream& WebRtcSocketImpl::GetOutputStream() { return output_stream_; } - -Exception WebRtcSocketImpl::Close() { - LOG(INFO) << "WebRtcSocket::Close(" << name_ << ") this: " << this; - if (closed_.Set(true)) return {Exception::kSuccess}; - - ClosePipe(); - // NOTE: This call blocks and triggers a state change on the signaling thread - // to 'closing' but does not block until 'closed' is sent so the data channel - // is not fully closed when this call is done. - data_channel_->Close(); - LOG(INFO) << "WebRtcSocket::Close(" << name_ << ") this: " << this << " done"; - return {Exception::kSuccess}; -} - -void WebRtcSocketImpl::OnStateChange() { - // Running on the signaling thread right now. - LOG(ERROR) << "WebRtcSocket::OnStateChange() webrtc data channel state: " - << webrtc::DataChannelInterface::DataStateString( - data_channel_->state()); - switch (data_channel_->state()) { - case webrtc::DataChannelInterface::DataState::kConnecting: - break; - case webrtc::DataChannelInterface::DataState::kOpen: - // We implicitly depend on the |socket_listener_| to offload from - // the signaling thread so it does not get blocked. - socket_listener_.socket_ready_cb(this); - break; - case webrtc::DataChannelInterface::DataState::kClosing: - break; - case webrtc::DataChannelInterface::DataState::kClosed: - LOG(ERROR) << "WebRtcSocket::OnStateChange() unregistering data " - "channel observer."; - // This will trigger a destruction of the owning connection flow - // We implicitly depend on the |socket_listener_| to offload from - // the signaling thread so it does not get blocked. - socket_listener_.socket_closed_cb(this); - - if (!closed_.Set(true)) { - OffloadFromSignalingThread([this] { ClosePipe(); }); - } - break; - } -} -void WebRtcSocketImpl::OnMessage(const webrtc::DataBuffer& buffer) { - // This is a data channel callback on the signaling thread, lets off load so - // we don't block signaling. - OffloadFromSignalingThread( - [this, buffer = ByteArray(buffer.data.data(), buffer.size())] { - if (!pipe_output_->Write(buffer.AsStringView()).Ok()) { - Close(); - return; - } - - if (!pipe_output_->Flush().Ok()) { - Close(); - } - }); -} - -void WebRtcSocketImpl::OnBufferedAmountChange(uint64_t sent_data_size) { - // This is a data channel callback on the signaling thread, lets off load so - // we don't block signaling. - OffloadFromSignalingThread([this] { WakeUpWriter(); }); -} - -bool WebRtcSocketImpl::SendMessage(const ByteArray& data) { - return data_channel_->Send( - webrtc::DataBuffer(std::string(data.data(), data.size()))); -} - -bool WebRtcSocketImpl::IsClosed() { return closed_.Get(); } - -void WebRtcSocketImpl::ClosePipe() { - LOG(INFO) << "WebRtcSocket::ClosePipe(" << name_ << ") this: " << this; - // This is thread-safe to close these sockets even if a read or write is in - // process on another thread, Close will wait for the exclusive mutex before - // setting state. - pipe_input_->Close(); - pipe_output_->Close(); - WakeUpWriter(); - LOG(INFO) << "WebRtcSocket::ClosePipe(" << name_ << ") this: " << this - << " done"; -} - -// Must not be called on signalling thread. -void WebRtcSocketImpl::WakeUpWriter() { - MutexLock lock(&backpressure_mutex_); - buffer_variable_.Notify(); -} - -void WebRtcSocketImpl::SetSocketListener(SocketListener&& listener) { - socket_listener_ = std::move(listener); -} - -void WebRtcSocketImpl::BlockUntilSufficientSpaceInBuffer(int length) { - MutexLock lock(&backpressure_mutex_); - while (!IsClosed() && - (data_channel_->buffered_amount() + length > kMaxDataSize)) { - // TODO(himanshujaju): Add wait with timeout. - buffer_variable_.Wait(); - } -} - -void WebRtcSocketImpl::OffloadFromSignalingThread(Runnable runnable) { - single_thread_executor_.Execute(std::move(runnable)); -} - -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/connections/implementation/mediums/webrtc/webrtc_socket_impl.h b/connections/implementation/mediums/webrtc/webrtc_socket_impl.h deleted file mode 100644 index b3605462..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_socket_impl.h +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2020 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 CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_IMPL_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_IMPL_H_ - -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "connections/implementation/mediums/webrtc_socket.h" -#include "internal/platform/atomic_boolean.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/condition_variable.h" -#include "internal/platform/exception.h" -#include "internal/platform/input_stream.h" -#include "internal/platform/listeners.h" -#include "internal/platform/mutex.h" -#include "internal/platform/output_stream.h" -#include "internal/platform/runnable.h" -#include "internal/platform/single_thread_executor.h" -#include "webrtc/api/data_channel_interface.h" -#include "webrtc/api/scoped_refptr.h" - -namespace nearby { -namespace connections { -namespace mediums { - -// Maximum data size: 1 MB -constexpr int kMaxDataSize = 1 * 1024 * 1024; - -// Defines the Socket implementation specific to WebRTC, which uses the WebRTC -// data channel to send and receive messages. -// -// Messages are buffered here to prevent the data channel from overflowing, -// which could lead to data loss. -class WebRtcSocketImpl : public WebRtcSocket, - public webrtc::DataChannelObserver { - public: - WebRtcSocketImpl( - const std::string& name, - webrtc::scoped_refptr data_channel); - ~WebRtcSocketImpl() override; - - WebRtcSocketImpl(const WebRtcSocketImpl& other) = delete; - WebRtcSocketImpl& operator=(const WebRtcSocketImpl& other) = delete; - - // Overrides for WebRtcSocket: - InputStream& GetInputStream() override; - OutputStream& GetOutputStream() override; - Exception Close() override; - bool IsValid() const override { return true; } - - // webrtc::DataChannelObserver: - void OnStateChange() override; - void OnMessage(const webrtc::DataBuffer& buffer) override; - void OnBufferedAmountChange(uint64_t sent_data_size) override; - - // Listener class the gets called when the socket is ready or closed - struct SocketListener { - absl::AnyInvocable socket_ready_cb = - DefaultCallback(); - absl::AnyInvocable socket_closed_cb = - DefaultCallback(); - }; - - void SetSocketListener(SocketListener&& listener); - - private: - class OutputStreamImpl : public OutputStream { - public: - explicit OutputStreamImpl(WebRtcSocketImpl* const socket) - : socket_(socket) {} - ~OutputStreamImpl() override = default; - - OutputStreamImpl(const OutputStreamImpl& other) = delete; - OutputStreamImpl& operator=(const OutputStreamImpl& other) = delete; - - // OutputStream: - Exception Write(absl::string_view data) override; - Exception Flush() override; - Exception Close() override; - - private: - // |this| OutputStreamImpl is owned by |socket_|. - WebRtcSocketImpl* const socket_; - }; - - void WakeUpWriter(); - bool IsClosed(); - void ClosePipe(); - bool SendMessage(const ByteArray& data); - void BlockUntilSufficientSpaceInBuffer(int length); - void OffloadFromSignalingThread(Runnable runnable); - - std::string name_; - webrtc::scoped_refptr data_channel_; - - std::unique_ptr pipe_input_; - std::unique_ptr pipe_output_; - OutputStreamImpl output_stream_{this}; - - AtomicBoolean closed_{false}; - - SocketListener socket_listener_; - - mutable Mutex backpressure_mutex_; - ConditionVariable buffer_variable_{&backpressure_mutex_}; - - // This should be destroyed first to ensure any remaining tasks flushed on - // shutdown get run while the other members are still alive. - SingleThreadExecutor single_thread_executor_; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_IMPL_H_ diff --git a/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc b/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc deleted file mode 100644 index fdffc732..00000000 --- a/connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright 2020 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. - -#include "connections/implementation/mediums/webrtc/webrtc_socket_impl.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/exception.h" -#include "webrtc/api/data_channel_interface.h" -#include "webrtc/api/scoped_refptr.h" -#include "webrtc/rtc_base/ref_counted_object.h" - -namespace nearby { -namespace connections { -namespace mediums { - -namespace { - -// using TestPlatform = platform::ImplementationPlatform; - -const char kSocketName[] = "TestSocket"; - -class MockDataChannel - : public webrtc::RefCountedObject { - public: - MOCK_METHOD(void, RegisterObserver, (webrtc::DataChannelObserver*)); - MOCK_METHOD(void, UnregisterObserver, ()); - - MOCK_METHOD(std::string, label, (), (const)); - - MOCK_METHOD(bool, reliable, (), (const)); - MOCK_METHOD(int, id, (), (const)); - MOCK_METHOD(DataState, state, (), (const)); - MOCK_METHOD(uint32_t, messages_sent, (), (const)); - MOCK_METHOD(uint64_t, bytes_sent, (), (const)); - MOCK_METHOD(uint32_t, messages_received, (), (const)); - MOCK_METHOD(uint64_t, bytes_received, (), (const)); - - MOCK_METHOD(uint64_t, buffered_amount, (), (const)); - - MOCK_METHOD(void, Close, ()); - - MOCK_METHOD(bool, Send, (const webrtc::DataBuffer&)); -}; - -} // namespace - -TEST(WebRtcSocketTest, ReadFromSocket) { - const char* message = "message"; - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - - webrtc_socket.OnMessage(webrtc::DataBuffer{message}); - ExceptionOr result = webrtc_socket.GetInputStream().Read(7); - EXPECT_TRUE(result.ok()); - EXPECT_EQ(result.result(), ByteArray{message}); -} - -TEST(WebRtcSocketTest, ReadMultipleMessages) { - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - - webrtc_socket.OnMessage(webrtc::DataBuffer{"Me"}); - webrtc_socket.OnMessage(webrtc::DataBuffer{"ssa"}); - webrtc_socket.OnMessage(webrtc::DataBuffer{"ge"}); - - ExceptionOr result; - - // This behaviour is different from the Java code - result = webrtc_socket.GetInputStream().Read(7); - EXPECT_TRUE(result.ok()); - EXPECT_EQ(result.result(), ByteArray{"Me"}); - - result = webrtc_socket.GetInputStream().Read(7); - EXPECT_TRUE(result.ok()); - EXPECT_EQ(result.result(), ByteArray{"ssa"}); - - result = webrtc_socket.GetInputStream().Read(7); - EXPECT_TRUE(result.ok()); - EXPECT_EQ(result.result(), ByteArray{"ge"}); -} - -TEST(WebRtcSocketTest, WriteToSocket) { - absl::string_view kMessage{"Message"}; - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - - EXPECT_CALL(*mock_data_channel, Send(testing::_)) - .WillRepeatedly(testing::Return(true)); - EXPECT_TRUE(webrtc_socket.GetOutputStream().Write(kMessage).Ok()); -} - -TEST(WebRtcSocketTest, SendDataBiggerThanMax) { - std::string kMessage(kMaxDataSize + 1, '0'); - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - - EXPECT_CALL(*mock_data_channel, Send(testing::_)).Times(0); - EXPECT_EQ(webrtc_socket.GetOutputStream().Write(kMessage), - Exception{Exception::kIo}); -} - -TEST(WebRtcSocketTest, WriteToDataChannelFails) { - absl::string_view kMessage{"Message"}; - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - - ON_CALL(*mock_data_channel, Send(testing::_)) - .WillByDefault(testing::Return(false)); - EXPECT_EQ(webrtc_socket.GetOutputStream().Write(kMessage), - Exception{Exception::kIo}); -} - -TEST(WebRtcSocketTest, Close) { - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - - EXPECT_CALL(*mock_data_channel, Close()); - - int socket_closed_cb_called = 0; - - webrtc_socket.SetSocketListener( - {.socket_closed_cb = [&](WebRtcSocketImpl* socket) { - socket_closed_cb_called++; - }}); - webrtc_socket.Close(); - - // We have to fake the close event to get the callback to run. - ON_CALL(*mock_data_channel, state()) - .WillByDefault( - testing::Return(webrtc::DataChannelInterface::DataState::kClosed)); - - webrtc_socket.OnStateChange(); - - EXPECT_EQ(socket_closed_cb_called, 1); -} - -TEST(WebRtcSocketTest, WriteOnClosedChannel) { - absl::string_view kMessage{"Message"}; - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - webrtc_socket.Close(); - - EXPECT_CALL(*mock_data_channel, Send(testing::_)).Times(0); - EXPECT_EQ(webrtc_socket.GetOutputStream().Write(kMessage), - Exception{Exception::kIo}); -} - -TEST(WebRtcSocketTest, ReadFromClosedChannel) { - absl::string_view kMessage{"Message"}; - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - ON_CALL(*mock_data_channel, Send(testing::_)) - .WillByDefault(testing::Return(true)); - - webrtc_socket.GetOutputStream().Write(kMessage); - webrtc_socket.Close(); - - EXPECT_TRUE(webrtc_socket.GetInputStream().Read(7).GetResult().Empty()); -} - -TEST(WebRtcSocketTest, DataChannelCloseEventCleansUp) { - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - - ON_CALL(*mock_data_channel, state()) - .WillByDefault( - testing::Return(webrtc::DataChannelInterface::DataState::kClosed)); - - webrtc_socket.OnStateChange(); - - EXPECT_TRUE(webrtc_socket.GetInputStream().Read(7).GetResult().Empty()); - - // Calling Close again should be safe even if the channel is already shut - // down. - webrtc_socket.Close(); -} - -TEST(WebRtcSocketTest, OpenStateTriggersCallback) { - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - - int socket_ready_cb_called = 0; - - webrtc_socket.SetSocketListener( - {.socket_ready_cb = [&](WebRtcSocketImpl* socket) { - socket_ready_cb_called++; - }}); - - ON_CALL(*mock_data_channel, state()) - .WillByDefault( - testing::Return(webrtc::DataChannelInterface::DataState::kOpen)); - - webrtc_socket.OnStateChange(); - - EXPECT_EQ(socket_ready_cb_called, 1); -} - -TEST(WebRtcSocketTest, CloseStateTriggersCallback) { - webrtc::scoped_refptr mock_data_channel( - new MockDataChannel()); - WebRtcSocketImpl webrtc_socket(kSocketName, mock_data_channel); - - int socket_closed_cb_called = 0; - - webrtc_socket.SetSocketListener( - {.socket_closed_cb = [&](WebRtcSocketImpl* socket) { - socket_closed_cb_called++; - }}); - - ON_CALL(*mock_data_channel, state()) - .WillByDefault( - testing::Return(webrtc::DataChannelInterface::DataState::kClosed)); - - webrtc_socket.OnStateChange(); - - EXPECT_EQ(socket_closed_cb_called, 1); -} - -} // namespace mediums -} // namespace connections -} // namespace nearby diff --git a/internal/platform/implementation/g3/webrtc.cc b/internal/platform/implementation/g3/webrtc.cc index 9659c50d..da43fa31 100644 --- a/internal/platform/implementation/g3/webrtc.cc +++ b/internal/platform/implementation/g3/webrtc.cc @@ -24,11 +24,11 @@ #include "internal/platform/byte_array.h" #include "internal/platform/implementation/webrtc.h" #include "internal/platform/medium_environment.h" -#include "webrtc/api/create_modular_peer_connection_factory.h" -#include "webrtc/api/peer_connection_interface.h" -#include "webrtc/api/scoped_refptr.h" -#include "webrtc/rtc_base/checks.h" -#include "webrtc/rtc_base/thread.h" +#include "third_party/webrtc/files/stable/webrtc/api/create_modular_peer_connection_factory.h" +#include "third_party/webrtc/files/stable/webrtc/api/peer_connection_interface.h" +#include "third_party/webrtc/files/stable/webrtc/api/scoped_refptr.h" +#include "third_party/webrtc/files/stable/webrtc/rtc_base/checks.h" +#include "third_party/webrtc/files/stable/webrtc/rtc_base/thread.h" namespace nearby { namespace g3 { diff --git a/internal/platform/implementation/g3/webrtc.h b/internal/platform/implementation/g3/webrtc.h index 435fa57e..943e27f6 100644 --- a/internal/platform/implementation/g3/webrtc.h +++ b/internal/platform/implementation/g3/webrtc.h @@ -23,7 +23,7 @@ #include "internal/platform/byte_array.h" #include "internal/platform/implementation/webrtc.h" #include "internal/platform/implementation/g3/single_thread_executor.h" -#include "webrtc/api/peer_connection_interface.h" +#include "third_party/webrtc/files/stable/webrtc/api/peer_connection_interface.h" namespace nearby { namespace g3 { diff --git a/internal/platform/implementation/webrtc.h b/internal/platform/implementation/webrtc.h index 5b64dd50..90938bfa 100644 --- a/internal/platform/implementation/webrtc.h +++ b/internal/platform/implementation/webrtc.h @@ -22,8 +22,8 @@ #include "absl/strings/string_view.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "internal/platform/byte_array.h" -#include "webrtc/api/peer_connection_interface.h" -#include "webrtc/api/scoped_refptr.h" +#include "third_party/webrtc/files/stable/webrtc/api/peer_connection_interface.h" +#include "third_party/webrtc/files/stable/webrtc/api/scoped_refptr.h" namespace nearby { namespace api { From 00c8ae557a85509741a2af7abb0608daf0a76ee7 Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 3 Jun 2026 11:27:40 -0700 Subject: [PATCH 136/151] Remove usages of libjingle_peerconnection_api. PiperOrigin-RevId: 926159807 --- internal/platform/implementation/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 94a03367..b509f980 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -100,7 +100,7 @@ cc_library( deps = [ "//connections/implementation/proto:offline_wire_formats_cc_proto", "//internal/platform:base", - "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface", "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/strings:string_view", From 0e578f71d44e6b0fe03e7b5a3494b8cf73ea9c9d Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 3 Jun 2026 13:28:30 -0700 Subject: [PATCH 137/151] [Nearby Connections]: Avoid modifying gatt_advertisement_infos_ while iterating. PiperOrigin-RevId: 926231653 --- .../ble/discovered_peripheral_tracker.cc | 7 +- .../ble/discovered_peripheral_tracker_test.cc | 88 +++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/connections/implementation/mediums/ble/discovered_peripheral_tracker.cc b/connections/implementation/mediums/ble/discovered_peripheral_tracker.cc index 6639dd4a..51e2dd53 100644 --- a/connections/implementation/mediums/ble/discovered_peripheral_tracker.cc +++ b/connections/implementation/mediums/ble/discovered_peripheral_tracker.cc @@ -228,6 +228,7 @@ bool DiscoveredPeripheralTracker::HandleOnLostAdvertisementLocked( return false; } + std::vector advertisements_to_clear; for (const auto& hash : on_lost_advertisement->hashes()) { for (const auto& it : gatt_advertisement_infos_) { if (it.second.instant_on_lost_hash.string_data() == hash) { @@ -256,12 +257,16 @@ bool DiscoveredPeripheralTracker::HandleOnLostAdvertisementLocked( << it.second.service_id; } - ClearGattAdvertisement(gatt_advertisement); + advertisements_to_clear.push_back(gatt_advertisement); } break; } } } + + for (const auto& advertisement : advertisements_to_clear) { + ClearGattAdvertisement(advertisement); + } return true; } diff --git a/connections/implementation/mediums/ble/discovered_peripheral_tracker_test.cc b/connections/implementation/mediums/ble/discovered_peripheral_tracker_test.cc index c34120ae..52fb547f 100644 --- a/connections/implementation/mediums/ble/discovered_peripheral_tracker_test.cc +++ b/connections/implementation/mediums/ble/discovered_peripheral_tracker_test.cc @@ -223,6 +223,42 @@ class DiscoveredPeripheralTrackerTest adapter_peripheral_->GetAddress().address()); } + void SetupMultipleAdvertisementsState( + const BleAdvertisementHeader& header, + const BleAdvertisement& advertisement_1, + const BleAdvertisement& advertisement_2) { + MutexLock lock(&discovered_peripheral_tracker_->mutex_); + ByteArray advertisement_bytes_1 = advertisement_1.ByteArrayWithExtraField(); + ByteArray advertisement_bytes_2 = advertisement_2.ByteArrayWithExtraField(); + std::vector gatt_advertisement_bytes_list = { + &advertisement_bytes_1, &advertisement_bytes_2}; + + discovered_peripheral_tracker_->HandleRawGattAdvertisements( + CreateBlePeripheral(), header, gatt_advertisement_bytes_list, + /*service_uuid=*/{}); + } + + void RegisterServiceIdCallback(const std::string& service_id, + CountDownLatch& lost_latch) { + discovered_peripheral_tracker_->StartTracking( + service_id, /*include_dct_advertisement=*/false, Pcp::kP2pPointToPoint, + { + .instant_lost_cb = + [&lost_latch]( + BlePeripheral peripheral, const std::string& service_id, + const ByteArray& advertisement_bytes, + bool fast_advertisement) { lost_latch.CountDown(); }, + }, + /*fast_advertisement_service_uuid=*/{}); + } + + bool CallHandleOnLostAdvertisementLocked( + const api::ble::BleAdvertisementData& advertisement_data) { + MutexLock lock(&discovered_peripheral_tracker_->mutex_); + return discovered_peripheral_tracker_->HandleOnLostAdvertisementLocked( + advertisement_data); + } + // Simulates to see a fast advertisement. void FindFastAdvertisement( const api::ble::BleAdvertisementData& advertisement_data, @@ -1267,6 +1303,58 @@ TEST_P(DiscoveredPeripheralTrackerTest, InstantLostPeripheralForInstantOnLost) { EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); } +TEST_P(DiscoveredPeripheralTrackerTest, + InstantLostPeripheralForInstantOnLost_MultipleAdvertisements) { + ByteArray advertisement_hash = GenerateRandomAdvertisementHash(); + BleAdvertisementHeader header(BleAdvertisementHeader::Version::kV2, + /*extended_advertisement=*/false, + /*num_slots=*/1, ByteArray{}, // bloom filter + advertisement_hash, + BleAdvertisementHeader::kDefaultPsmValue); + + ByteArray advertisement_bytes_1 = CreateBleAdvertisement( + std::string(kServiceIdA), ByteArray(std::string(kData)), + ByteArray(std::string(kDeviceToken))); + ByteArray advertisement_bytes_2 = CreateBleAdvertisement( + std::string(kServiceIdB), ByteArray(std::string(kData2)), + ByteArray(std::string(kDeviceToken))); + + auto adv_status_or_1 = + BleAdvertisement::CreateBleAdvertisement(advertisement_bytes_1); + ASSERT_OK(adv_status_or_1); + BleAdvertisement advertisement_1 = adv_status_or_1.value(); + + auto adv_status_or_2 = + BleAdvertisement::CreateBleAdvertisement(advertisement_bytes_2); + ASSERT_OK(adv_status_or_2); + BleAdvertisement advertisement_2 = adv_status_or_2.value(); + + // Register callbacks for both Service A and Service B. + CountDownLatch lost_latch(2); + RegisterServiceIdCallback(std::string(kServiceIdA), lost_latch); + RegisterServiceIdCallback(std::string(kServiceIdB), lost_latch); + + // Use helper method to set up state manually. + SetupMultipleAdvertisementsState(header, advertisement_1, advertisement_2); + + // Create OnLost advertisement for advertisement_1's hash. + auto advertisement = InstantOnLostAdvertisement::CreateFromHashes( + std::list({std::string(bleutils::GenerateAdvertisementHash( + advertisement_1.ByteArrayWithExtraField()))})); + ASSERT_OK(advertisement); + + api::ble::BleAdvertisementData loss_advertisement_data{}; + loss_advertisement_data.service_data.insert( + {bleutils::kCopresenceServiceUuid, ByteArray(advertisement->ToBytes())}); + + // Call HandleOnLostAdvertisementLocked using helper. + bool result = CallHandleOnLostAdvertisementLocked(loss_advertisement_data); + EXPECT_TRUE(result); + + // Verify that both are lost (callback triggered twice). + EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); +} + TEST_P(DiscoveredPeripheralTrackerTest, IgnoreFoundAdvertisementForInstantOnLost) { std::vector service_ids = {std::string(kServiceIdA)}; From f7041e16eca156f60ebc9ce38b931fc166c6e411 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 3 Jun 2026 15:55:31 -0700 Subject: [PATCH 138/151] internal PiperOrigin-RevId: 926321187 --- sharing/proto/wire_format.proto | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sharing/proto/wire_format.proto b/sharing/proto/wire_format.proto index b0db8294..01f5a4d1 100644 --- a/sharing/proto/wire_format.proto +++ b/sharing/proto/wire_format.proto @@ -213,13 +213,14 @@ message V1Frame { // An introduction packet sent by the sending side. Contains a list of files // they'd like to share. -// NEXT_ID=10 +// NEXT_ID=11 message IntroductionFrame { enum SharingUseCase { UNKNOWN = 0; NEARBY_SHARE = 1; REMOTE_COPY = 2; TAP_TO_SHARE = 9; + FILE_SYNC = 10; } repeated FileMetadata file_metadata = 1; From 9605d33327011a30d3248204a5bb7d1a18b3d34f Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 3 Jun 2026 21:23:21 -0700 Subject: [PATCH 139/151] the changes in sharing_enums is for internal clearcut logging. PiperOrigin-RevId: 926443589 --- proto/sharing_enums.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index d2f0b0bc..e6b055bc 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -362,6 +362,7 @@ enum Visibility { SELECTED_CONTACTS_ONLY = 3 [deprecated = true]; HIDDEN = 4; SELF_SHARE = 5; + FAMILY = 6; } enum DataUsage { From 2a3b9cd809c8ba6c7d09a2066d161fac68e9c373 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 4 Jun 2026 13:58:43 -0700 Subject: [PATCH 140/151] Fix build failures. PiperOrigin-RevId: 926873356 --- .../platform/implementation/windows/bluetooth_adapter.cc | 5 +++++ internal/platform/implementation/windows/utils.cc | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/internal/platform/implementation/windows/bluetooth_adapter.cc b/internal/platform/implementation/windows/bluetooth_adapter.cc index 9bef1fae..fb0a8396 100644 --- a/internal/platform/implementation/windows/bluetooth_adapter.cc +++ b/internal/platform/implementation/windows/bluetooth_adapter.cc @@ -32,6 +32,11 @@ #include #include +// Remove LogSeverity macro defined in setupapi.h +#if defined(LogSeverity) +#undef LogSeverity +#endif + #include #include #include diff --git a/internal/platform/implementation/windows/utils.cc b/internal/platform/implementation/windows/utils.cc index ff166f7d..cfabecb3 100644 --- a/internal/platform/implementation/windows/utils.cc +++ b/internal/platform/implementation/windows/utils.cc @@ -20,6 +20,11 @@ #include // clang-format on +// Remove LogSeverity macro defined in setupapi.h +#if defined(LogSeverity) +#undef LogSeverity +#endif + // Standard C/C++ headers #include #include From d6933211d96ec291c2145e58356d67dde3506255 Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 4 Jun 2026 18:28:11 -0700 Subject: [PATCH 141/151] Automated Code Change PiperOrigin-RevId: 926997292 --- .../implementation/mediums/wifi_lan_test.cc | 71 ------------------- 1 file changed, 71 deletions(-) diff --git a/connections/implementation/mediums/wifi_lan_test.cc b/connections/implementation/mediums/wifi_lan_test.cc index b8d47d04..6b80bd8e 100644 --- a/connections/implementation/mediums/wifi_lan_test.cc +++ b/connections/implementation/mediums/wifi_lan_test.cc @@ -167,77 +167,6 @@ TEST_P(WifiLanTest, CanConnect) { env_.Stop(); } -TEST_P(WifiLanTest, CanConnectWithMultiplex) { - bool is_multiplex_enabled_wifi_lan = NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexWifiLan); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexWifiLan, - true); - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - env_.Start(); - WifiLan wifi_lan_client; - WifiLan wifi_lan_server; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch accept_latch(1); - CountDownLatch connect_latch(1); - - WifiLanSocket socket_for_server; - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - wifi_lan_server.StartAdvertising( - service_id, nsd_service_info, - [&](const std::string& service_id, WifiLanSocket socket) { - socket_for_server = std::move(socket); - accept_latch.CountDown(); - }); - - WifiLanSocket socket_for_client; - SingleThreadExecutor client_executor; - client_executor.Execute([&]() { - NsdServiceInfo discovered_service_info; - wifi_lan_client.StartDiscovery( - service_id, { - .service_discovered_cb = - [&discovered_latch, &discovered_service_info]( - NsdServiceInfo service_info, - const std::string& service_id) { - LOG(INFO) << "Discovered service_info=" - << &service_info; - discovered_service_info = service_info; - discovered_latch.CountDown(); - }, - }); - discovered_latch.Await(kWaitDuration).result(); - ASSERT_TRUE(discovered_service_info.IsValid()); - - CancellationFlag flag; - ErrorOr socket_for_client_result = - wifi_lan_client.Connect(service_id, discovered_service_info, &flag); - socket_for_client = std::move(socket_for_client_result.value()); - Base64Utils::WriteInt(&socket_for_client.GetOutputStream(), 4); - connect_latch.CountDown(); - }); - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(connect_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); - EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); - EXPECT_TRUE(socket_for_server.IsValid()); - EXPECT_TRUE(socket_for_client.IsValid()); - env_.Stop(); - NearbyFlags::GetInstance().OverrideBoolFlagValue( - config_package_nearby::nearby_connections_feature:: - kEnableMultiplexWifiLan, - is_multiplex_enabled_wifi_lan); -} - TEST_P(WifiLanTest, CanCancelConnect) { FeatureFlags feature_flags = GetParam(); env_.SetFeatureFlags(feature_flags); From 33a6a483203acfd37269032bd4216bdd62206feb Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 4 Jun 2026 19:17:50 -0700 Subject: [PATCH 142/151] Update save path for file sync transfers. PiperOrigin-RevId: 927012760 --- sharing/BUILD | 1 + sharing/fake_nearby_connections_manager.cc | 7 + sharing/fake_nearby_connections_manager.h | 14 +- sharing/nearby_sharing_service_impl.cc | 22 ++ sharing/nearby_sharing_service_impl_test.cc | 283 ++++++++++++++++++-- 5 files changed, 304 insertions(+), 23 deletions(-) diff --git a/sharing/BUILD b/sharing/BUILD index e66e1ce5..2af1bf4a 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -649,6 +649,7 @@ cc_test( ":nearby_connection_impl", ":nearby_sharing_service", ":share_session", + ":share_session_usage", ":test_support", ":transfer_metadata", ":transfer_metadata_matchers", diff --git a/sharing/fake_nearby_connections_manager.cc b/sharing/fake_nearby_connections_manager.cc index e69fbb7d..4fff1842 100644 --- a/sharing/fake_nearby_connections_manager.cc +++ b/sharing/fake_nearby_connections_manager.cc @@ -32,6 +32,7 @@ #include "internal/base/file_path.h" #include "sharing/common/nearby_share_enums.h" #include "sharing/internal/public/logging.h" +#include "sharing/nearby_connection.h" #include "sharing/nearby_connections_manager.h" #include "sharing/nearby_connections_types.h" #include "sharing/proto/enums.pb.h" @@ -204,6 +205,12 @@ void FakeNearbyConnectionsManager::UpgradeBandwidth( upgrade_bandwidth_endpoint_ids_.insert(std::string(endpoint_id)); } +void FakeNearbyConnectionsManager::OverrideSavePath( + absl::string_view endpoint_id, const FilePath& custom_save_path) { + absl::MutexLock lock(endpoints_mutex_); + custom_save_paths_[endpoint_id] = custom_save_path; +} + void FakeNearbyConnectionsManager::OnEndpointFound( absl::string_view endpoint_id, std::unique_ptr info) { diff --git a/sharing/fake_nearby_connections_manager.h b/sharing/fake_nearby_connections_manager.h index 94b3dddb..eabde28b 100644 --- a/sharing/fake_nearby_connections_manager.h +++ b/sharing/fake_nearby_connections_manager.h @@ -27,6 +27,7 @@ #include #include "absl/base/thread_annotations.h" +#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" @@ -76,7 +77,7 @@ class FakeNearbyConnectionsManager : public NearbyConnectionsManager { void UpgradeBandwidth(absl::string_view endpoint_id) override; void SetCustomSavePath(absl::string_view custom_save_path) override {} void OverrideSavePath(absl::string_view endpoint_id, - const FilePath& custom_save_path) override {} + const FilePath& custom_save_path) override; absl::flat_hash_set GetAndClearUnknownFilePathsToDelete() override; // Testing methods @@ -131,6 +132,14 @@ class FakeNearbyConnectionsManager : public NearbyConnectionsManager { return it->second; } + std::optional custom_save_path(absl::string_view endpoint_id) { + absl::MutexLock lock(endpoints_mutex_); + auto it = custom_save_paths_.find(endpoint_id); + if (it == custom_save_paths_.end()) return std::nullopt; + + return it->second; + } + bool has_incoming_payloads() { absl::MutexLock lock(incoming_payloads_mutex_); return !incoming_payloads_.empty(); @@ -177,6 +186,9 @@ class FakeNearbyConnectionsManager : public NearbyConnectionsManager { // Maps endpoint_id to endpoint_info. std::map> connection_endpoint_infos_ ABSL_GUARDED_BY(endpoints_mutex_); + // Maps endpoint_id to custom_save_path. + absl::flat_hash_map custom_save_paths_ + ABSL_GUARDED_BY(endpoints_mutex_); std::map> payload_status_listeners_; diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 49f16308..27575d31 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -2703,6 +2703,28 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( return; } FilePath save_path{settings_->GetCustomSavePath()}; + // If transfer is for file sync, override the save path to the custom save + // path. + if (frame.use_case() == IntroductionFrame::FILE_SYNC) { + if (!session.certificate().has_value() || + session.certificate()->binding_id().empty()) { + LOG(ERROR) << __func__ + << ": Binding id is empty for file sync session."; + Fail(session, TransferMetadata::Status::kRejected); + return; + } + std::optional binding = + sync_manager_.GetSyncBinding(session.certificate()->binding_id()); + if (!binding.has_value()) { + LOG(ERROR) << __func__ + << ": Sync binding not found for binding id: " + << session.certificate()->binding_id(); + Fail(session, TransferMetadata::Status::kRejected); + return; + } + save_path = FilePath(binding->destination_directory()); + session.set_session_usage(ShareSessionUsage::kFileSync); + } // Override save path for this connection. // This must be called before the transfer is accepted and payloads are being // received. diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index 491a56ef..23d3c1e8 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -88,6 +88,7 @@ #include "sharing/proto/enums.pb.h" #include "sharing/proto/rpc_resources.pb.h" #include "sharing/proto/wire_format.pb.h" +#include "sharing/share_session_usage.h" #include "sharing/share_target.h" #include "sharing/share_target_discovered_callback.h" #include "sharing/text_attachment.h" @@ -273,11 +274,13 @@ std::unique_ptr GetTextPayload(int64_t payload_id, std::vector(text.begin(), text.end())); } -std::unique_ptr GetValidIntroductionFrame() { +std::unique_ptr GetValidIntroductionFrame( + IntroductionFrame::SharingUseCase use_case) { IntroductionFrame* introduction_frame = IntroductionFrame::default_instance().New(); auto text_metadatas = introduction_frame->mutable_text_metadata(); introduction_frame->set_start_transfer(true); + introduction_frame->set_use_case(use_case); for (int i = 1; i <= 3; ++i) { nearby::sharing::service::proto::TextMetadata* text_metadata = @@ -665,10 +668,9 @@ class NearbySharingServiceImplTest : public testing::Test { EXPECT_TRUE(fake_nearby_connections_manager_->IsAdvertising()); } - void ProcessLatestPublicCertificateDecryption(size_t expected_num_calls, - bool success, - bool for_self_share = false, - uint8_t vendor_id = 0) { + void ProcessLatestPublicCertificateDecryption( + size_t expected_num_calls, bool success, bool for_self_share = false, + uint8_t vendor_id = 0, absl::string_view binding_id = "") { // Ensure that all pending mojo messages are processed and the certificate // manager state is as expected up to this point. std::vector< @@ -688,6 +690,9 @@ class NearbySharingServiceImplTest : public testing::Test { DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS, GetNearbyShareTestNotBefore(), vendor_id); cert.set_for_self_share(for_self_share); + if (!binding_id.empty()) { + cert.set_binding_id(binding_id); + } std::move(calls.back().callback)( NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate( cert, GetNearbyShareTestEncryptedMetadataKey())); @@ -744,13 +749,17 @@ class NearbySharingServiceImplTest : public testing::Test { return advertisement->ToEndpointInfo(); } - void SetUpIntroductionFrameDecoder(bool return_empty_introduction_frame) { - std::unique_ptr frame; - if (return_empty_introduction_frame) { - frame = GetEmptyIntroductionFrame(); - } else { - frame = GetValidIntroductionFrame(); - } + void SetUpEmptyIntroductionFrameDecoder() { + std::unique_ptr frame = GetEmptyIntroductionFrame(); + std::vector bytes(frame->ByteSizeLong()); + frame->SerializeToArray(bytes.data(), bytes.size()); + ReceiveMessageFromConnection(std::move(bytes)); + } + + void SetUpIntroductionFrameDecoder( + IntroductionFrame::SharingUseCase use_case = + IntroductionFrame::NEARBY_SHARE) { + std::unique_ptr frame = GetValidIntroductionFrame(use_case); std::vector bytes(frame->ByteSizeLong()); frame->SerializeToArray(bytes.data(), bytes.size()); ReceiveMessageFromConnection(std::move(bytes)); @@ -775,7 +784,7 @@ class NearbySharingServiceImplTest : public testing::Test { bool for_self_share = false) { fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, GetToken()); - SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false); + SetUpIntroductionFrameDecoder(); int64_t share_target_id; SetLanConnected(true); @@ -2375,7 +2384,7 @@ TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest, IncomingConnectionEmptyIntroductionFrame) { fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, GetToken()); - SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/true); + SetUpEmptyIntroductionFrameDecoder(); SetLanConnected(true); NiceMock callback; @@ -2414,7 +2423,7 @@ TEST_F(NearbySharingServiceImplTest, IncomingConnectionValidIntroductionFrameInvalidCertificate) { fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, GetToken()); - SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false); + SetUpIntroductionFrameDecoder(); SetLanConnected(true); NiceMock callback; @@ -2464,6 +2473,7 @@ TEST_F(NearbySharingServiceImplTest, IncomingConnectionTimedOut) { const AttachmentContainer& container, TransferMetadata metadata) { EXPECT_TRUE(metadata.is_final_status()); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing); EXPECT_EQ(metadata.status(), TransferMetadata::Status::kTimedOut); }); @@ -2487,6 +2497,7 @@ TEST_F(NearbySharingServiceImplTest, const AttachmentContainer& container, TransferMetadata metadata) { EXPECT_TRUE(metadata.is_final_status()); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing); EXPECT_EQ(metadata.status(), TransferMetadata::Status::kFailed); }); @@ -2614,7 +2625,7 @@ TEST_F(NearbySharingServiceImplTest, IncomingConnectionValidIntroductionFrameValidCertificate) { fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, GetToken()); - SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false); + SetUpIntroductionFrameDecoder(); SetLanConnected(true); NiceMock callback; @@ -2655,6 +2666,128 @@ TEST_F(NearbySharingServiceImplTest, .has_value()); } +TEST_F(NearbySharingServiceImplTest, + IncomingConnectionValidIntroductionFrameValidCertificateFileSync) { + fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, + GetToken()); + SetUpIntroductionFrameDecoder(IntroductionFrame::FILE_SYNC); + + constexpr absl::string_view kBindingId = "binding_id"; + sync::SyncBinding binding; + binding.set_binding_id(kBindingId); + binding.set_source_name(kDeviceName); + binding.set_destination_directory( + FilePath("Downloads").append(FilePath(kDeviceName)).ToString()); + binding.set_source_device_type(sync::SyncBinding::SOURCE_DEVICE_TYPE_PHONE); + service_->sync_manager().AddSyncBinding(binding); + + SetLanConnected(true); + NiceMock callback; + absl::Notification notification; + EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_, testing::_)) + .WillOnce([¬ification](const ShareTarget& share_target, + const AttachmentContainer& container, + TransferMetadata metadata) { + EXPECT_FALSE(metadata.is_final_status()); + EXPECT_EQ(TransferMetadata::Status::kAwaitingLocalConfirmation, + metadata.status()); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kFileSync); + EXPECT_TRUE(share_target.is_incoming); + EXPECT_TRUE(share_target.is_known); + EXPECT_TRUE(container.HasAttachments()); + EXPECT_EQ(container.GetTextAttachments().size(), 3u); + EXPECT_EQ(container.GetFileAttachments().size(), 1u); + EXPECT_EQ(share_target.device_name, kDeviceName); + EXPECT_EQ(share_target.type, kDeviceType); + EXPECT_NE(share_target.device_id, kEndpointId); + EXPECT_EQ(share_target.full_name, kTestMetadataFullName); + EXPECT_FALSE(share_target.for_self_share); + EXPECT_FALSE(metadata.is_self_share()); + EXPECT_TRUE(metadata.token().has_value()); + notification.Notify(); + }); + + SetUpKeyVerification(/*is_incoming=*/true, PairedKeyResultFrame::SUCCESS); + SetUpForegroundReceiveSurface(callback); + ScopedReceiveSurface r(service_.get(), &callback); + EXPECT_CALL(*mock_app_info_, SetActiveFlag()); + StartIncomingConnection(); + ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1, + /*success=*/true, + /*for_self_share=*/false, + /*vendor_id=*/0, kBindingId); + EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout)); + + EXPECT_TRUE( + fake_nearby_connections_manager_->connection_endpoint_info(kEndpointId) + .has_value()); + ASSERT_TRUE(fake_nearby_connections_manager_->custom_save_path(kEndpointId) + .has_value()); + EXPECT_EQ(fake_nearby_connections_manager_->custom_save_path(kEndpointId) + ->ToString(), + binding.destination_directory()); +} + +TEST_F(NearbySharingServiceImplTest, + IncomingIntroductionFrameCertificateEmptyBindingId) { + fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, + GetToken()); + SetUpIntroductionFrameDecoder(IntroductionFrame::FILE_SYNC); + + SetLanConnected(true); + NiceMock callback; + absl::Notification notification; + EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_, testing::_)) + .WillOnce([¬ification](const ShareTarget& share_target, + const AttachmentContainer& container, + TransferMetadata metadata) { + EXPECT_EQ(TransferMetadata::Status::kRejected, metadata.status()); + notification.Notify(); + }); + + SetUpKeyVerification(/*is_incoming=*/true, PairedKeyResultFrame::SUCCESS); + SetUpForegroundReceiveSurface(callback); + ScopedReceiveSurface r(service_.get(), &callback); + EXPECT_CALL(*mock_app_info_, SetActiveFlag()); + StartIncomingConnection(); + ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1, + /*success=*/true, + /*for_self_share=*/false, + /*vendor_id=*/0, /*binding_id=*/""); + EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout)); +} + +TEST_F(NearbySharingServiceImplTest, + IncomingIntroductionFrameFileSyncBindingNotFound) { + fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, + GetToken()); + SetUpIntroductionFrameDecoder(IntroductionFrame::FILE_SYNC); + + constexpr absl::string_view kBindingId = "binding_id"; + + SetLanConnected(true); + NiceMock callback; + absl::Notification notification; + EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_, testing::_)) + .WillOnce([¬ification](const ShareTarget& share_target, + const AttachmentContainer& container, + TransferMetadata metadata) { + EXPECT_EQ(TransferMetadata::Status::kRejected, metadata.status()); + notification.Notify(); + }); + + SetUpKeyVerification(/*is_incoming=*/true, PairedKeyResultFrame::SUCCESS); + SetUpForegroundReceiveSurface(callback); + ScopedReceiveSurface r(service_.get(), &callback); + EXPECT_CALL(*mock_app_info_, SetActiveFlag()); + StartIncomingConnection(); + ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1, + /*success=*/true, + /*for_self_share=*/false, + /*vendor_id=*/0, kBindingId); + EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout)); +} + TEST_F(NearbySharingServiceImplTest, AcceptInvalidShareTarget) { absl::Notification notification; service_->Accept( @@ -2711,6 +2844,7 @@ TEST_F(NearbySharingServiceImplTest, const AttachmentContainer& container, TransferMetadata metadata) { EXPECT_FALSE(metadata.is_final_status()); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing); EXPECT_EQ(metadata.status(), TransferMetadata::Status::kInProgress); progress_notification.Notify(); }); @@ -2785,6 +2919,7 @@ TEST_F(NearbySharingServiceImplTest, AcceptValidShareTargetPayloadFailed) { const AttachmentContainer& container, TransferMetadata metadata) { EXPECT_TRUE(metadata.is_final_status()); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing); EXPECT_EQ(metadata.status(), TransferMetadata::Status::kFailed); ASSERT_TRUE(container.HasAttachments()); EXPECT_EQ(container.GetFileAttachments().size(), 1u); @@ -2831,6 +2966,7 @@ TEST_F(NearbySharingServiceImplTest, AcceptValidShareTargetPayloadCancelled) { const AttachmentContainer& container, TransferMetadata metadata) { EXPECT_TRUE(metadata.is_final_status()); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing); EXPECT_EQ(metadata.status(), TransferMetadata::Status::kCancelled); ASSERT_TRUE(container.HasAttachments()); EXPECT_EQ(container.GetFileAttachments().size(), 1u); @@ -2883,6 +3019,7 @@ TEST_F(NearbySharingServiceImplTest, RejectValidShareTarget) { const AttachmentContainer& container, TransferMetadata metadata) { EXPECT_TRUE(metadata.is_final_status()); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing); EXPECT_EQ(metadata.status(), TransferMetadata::Status::kRejected); }); @@ -2909,7 +3046,7 @@ TEST_F(NearbySharingServiceImplTest, IncomingConnectionKeyVerificationRunnerStatusUnable) { fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, GetToken()); - SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false); + SetUpIntroductionFrameDecoder(); SetLanConnected(true); NiceMock callback; @@ -2952,7 +3089,7 @@ TEST_F(NearbySharingServiceImplTest, IncomingConnectionKeyVerificationRunnerStatusUnableLowPower) { fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, GetToken()); - SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false); + SetUpIntroductionFrameDecoder(); SetLanConnected(true); NiceMock callback; @@ -3654,6 +3791,7 @@ TEST_F(NearbySharingServiceImplTest, CancelReceiverInitiator) { const AttachmentContainer& container, TransferMetadata metadata) { EXPECT_EQ(share_target.id, target_id); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing); EXPECT_EQ(metadata.status(), TransferMetadata::Status::kCancelled); }); EXPECT_FALSE( @@ -3702,6 +3840,7 @@ TEST_F(NearbySharingServiceImplTest, CancelReceiverNoninitiator) { const AttachmentContainer& container, TransferMetadata metadata) { EXPECT_EQ(target_id, share_target.id); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing); EXPECT_EQ(TransferMetadata::Status::kCancelled, metadata.status()); notification.Notify(); }); @@ -4661,8 +4800,7 @@ TEST_F(NearbySharingServiceImplTest, LoginAndLogoutShouldResetSettings) { ASSERT_TRUE(service_->GetAccountManager()->GetCurrentAccount().has_value()); EXPECT_EQ(service_->GetAccountManager()->GetCurrentAccount()->id, kTestAccountId); - device_id = - preference_manager_.GetString(PrefNames::kDeviceId, ""); + device_id = preference_manager_.GetString(PrefNames::kDeviceId, ""); EXPECT_FALSE(device_id.empty()); EXPECT_EQ(device_id.size(), 10u); for (const char c : device_id) EXPECT_TRUE(std::isalnum(c)); @@ -4679,8 +4817,7 @@ TEST_F(NearbySharingServiceImplTest, LoginAndLogoutShouldResetSettings) { EXPECT_TRUE(service_->GetSettings()->GetIsAnalyticsEnabled()); EXPECT_FALSE(service_->GetAccountManager()->GetCurrentAccount().has_value()); EXPECT_TRUE(sharing_service_task_runner_->SyncWithTimeout(kTaskWaitTimeout)); - device_id = - preference_manager_.GetString(PrefNames::kDeviceId, ""); + device_id = preference_manager_.GetString(PrefNames::kDeviceId, ""); EXPECT_TRUE(device_id.empty()); } @@ -5097,5 +5234,107 @@ TEST_F(NearbySharingServiceImplTest, InitiatePairingSuccess) { EXPECT_THAT(binding->sync_bindings(0), EqualsProto(expected_binding)); } +TEST_F(NearbySharingServiceImplTest, + InitiatePairingSuccessCheckUsageAndBindingId) { + MockTransferUpdateCallback transfer_callback; + MockShareTargetDiscoveredCallback discovery_callback; + int64_t target_id = SetUpOutgoingShareTarget( + transfer_callback, discovery_callback, /*for_self_share=*/true); + ScopedSendSurface s(service_.get(), &transfer_callback); + absl::Notification notification; + + constexpr absl::string_view kBindingId = "binding_id"; + + EXPECT_CALL(transfer_callback, + OnTransferUpdate(testing::_, testing::_, testing::_)) + .WillOnce([&](const ShareTarget& share_target, + const AttachmentContainer& container, + const TransferMetadata& metadata) { + EXPECT_EQ(share_target.id, target_id); + EXPECT_EQ(metadata.status(), TransferMetadata::Status::kConnecting); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kUnknown); + EXPECT_TRUE(metadata.binding_id().empty()); + }) + .WillOnce([&](const ShareTarget& share_target, + const AttachmentContainer& container, + const TransferMetadata& metadata) { + EXPECT_EQ(share_target.id, target_id); + EXPECT_EQ(metadata.status(), + TransferMetadata::Status::kAwaitingRemoteAcceptance); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kPairing); + EXPECT_TRUE(metadata.binding_id().empty()); + }) + .WillOnce([&](const ShareTarget& share_target, + const AttachmentContainer& container, + const TransferMetadata& metadata) { + EXPECT_EQ(share_target.id, target_id); + EXPECT_EQ(metadata.status(), TransferMetadata::Status::kComplete); + EXPECT_EQ(metadata.usage(), ShareSessionUsage::kPairing); + EXPECT_EQ(metadata.binding_id(), kBindingId); + notification.Notify(); + }); + + absl::Notification pairing_notification; + NearbySharingServiceImpl::StatusCodes pairing_result; + EXPECT_CALL(*mock_app_info_, SetActiveFlag()); + google::nearby::identity::v1::InitiateBindingResponse response; + response.set_binding_id(kBindingId); + nearby_identity_client_.SetInitiateBindingResponses({response}); + service_->InitiatePairing( + target_id, service::proto::BindingRequest::FILESYNC, + [&](NearbySharingServiceImpl::StatusCodes status_code) { + pairing_result = status_code; + pairing_notification.Notify(); + }); + EXPECT_TRUE( + pairing_notification.WaitForNotificationWithTimeout(kTaskWaitTimeout)); + EXPECT_EQ(pairing_result, NearbySharingServiceImpl::StatusCodes::kOk); + + FlushTesting(); + // Verify data sent to the remote device so far. + EXPECT_TRUE(ExpectPairedKeyEncryptionFrame()); + EXPECT_TRUE(ExpectPairedKeyResultFrame()); + + // Check BindingRequest frame sent to the remote device. + std::unique_ptr frame = GetWrittenFrame(); + ASSERT_TRUE(frame->has_v1()); + EXPECT_EQ(frame->v1().type(), service::proto::V1Frame::BINDINGS); + EXPECT_EQ(frame->v1().bindings().binding_request().binding_id(), kBindingId); + EXPECT_EQ(frame->v1().bindings().binding_request().type(), + service::proto::BindingRequest::FILESYNC); + + preference_manager_.SetString(PrefNames::kCustomSavePath, "Downloads"); + Frame binding_response_frame; + binding_response_frame.set_version(Frame::V1); + binding_response_frame.mutable_v1()->set_type( + service::proto::V1Frame::BINDINGS); + binding_response_frame.mutable_v1() + ->mutable_bindings() + ->mutable_binding_response() + ->set_status(service::proto::BindingResponse::SUCCESS); + std::vector result_bytes(binding_response_frame.ByteSizeLong()); + binding_response_frame.SerializeToArray(result_bytes.data(), + result_bytes.size()); + ReceiveMessageFromConnection(std::move(result_bytes)); + + // Verify that connection is closed. + EXPECT_FALSE( + fake_nearby_connections_manager_->connection_endpoint_info(kEndpointId) + .has_value()); + + std::optional binding = + preference_manager_.GetSyncBindingValue(); + ASSERT_TRUE(binding.has_value()); + EXPECT_EQ(binding->sync_bindings().size(), 1); + sync::SyncBinding expected_binding; + expected_binding.set_binding_id(kBindingId); + expected_binding.set_source_name(kDeviceName); + expected_binding.set_destination_directory( + FilePath("Downloads").append(FilePath(kDeviceName)).ToString()); + expected_binding.set_source_device_type( + sync::SyncBinding::SOURCE_DEVICE_TYPE_PHONE); + EXPECT_THAT(binding->sync_bindings(0), EqualsProto(expected_binding)); +} + } // namespace NearbySharingServiceUnitTests } // namespace nearby::sharing From e7e754611a9c028daf97eaf684448aa370880fe1 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 5 Jun 2026 12:54:23 -0700 Subject: [PATCH 143/151] internal PiperOrigin-RevId: 927440257 --- .../implementation/flags/nearby_connections_feature_flags.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h index 9b322ee5..d6cd22d4 100755 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -55,15 +55,9 @@ constexpr auto kEnableGattClientDisconnection = // When true, enable multiplexing in NC for Bluetooth. constexpr auto kEnableMultiplexBluetooth = flags::Flag(kConfigPackage, "45676646", false); -// When true, enable multiplexing in NC for Wifi. -constexpr auto kEnableMultiplexWifiLan = - flags::Flag(kConfigPackage, "45676647", false); // Enable/Disable preferences for Nearby Connections. constexpr auto kEnableNearbyConnectionsPreferences = flags::Flag(kConfigPackage, "45732423", false); -// Enable/Disable payload manager to skip chunk update. -constexpr auto kEnablePayloadManagerToSkipChunkUpdate = - flags::Flag(kConfigPackage, "45415729", true); // Enable/Disable payload-received-ack feature. constexpr auto kEnablePayloadReceivedAck = flags::Flag(kConfigPackage, "45425840", false); From 3dcbad2dea350bacd8bd1dcac959224dbe2f631b Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 8 Jun 2026 11:18:26 -0700 Subject: [PATCH 144/151] Fix read error does not cause send to fail. PiperOrigin-RevId: 928671777 --- connections/BUILD | 2 +- connections/implementation/payload_manager.cc | 331 ++++++++---------- connections/implementation/payload_manager.h | 132 +++---- connections/payload.cc | 7 +- connections/payload.h | 13 +- connections/payload_test.cc | 23 +- connections/payload_type.h | 73 ++-- 7 files changed, 262 insertions(+), 319 deletions(-) diff --git a/connections/BUILD b/connections/BUILD index f850f505..054ef7de 100644 --- a/connections/BUILD +++ b/connections/BUILD @@ -103,8 +103,8 @@ cc_library( "//proto:connections_enums_cc_proto", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/random", + "@com_google_absl//absl/strings", "@com_google_absl//absl/time", - "@com_google_absl//absl/types:variant", ], ) diff --git a/connections/implementation/payload_manager.cc b/connections/implementation/payload_manager.cc index 9fdd392d..f64e3ee1 100644 --- a/connections/implementation/payload_manager.cc +++ b/connections/implementation/payload_manager.cc @@ -27,7 +27,7 @@ #include "absl/functional/any_invocable.h" #include "absl/functional/bind_front.h" #include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" #include "absl/time/time.h" #include "connections/implementation/analytics/analytics_recorder.h" #include "connections/implementation/client_proxy.h" @@ -52,8 +52,7 @@ #include "internal/platform/mutex_lock.h" #include "internal/platform/single_thread_executor.h" -namespace nearby { -namespace connections { +namespace nearby::connections { namespace { using ::location::nearby::connections::OfflineFrame; @@ -65,17 +64,59 @@ using ::location::nearby::proto::connections::PayloadStatus; using ::nearby::analytics::AnalyticsRecorder; constexpr absl::Duration kMinTransferUpdateInterval = absl::Milliseconds(50); + +std::string EndpointIdsToString(const std::vector& endpoint_ids) { + return absl::StrCat(endpoint_ids.size(), ":", + absl::StrJoin(endpoint_ids, ",")); +} + +PayloadStatus ControlMessageEventToPayloadStatus( + PayloadTransferFrame::ControlMessage::EventType event) { + switch (event) { + case PayloadTransferFrame::ControlMessage::PAYLOAD_ERROR: + return PayloadStatus::REMOTE_ERROR; + case PayloadTransferFrame::ControlMessage::PAYLOAD_CANCELED: + return PayloadStatus::REMOTE_CANCELLATION; + default: + VLOG(1) << "PayloadManager: unknown event=" << event; + return PayloadStatus::UNKNOWN_PAYLOAD_STATUS; + } +} + +OperationResultCode ControlMessageEventToOperationResultCode( + PayloadTransferFrame::ControlMessage::EventType event) { + switch (event) { + case PayloadTransferFrame::ControlMessage::PAYLOAD_ERROR: + return OperationResultCode::NEARBY_GENERIC_REMOTE_REPORT_PAYLOADS_ERROR; + case PayloadTransferFrame::ControlMessage::PAYLOAD_CANCELED: + return OperationResultCode::CLIENT_CANCELLATION_REMOTE_CANCEL_PAYLOAD; + default: + VLOG(1) << "PayloadManager: unknown event=" << event; + return OperationResultCode::DETAIL_UNKNOWN; + } +} + +PayloadProgressInfo::Status PayloadStatusToTransferUpdateStatus( + PayloadStatus status) { + switch (status) { + case PayloadStatus::LOCAL_CANCELLATION: + case PayloadStatus::REMOTE_CANCELLATION: + return PayloadProgressInfo::Status::kCanceled; + case PayloadStatus::SUCCESS: + return PayloadProgressInfo::Status::kSuccess; + default: + return PayloadProgressInfo::Status::kFailure; + } +} + } // namespace -bool PayloadManager::SendPayloadLoop( +int PayloadManager::SendPayloadLoop( ClientProxy* client, PendingPayload& pending_payload, PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t& next_chunk_offset, size_t resume_offset, int index) { - // in lieu of structured binding: - auto pair = GetAvailableAndUnavailableEndpoints(pending_payload); - const EndpointIds& available_endpoint_ids = - EndpointsToEndpointIds(pair.first); - const Endpoints& unavailable_endpoints = pair.second; + int64_t next_chunk_offset, size_t resume_offset, int index) { + auto [available_endpoint_ids, unavailable_endpoints] = + GetAvailableAndUnavailableEndpoints(pending_payload); // First, handle any non-available endpoints. for (const auto& endpoint : unavailable_endpoints) { @@ -91,7 +132,7 @@ bool PayloadManager::SendPayloadLoop( << pending_payload.GetInternalPayload()->GetId() << " after sending " << next_chunk_offset << " bytes because none of the endpoints are available anymore."; - return false; + return -1; } // Check if the payload has been cancelled by the client and, if so, @@ -104,13 +145,9 @@ bool PayloadManager::SendPayloadLoop( client, available_endpoint_ids, payload_header, next_chunk_offset, OperationResultCode::CLIENT_CANCELLATION_LOCAL_CANCEL_PAYLOAD, PayloadStatus::LOCAL_CANCELLATION); - return false; + return -1; } - // Update the current offsets for all endpoints still active for this - // payload. For the sake of accuracy, we update the pending payload here - // because it's after all payload terminating events are handled, but - // right before we actually start detaching the next chunk. if (next_chunk_offset == 0 && resume_offset > 0) { ExceptionOr real_offset = pending_payload.GetInternalPayload()->SkipToOffset(resume_offset); @@ -123,13 +160,17 @@ bool PayloadManager::SendPayloadLoop( payload_header, next_chunk_offset, OperationResultCode::IO_FILE_READING_ERROR, PayloadStatus::LOCAL_ERROR); - return false; + return -1; } VLOG(1) << "PayloadManager successfully skipped " << real_offset.GetResult() << " bytes on payload_id " << pending_payload.GetInternalPayload()->GetId(); next_chunk_offset = real_offset.GetResult(); } + // Update the current offsets for all endpoints still active for this + // payload. For the sake of accuracy, we update the pending payload here + // because it's after all payload terminating events are handled, but + // right before we actually start detaching the next chunk. for (const auto& endpoint_id : available_endpoint_ids) { pending_payload.SetOffsetForEndpoint(endpoint_id, next_chunk_offset); } @@ -139,19 +180,20 @@ bool PayloadManager::SendPayloadLoop( int chunk_size = GetOptimalChunkSize(available_endpoint_ids); ByteArray next_chunk = pending_payload.GetInternalPayload()->DetachNextChunk(chunk_size); - if (shutdown_.Get()) return false; + if (shutdown_.Get()) return -1; // Save chunk size. We'll need it after we move next_chunk. - auto next_chunk_size = next_chunk.size(); - if (!next_chunk_size && + size_t next_chunk_size = next_chunk.size(); + // If there are no more chunks, check if there should be more data to send. + if (next_chunk_size == 0 && pending_payload.GetInternalPayload()->GetTotalSize() > 0 && - pending_payload.GetInternalPayload()->GetTotalSize() < + pending_payload.GetInternalPayload()->GetTotalSize() > next_chunk_offset) { VLOG(1) << "Payload xfer failed: payload_id=" << pending_payload.GetInternalPayload()->GetId(); HandleFinishedOutgoingPayload( client, available_endpoint_ids, payload_header, next_chunk_offset, OperationResultCode::IO_FILE_READING_ERROR, PayloadStatus::LOCAL_ERROR); - return false; + return -1; } // Only need to handle outgoing data chunk offset, because the offset will be @@ -160,13 +202,14 @@ bool PayloadManager::SendPayloadLoop( // happened. PayloadTransferFrame::PayloadChunk payload_chunk(CreatePayloadChunk( next_chunk_offset - resume_offset, std::move(next_chunk), index)); - const EndpointIds& failed_endpoint_ids = endpoint_manager_->SendPayloadChunk( - payload_header, payload_chunk, available_endpoint_ids); + const std::vector& failed_endpoint_ids = + endpoint_manager_->SendPayloadChunk(payload_header, payload_chunk, + available_endpoint_ids); // Check whether at least one endpoint failed. if (!failed_endpoint_ids.empty()) { VLOG(1) << "Payload xfer: endpoints failed: payload_id=" << payload_header.id() << "; endpoint_ids={" - << ToString(failed_endpoint_ids) << "}", + << EndpointIdsToString(failed_endpoint_ids) << "}", HandleFinishedOutgoingPayload( client, failed_endpoint_ids, payload_header, next_chunk_offset, OperationResultCode::CONNECTIVITY_GENERIC_WRITING_CHANNEL_IO_ERROR, @@ -191,90 +234,36 @@ bool PayloadManager::SendPayloadLoop( payload_chunk.offset(), payload_chunk.body().size()); } } - VLOG(1) << "PayloadManager done sending chunk at offset " - << next_chunk_offset << " of payload_id=" - << pending_payload.GetInternalPayload()->GetId(); - next_chunk_offset += next_chunk_size; - if (!next_chunk_size) { + if (next_chunk_size == 0) { // That was the last chunk, we're outta here. VLOG(1) << "Payload xfer done: payload_id=" << pending_payload.GetInternalPayload()->GetId() << "; size=" << next_chunk_offset; - return false; + return -1; + } else { + VLOG(1) << "PayloadManager done sending chunk at offset " + << next_chunk_offset << " of payload_id=" + << pending_payload.GetInternalPayload()->GetId(); } } - return true; + return next_chunk_size; } -std::pair +std::pair, PayloadManager::Endpoints> PayloadManager::GetAvailableAndUnavailableEndpoints( const PendingPayload& pending_payload) { - Endpoints available; - Endpoints unavailable; + auto results = std::make_pair(std::vector(), + std::vector()); for (auto* endpoint_info : pending_payload.GetEndpoints()) { - if (endpoint_info->status.Get() == - PayloadManager::EndpointInfo::Status::kAvailable) { - available.push_back(endpoint_info); + if (endpoint_info->status.Get() == EndpointInfo::Status::kAvailable) { + results.first.push_back(endpoint_info->id); } else { - unavailable.push_back(endpoint_info); + results.second.push_back(endpoint_info); } } - return std::make_pair(std::move(available), std::move(unavailable)); -} - -PayloadManager::EndpointIds PayloadManager::EndpointsToEndpointIds( - const Endpoints& endpoints) { - EndpointIds endpoint_ids; - endpoint_ids.reserve(endpoints.size()); - for (const auto& item : endpoints) { - if (item) { - endpoint_ids.emplace_back(item->id); - } - } - return endpoint_ids; -} - -std::string PayloadManager::ToString(const Endpoints& endpoints) { - std::string endpoints_string = absl::StrCat(endpoints.size(), ": "); - bool first = true; - for (const auto& item : endpoints) { - if (first) { - absl::StrAppend(&endpoints_string, item->id); - first = false; - } else { - absl::StrAppend(&endpoints_string, ", ", item->id); - } - } - return endpoints_string; -} - -std::string PayloadManager::ToString(const EndpointIds& endpoint_ids) { - std::string endpoints_string = absl::StrCat(endpoint_ids.size(), ": "); - bool first = true; - for (const auto& id : endpoint_ids) { - if (first) { - absl::StrAppend(&endpoints_string, id); - first = false; - } else { - absl::StrAppend(&endpoints_string, ", ", id); - } - } - return endpoints_string; -} - -std::string PayloadManager::ToString(PayloadType type) { - switch (type) { - case PayloadType::kBytes: - return std::string("Bytes"); - case PayloadType::kStream: - return std::string("Stream"); - case PayloadType::kFile: - return std::string("File"); - case PayloadType::kUnknown: - return std::string("Unknown"); - } + return results; } std::string PayloadManager::ToString(EndpointInfo::Status status) { @@ -292,7 +281,7 @@ std::string PayloadManager::ToString(EndpointInfo::Status status) { // Creates and starts tracking a PendingPayload for this Payload. Payload::Id PayloadManager::CreateOutgoingPayload( - Payload payload, const EndpointIds& endpoint_ids) { + Payload payload, const std::vector& endpoint_ids) { ErrorOr> result = CreateOutgoingInternalPayload(std::move(payload)); if (result.has_error()) { @@ -389,13 +378,14 @@ bool PayloadManager::NotifyShutdown() { } void PayloadManager::SendPayload(ClientProxy* client, - const EndpointIds& endpoint_ids, + const std::vector& endpoint_ids, Payload payload) { if (shutdown_.Get()) return; - VLOG(1) << "SendPayload: endpoint_ids={" << ToString(endpoint_ids) << "}"; + VLOG(1) << "SendPayload: endpoint_ids={" << EndpointIdsToString(endpoint_ids) + << "}"; // Before transfer to internal payload, retrieves the Payload size for // analytics. - std::int64_t payload_total_size; + int64_t payload_total_size; switch (payload.GetType()) { case connections::PayloadType::kBytes: payload_total_size = payload.AsBytes().size(); @@ -420,8 +410,7 @@ void PayloadManager::SendPayload(ClientProxy* client, OperationResultCode::NEARBY_GENERIC_OUTGOING_PAYLOAD_CREATION_FAILURE); VLOG(1) << "PayloadManager failed to determine the right executor for " "outgoing payload_id=" - << payload.GetId() - << ", payload_type=" << ToString(payload.GetType()); + << payload.GetId() << ", payload_type=" << payload.GetType(); return; } @@ -450,7 +439,7 @@ void PayloadManager::SendPayload(ClientProxy* client, NEARBY_GENERIC_OUTGOING_PAYLOAD_CREATION_FAILURE); VLOG(1) << "PayloadManager failed to create InternalPayload for outgoing " "payload_id=" - << payload_id << ", payload_type=" << ToString(payload_type) + << payload_id << ", payload_type=" << payload_type << ", aborting sendPayload()."; return; } @@ -465,13 +454,19 @@ void PayloadManager::SendPayload(ClientProxy* client, CreatePayloadHeader(*internal_payload, resume_offset)}; bool should_continue = true; - std::int64_t next_chunk_offset = 0; + int64_t next_chunk_offset = 0; int index = 0; while (should_continue && !shutdown_.Get()) { - should_continue = - SendPayloadLoop(client, *pending_payload, payload_header, - next_chunk_offset, resume_offset, index); + int bytes_sent = SendPayloadLoop(client, *pending_payload, payload_header, + next_chunk_offset, resume_offset, index); + should_continue = (bytes_sent >= 0); + if (should_continue) { + if (next_chunk_offset == 0 && resume_offset > 0) { + next_chunk_offset = resume_offset; + } + next_chunk_offset += bytes_sent; + } index++; } @@ -482,8 +477,7 @@ void PayloadManager::SendPayload(ClientProxy* client, }); }); VLOG(1) << "PayloadManager: xfer scheduled: self=" << this - << "; payload_id=" << payload_id - << ", payload_type=" << ToString(payload_type); + << "; payload_id=" << payload_id << ", payload_type=" << payload_type; } PayloadManager::PendingPayloadHandle PayloadManager::GetPayload( @@ -580,14 +574,14 @@ void PayloadManager::OnEndpointDisconnect(ClientProxy* client, pending_payloads_.ForEachPayload([&](PendingPayload* pending_payload) { auto endpoint_info = pending_payload->GetEndpoint(endpoint_id); if (!endpoint_info) return; - std::int64_t endpoint_offset = endpoint_info->offset; + int64_t endpoint_offset = endpoint_info->offset; // Stop tracking the endpoint for this payload. pending_payload->RemoveEndpoints({endpoint_id}); // |endpoint_info| is longer valid after calling // RemoveEndpoints. endpoint_info = nullptr; - std::int64_t payload_total_size = + int64_t payload_total_size = pending_payload->GetInternalPayload()->GetTotalSize(); // If no endpoints are left for this payload, close it. @@ -669,45 +663,6 @@ OperationResultCode PayloadManager::EndpointInfoStatusToOperationResultCode( } } -PayloadStatus PayloadManager::ControlMessageEventToPayloadStatus( - PayloadTransferFrame::ControlMessage::EventType event) { - switch (event) { - case PayloadTransferFrame::ControlMessage::PAYLOAD_ERROR: - return PayloadStatus::REMOTE_ERROR; - case PayloadTransferFrame::ControlMessage::PAYLOAD_CANCELED: - return PayloadStatus::REMOTE_CANCELLATION; - default: - VLOG(1) << "PayloadManager: unknown event=" << event; - return PayloadStatus::UNKNOWN_PAYLOAD_STATUS; - } -} - -OperationResultCode PayloadManager::ControlMessageEventToOperationResultCode( - PayloadTransferFrame::ControlMessage::EventType event) { - switch (event) { - case PayloadTransferFrame::ControlMessage::PAYLOAD_ERROR: - return OperationResultCode::NEARBY_GENERIC_REMOTE_REPORT_PAYLOADS_ERROR; - case PayloadTransferFrame::ControlMessage::PAYLOAD_CANCELED: - return OperationResultCode::CLIENT_CANCELLATION_REMOTE_CANCEL_PAYLOAD; - default: - VLOG(1) << "PayloadManager: unknown event=" << event; - return OperationResultCode::DETAIL_UNKNOWN; - } -} - -PayloadProgressInfo::Status PayloadManager::PayloadStatusToTransferUpdateStatus( - PayloadStatus status) { - switch (status) { - case PayloadStatus::LOCAL_CANCELLATION: - case PayloadStatus::REMOTE_CANCELLATION: - return PayloadProgressInfo::Status::kCanceled; - case PayloadStatus::SUCCESS: - return PayloadProgressInfo::Status::kSuccess; - default: - return PayloadProgressInfo::Status::kFailure; - } -} - SingleThreadExecutor* PayloadManager::GetOutgoingPayloadExecutor( PayloadType payload_type) { switch (payload_type) { @@ -722,7 +677,8 @@ SingleThreadExecutor* PayloadManager::GetOutgoingPayloadExecutor( } } -int PayloadManager::GetOptimalChunkSize(EndpointIds endpoint_ids) { +int PayloadManager::GetOptimalChunkSize( + const std::vector& endpoint_ids) { int minChunkSize = std::numeric_limits::max(); for (const auto& endpoint_id : endpoint_ids) { minChunkSize = std::min( @@ -754,8 +710,7 @@ PayloadTransferFrame::PayloadHeader PayloadManager::CreatePayloadHeader( } PayloadTransferFrame::PayloadChunk PayloadManager::CreatePayloadChunk( - std::int64_t payload_chunk_offset, ByteArray payload_chunk_body, - int index) { + int64_t payload_chunk_offset, ByteArray payload_chunk_body, int index) { PayloadTransferFrame::PayloadChunk payload_chunk; payload_chunk.set_offset(payload_chunk_offset); @@ -776,9 +731,8 @@ PayloadManager::CreateIncomingPayload(const PayloadTransferFrame& frame, const std::string& endpoint_id, const std::string& save_path) { ErrorOr> result = - CreateIncomingInternalPayload(frame, save_path.empty() - ? custom_save_path_ - : save_path); + CreateIncomingInternalPayload( + frame, save_path.empty() ? custom_save_path_ : save_path); if (result.has_error()) { return {result.error()}; } @@ -788,7 +742,8 @@ PayloadManager::CreateIncomingPayload(const PayloadTransferFrame& frame, pending_payloads_.StartTrackingPayload( payload_id, std::make_unique( - std::move(internal_payload), EndpointIds{endpoint_id}, true, + std::move(internal_payload), std::vector{endpoint_id}, + true, absl::bind_front(&PayloadManager::OnPendingPayloadDestroy, this))); return {pending_payloads_.GetPayload(payload_id)}; } @@ -803,9 +758,9 @@ void PayloadManager::OnPendingPayloadDestroy(const PendingPayload* payload) { } void PayloadManager::SendClientCallbacksForFinishedOutgoingPayload( - ClientProxy* client, const EndpointIds& finished_endpoint_ids, + ClientProxy* client, const std::vector& finished_endpoint_ids, const PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t num_bytes_successfully_transferred, PayloadStatus status, + int64_t num_bytes_successfully_transferred, PayloadStatus status, OperationResultCode operation_result_code) { RunOnStatusUpdateThread( "outgoing-payload-callbacks", @@ -819,8 +774,7 @@ void PayloadManager::SendClientCallbacksForFinishedOutgoingPayload( } PayloadProgressInfo update{ - payload_header.id(), - PayloadManager::PayloadStatusToTransferUpdateStatus(status), + payload_header.id(), PayloadStatusToTransferUpdateStatus(status), payload_header.total_size(), num_bytes_successfully_transferred}; for (const auto& endpoint_id : finished_endpoint_ids) { // Skip sending notifications if we have stopped tracking this @@ -855,7 +809,7 @@ void PayloadManager::SendClientCallbacksForFinishedOutgoingPayload( void PayloadManager::SendClientCallbacksForFinishedIncomingPayload( ClientProxy* client, const std::string& endpoint_id, const PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t offset_bytes, PayloadStatus status, + int64_t offset_bytes, PayloadStatus status, OperationResultCode operation_result_code) { RunOnStatusUpdateThread( "incoming-payload-callbacks", @@ -870,10 +824,9 @@ void PayloadManager::SendClientCallbacksForFinishedIncomingPayload( // Unless we never started tracking this payload (meaning we // failed to even create the InternalPayload), notify the client // (and close it). - PayloadProgressInfo update{ - payload_header.id(), - PayloadManager::PayloadStatusToTransferUpdateStatus(status), - payload_header.total_size(), offset_bytes}; + PayloadProgressInfo update{payload_header.id(), + PayloadStatusToTransferUpdateStatus(status), + payload_header.total_size(), offset_bytes}; NotifyClientOfIncomingPayloadProgressInfo(client, endpoint_id, update); DestroyPendingPayload(payload_header.id()); @@ -884,9 +837,9 @@ void PayloadManager::SendClientCallbacksForFinishedIncomingPayload( } void PayloadManager::SendControlMessage( - const EndpointIds& endpoint_ids, + const std::vector& endpoint_ids, const PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t num_bytes_successfully_transferred, + int64_t num_bytes_successfully_transferred, PayloadTransferFrame::ControlMessage::EventType event_type) { PayloadTransferFrame::ControlMessage control_message; control_message.set_event(event_type); @@ -922,7 +875,7 @@ bool PayloadManager::WaitForReceivedAck( ClientProxy* client, const std::string& endpoint_id, PendingPayload& pending_payload, const PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t payload_chunk_offset, bool is_last_chunk) { + int64_t payload_chunk_offset, bool is_last_chunk) { if (!is_last_chunk || !IsPayloadReceivedAckEnabled(client, endpoint_id, pending_payload)) { return true; @@ -1025,9 +978,9 @@ bool PayloadManager::IsPayloadReceivedAckEnabled( } void PayloadManager::HandleFinishedOutgoingPayload( - ClientProxy* client, const EndpointIds& finished_endpoint_ids, + ClientProxy* client, const std::vector& finished_endpoint_ids, const PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t num_bytes_successfully_transferred, + int64_t num_bytes_successfully_transferred, OperationResultCode operation_result_code, PayloadStatus status) { // This call will destroy a pending payload. SendClientCallbacksForFinishedOutgoingPayload( @@ -1071,7 +1024,7 @@ void PayloadManager::HandleFinishedOutgoingPayload( void PayloadManager::HandleFinishedIncomingPayload( ClientProxy* client, const std::string& endpoint_id, const PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t offset_bytes, PayloadStatus status, + int64_t offset_bytes, PayloadStatus status, OperationResultCode operation_result_code) { SendClientCallbacksForFinishedIncomingPayload(client, endpoint_id, payload_header, offset_bytes, @@ -1097,8 +1050,8 @@ void PayloadManager::HandleFinishedIncomingPayload( void PayloadManager::HandleSuccessfulOutgoingChunk( ClientProxy* client, const std::string& endpoint_id, const PayloadTransferFrame::PayloadHeader& payload_header, - std::int32_t payload_chunk_flags, std::int64_t payload_chunk_offset, - std::int64_t payload_chunk_body_size) { + int32_t payload_chunk_flags, int64_t payload_chunk_offset, + int64_t payload_chunk_body_size) { { MutexLock lock(&chunk_update_mutex_); ++outgoing_chunk_update_count_; @@ -1192,8 +1145,8 @@ void PayloadManager::DestroyPendingPayload(Payload::Id payload_id) { void PayloadManager::HandleSuccessfulIncomingChunk( ClientProxy* client, const std::string& endpoint_id, const PayloadTransferFrame::PayloadHeader& payload_header, - std::int32_t payload_chunk_flags, std::int64_t payload_chunk_offset, - std::int64_t payload_chunk_body_size) { + int32_t payload_chunk_flags, int64_t payload_chunk_offset, + int64_t payload_chunk_body_size) { { MutexLock lock(&chunk_update_mutex_); ++incoming_chunk_update_count_; @@ -1377,7 +1330,7 @@ void PayloadManager::ProcessDataPacket( payload_chunk.offset()); // Save size of packet before we move it. - std::int64_t payload_body_size = payload_chunk.body().size(); + int64_t payload_body_size = payload_chunk.body().size(); if (pending_payload->GetInternalPayload() ->AttachNextChunk(payload_chunk.body()) @@ -1493,18 +1446,18 @@ void PayloadManager::NotifyClientOfIncomingPayloadProgressInfo( } void PayloadManager::RecordPayloadStartedAnalytics( - ClientProxy* client, const EndpointIds& endpoint_ids, - std::int64_t payload_id, PayloadType payload_type, std::int64_t offset, - std::int64_t total_size) { + ClientProxy* client, const std::vector& endpoint_ids, + int64_t payload_id, PayloadType payload_type, int64_t offset, + int64_t total_size) { client->GetAnalyticsRecorder().OnOutgoingPayloadStarted( endpoint_ids, payload_id, payload_type, total_size == -1 ? -1 : total_size - offset); } void PayloadManager::RecordInvalidPayloadAnalytics( - ClientProxy* client, const EndpointIds& endpoint_ids, - std::int64_t payload_id, PayloadType payload_type, std::int64_t offset, - std::int64_t total_size, OperationResultCode operation_result_code) { + ClientProxy* client, const std::vector& endpoint_ids, + int64_t payload_id, PayloadType payload_type, int64_t offset, + int64_t total_size, OperationResultCode operation_result_code) { RecordPayloadStartedAnalytics(client, endpoint_ids, payload_id, payload_type, offset, total_size); @@ -1582,8 +1535,8 @@ bool PayloadManager::EndpointInfo::IsEndpointAvailable( PayloadManager::PendingPayload::PendingPayload( std::unique_ptr internal_payload, - const EndpointIds& endpoint_ids, bool is_incoming, - DestroyCallback destroy_callback) + const std::vector& endpoint_ids, bool is_incoming, + absl::AnyInvocable destroy_callback) : is_incoming_(is_incoming), internal_payload_(std::move(internal_payload)), destroy_callback_(std::move(destroy_callback)) { @@ -1649,7 +1602,7 @@ PayloadManager::EndpointInfo* PayloadManager::PendingPayload::GetEndpoint( } void PayloadManager::PendingPayload::RemoveEndpoints( - const EndpointIds& endpoint_ids) { + const std::vector& endpoint_ids) { MutexLock lock(&mutex_); for (const auto& id : endpoint_ids) { @@ -1669,7 +1622,7 @@ void PayloadManager::PendingPayload::SetEndpointStatusFromControlMessage( } void PayloadManager::PendingPayload::SetOffsetForEndpoint( - const std::string& endpoint_id, std::int64_t offset) { + const std::string& endpoint_id, int64_t offset) { MutexLock lock(&mutex_); auto item = endpoints_.find(endpoint_id); @@ -1783,7 +1736,8 @@ void PayloadManager::PendingPayloads::Release(PendingPayload* payload) { } PayloadManager::PendingPayloadHandle::PendingPayloadHandle( - PendingPayload* payload, DestroyCallback destroy_callback) + PendingPayload* payload, + absl::AnyInvocable destroy_callback) : payload_(payload), destroy_callback_(std::move(destroy_callback)) {} PayloadManager::PendingPayloadHandle::~PendingPayloadHandle() { @@ -1793,9 +1747,8 @@ PayloadManager::PendingPayloadHandle::~PendingPayloadHandle() { } std::string PayloadManager::PendingPayload::ToString() const { - return absl::StrFormat("Payload(%s, %d)", - IsIncoming() ? "incoming" : "outgoing", GetId()); + return absl::StrCat("Payload(", IsIncoming() ? "incoming" : "outgoing", + GetId(), ")"); } -} // namespace connections -} // namespace nearby +} // namespace nearby::connections diff --git a/connections/implementation/payload_manager.h b/connections/implementation/payload_manager.h index 533ee79d..cb4b031d 100644 --- a/connections/implementation/payload_manager.h +++ b/connections/implementation/payload_manager.h @@ -42,8 +42,7 @@ #include "internal/platform/mutex.h" #include "internal/platform/single_thread_executor.h" -namespace nearby { -namespace connections { +namespace nearby::connections { // Annotations for methods that need to run on PayloadStatusUpdateThread. // Use only in PayloadManager @@ -52,13 +51,13 @@ namespace connections { class PayloadManager : public EndpointManager::FrameProcessor { public: - using EndpointIds = std::vector; static constexpr absl::Duration kWaitCloseTimeout = absl::Milliseconds(5000); explicit PayloadManager(EndpointManager& endpoint_manager); ~PayloadManager() override; - void SendPayload(ClientProxy* client, const EndpointIds& endpoint_ids, + void SendPayload(ClientProxy* client, + const std::vector& endpoint_ids, Payload payload); Status CancelPayload(ClientProxy* client, Payload::Id payload_id); @@ -103,7 +102,7 @@ class PayloadManager : public EndpointManager::FrameProcessor { std::string id; AtomicReference status{Status::kUnknown}; - std::int64_t offset = 0; + int64_t offset = 0; mutable Mutex payload_received_ack_mutex; ConditionVariable payload_received_ack_cond{&payload_received_ack_mutex}; bool is_payload_received_ack ABSL_GUARDED_BY(payload_received_ack_mutex) = @@ -113,10 +112,10 @@ class PayloadManager : public EndpointManager::FrameProcessor { // Tracks state for an InternalPayload and the endpoints associated with it. class PendingPayload { public: - using DestroyCallback = absl::AnyInvocable; - PendingPayload(std::unique_ptr internal_payload, - const EndpointIds& endpoint_ids, bool is_incoming, - DestroyCallback destroy_callback); + PendingPayload( + std::unique_ptr internal_payload, + const std::vector& endpoint_ids, bool is_incoming, + absl::AnyInvocable destroy_callback); PendingPayload(PendingPayload&&) = default; PendingPayload& operator=(PendingPayload&&) = default; @@ -146,7 +145,7 @@ class PayloadManager : public EndpointManager::FrameProcessor { ABSL_LOCKS_EXCLUDED(mutex_); // Removes the given endpoints, e.g. on error. - void RemoveEndpoints(const EndpointIds& endpoint_ids_to_remove) + void RemoveEndpoints(const std::vector& endpoint_ids_to_remove) ABSL_LOCKS_EXCLUDED(mutex_); // Sets the status for a particular endpoint. @@ -156,8 +155,8 @@ class PayloadManager : public EndpointManager::FrameProcessor { ControlMessage& control_message) ABSL_LOCKS_EXCLUDED(mutex_); // Sets the offset for a particular endpoint. - void SetOffsetForEndpoint(const std::string& endpoint_id, - std::int64_t offset) ABSL_LOCKS_EXCLUDED(mutex_); + void SetOffsetForEndpoint(const std::string& endpoint_id, int64_t offset) + ABSL_LOCKS_EXCLUDED(mutex_); // Closes internal_payload_. // Close is called when a pending peyload does not have associated @@ -173,11 +172,11 @@ class PayloadManager : public EndpointManager::FrameProcessor { private: mutable Mutex mutex_; - bool is_incoming_; + const bool is_incoming_; AtomicBoolean is_locally_canceled_{false}; AtomicBoolean is_closed_; - std::unique_ptr internal_payload_; - DestroyCallback destroy_callback_; + const std::unique_ptr internal_payload_; + absl::AnyInvocable destroy_callback_; absl::flat_hash_map endpoints_ ABSL_GUARDED_BY(mutex_); int refcount_ = 0; @@ -188,10 +187,10 @@ class PayloadManager : public EndpointManager::FrameProcessor { // Create instances with `GetPayload(Payload::Id)`. class PendingPayloadHandle { public: - using DestroyCallback = absl::AnyInvocable; PendingPayloadHandle() = default; - PendingPayloadHandle(PendingPayload* payload, - DestroyCallback destroy_callback); + PendingPayloadHandle( + PendingPayload* payload, + absl::AnyInvocable destroy_callback); PendingPayloadHandle(const PendingPayloadHandle&) = delete; PendingPayloadHandle(PendingPayloadHandle&& other) { payload_ = other.payload_; @@ -217,7 +216,7 @@ class PayloadManager : public EndpointManager::FrameProcessor { private: PendingPayload* payload_ = nullptr; - DestroyCallback destroy_callback_; + absl::AnyInvocable destroy_callback_; }; // Tracks and manages PendingPayload objects in a synchronized manner. @@ -256,31 +255,26 @@ class PayloadManager : public EndpointManager::FrameProcessor { }; using Endpoints = std::vector; - static std::string ToString(const EndpointIds& endpoint_ids); - static std::string ToString(const Endpoints& endpoints); - static std::string ToString(PayloadType type); static std::string ToString(EndpointInfo::Status status); // Splits the endpoints for this payload by availability. - // Returns a pair of lists of EndpointInfo*, with the first being the list - // of still-available endpoints, and the second for unavailable endpoints. - static std::pair GetAvailableAndUnavailableEndpoints( - const PendingPayload& pending_payload); + // Returns a pair of lists, with the first being the list of still-available + // endpoint ids, and the second for unavailable endpoints. + static std::pair, Endpoints> + GetAvailableAndUnavailableEndpoints(const PendingPayload& pending_payload); - // Converts list of EndpointInfo to list of Endpoint ids. - // Returns list of endpoint ids. - static EndpointIds EndpointsToEndpointIds(const Endpoints& endpoints); - - bool SendPayloadLoop( + // Returns the number of bytes sent. 0 bytes sent indicates end of payload. + // Returns -1 on error. + int SendPayloadLoop( ClientProxy* client, PendingPayload& pending_payload, location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t& next_chunk_offset, size_t resume_offset, int index); + int64_t next_chunk_offset, size_t resume_offset, int index); void SendClientCallbacksForFinishedIncomingPayloadRunnable( ClientProxy* client, const std::string& endpoint_id, const location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t offset_bytes, + int64_t offset_bytes, location::nearby::proto::connections::PayloadStatus status, location::nearby::proto::connections::OperationResultCode operation_result_code); @@ -292,27 +286,14 @@ class PayloadManager : public EndpointManager::FrameProcessor { EndpointInfoStatusToPayloadStatus(EndpointInfo::Status status); static location::nearby::proto::connections::OperationResultCode EndpointInfoStatusToOperationResultCode(EndpointInfo::Status status); - // Converts a ControlMessage::EventType for a particular payload to a - // PayloadStatus. Called when we've received a ControlMessage with this - // event from a remote endpoint; thus the PayloadStatuses are REMOTE_*. - static location::nearby::proto::connections::PayloadStatus - ControlMessageEventToPayloadStatus( - location::nearby::connections::PayloadTransferFrame::ControlMessage:: - EventType event); - static location::nearby::proto::connections::OperationResultCode - ControlMessageEventToOperationResultCode( - location::nearby::connections::PayloadTransferFrame::ControlMessage:: - EventType event); - static PayloadProgressInfo::Status PayloadStatusToTransferUpdateStatus( - location::nearby::proto::connections::PayloadStatus status); - int GetOptimalChunkSize(EndpointIds endpoint_ids); + int GetOptimalChunkSize(const std::vector& endpoint_ids); location::nearby::connections::PayloadTransferFrame::PayloadHeader CreatePayloadHeader(const InternalPayload& internal_payload, size_t offset); location::nearby::connections::PayloadTransferFrame::PayloadChunk - CreatePayloadChunk(std::int64_t offset, ByteArray body, int index); + CreatePayloadChunk(int64_t offset, ByteArray body, int index); bool IsLastChunk( location::nearby::connections::PayloadTransferFrame::PayloadChunk payload_chunk) { @@ -326,18 +307,19 @@ class PayloadManager : public EndpointManager::FrameProcessor { // path set in `SetCustomSavePath()`. ErrorOr CreateIncomingPayload( const location::nearby::connections::PayloadTransferFrame& frame, - const std::string& endpoint_id, - const std::string& save_path) ABSL_LOCKS_EXCLUDED(mutex_); + const std::string& endpoint_id, const std::string& save_path) + ABSL_LOCKS_EXCLUDED(mutex_); - Payload::Id CreateOutgoingPayload(Payload payload, - const EndpointIds& endpoint_ids) + Payload::Id CreateOutgoingPayload( + Payload payload, const std::vector& endpoint_ids) ABSL_LOCKS_EXCLUDED(mutex_); void SendClientCallbacksForFinishedOutgoingPayload( - ClientProxy* client, const EndpointIds& finished_endpoint_ids, + ClientProxy* client, + const std::vector& finished_endpoint_ids, const location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t num_bytes_successfully_transferred, + int64_t num_bytes_successfully_transferred, location::nearby::proto::connections::PayloadStatus status, location::nearby::proto::connections::OperationResultCode operation_result_code); @@ -345,16 +327,16 @@ class PayloadManager : public EndpointManager::FrameProcessor { ClientProxy* client, const std::string& endpoint_id, const location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t offset_bytes, + int64_t offset_bytes, location::nearby::proto::connections::PayloadStatus status, location::nearby::proto::connections::OperationResultCode operation_result_code); void SendControlMessage( - const EndpointIds& endpoint_ids, + const std::vector& endpoint_ids, const location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t num_bytes_successfully_transferred, + int64_t num_bytes_successfully_transferred, location::nearby::connections::PayloadTransferFrame::ControlMessage:: EventType event_type); @@ -368,7 +350,7 @@ class PayloadManager : public EndpointManager::FrameProcessor { PendingPayload& pending_payload, const location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t payload_chunk_offset, bool is_last_chunk); + int64_t payload_chunk_offset, bool is_last_chunk); bool IsPayloadReceivedAckEnabled(ClientProxy* client, const std::string& endpoint_id, PendingPayload& pending_payload); @@ -376,10 +358,11 @@ class PayloadManager : public EndpointManager::FrameProcessor { // Handles a finished outgoing payload for the given endpointIds. All // statuses except for SUCCESS are handled here. void HandleFinishedOutgoingPayload( - ClientProxy* client, const EndpointIds& finished_endpoint_ids, + ClientProxy* client, + const std::vector& finished_endpoint_ids, const location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t num_bytes_successfully_transferred, + int64_t num_bytes_successfully_transferred, location::nearby::proto::connections::OperationResultCode operation_result_code, location::nearby::proto::connections::PayloadStatus status = location:: @@ -388,7 +371,7 @@ class PayloadManager : public EndpointManager::FrameProcessor { ClientProxy* client, const std::string& endpoint_id, const location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, - std::int64_t offset_bytes, + int64_t offset_bytes, location::nearby::proto::connections::PayloadStatus status, location::nearby::proto::connections::OperationResultCode operation_result_code); @@ -397,14 +380,14 @@ class PayloadManager : public EndpointManager::FrameProcessor { ClientProxy* client, const std::string& endpoint_id, const location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, - std::int32_t payload_chunk_flags, std::int64_t payload_chunk_offset, - std::int64_t payload_chunk_body_size); + int32_t payload_chunk_flags, int64_t payload_chunk_offset, + int64_t payload_chunk_body_size); void HandleSuccessfulIncomingChunk( ClientProxy* client, const std::string& endpoint_id, const location::nearby::connections::PayloadTransferFrame::PayloadHeader& payload_header, - std::int32_t payload_chunk_flags, std::int64_t payload_chunk_offset, - std::int64_t payload_chunk_body_size); + int32_t payload_chunk_flags, int64_t payload_chunk_offset, + int64_t payload_chunk_body_size); void ProcessDataPacket(ClientProxy* to_client, const std::string& from_endpoint_id, @@ -436,16 +419,14 @@ class PayloadManager : public EndpointManager::FrameProcessor { ABSL_LOCKS_EXCLUDED(mutex_); void CancelAllPayloads() ABSL_LOCKS_EXCLUDED(mutex_); - void RecordPayloadStartedAnalytics(ClientProxy* client, - const EndpointIds& endpoint_ids, - std::int64_t payload_id, - PayloadType payload_type, - std::int64_t offset, - std::int64_t total_size); + void RecordPayloadStartedAnalytics( + ClientProxy* client, const std::vector& endpoint_ids, + int64_t payload_id, PayloadType payload_type, int64_t offset, + int64_t total_size); void RecordInvalidPayloadAnalytics( - ClientProxy* client, const EndpointIds& endpoint_ids, - std::int64_t payload_id, PayloadType payload_type, std::int64_t offset, - std::int64_t total_size, + ClientProxy* client, const std::vector& endpoint_ids, + int64_t payload_id, PayloadType payload_type, int64_t offset, + int64_t total_size, location::nearby::proto::connections::OperationResultCode operation_result_code); @@ -480,7 +461,6 @@ class PayloadManager : public EndpointManager::FrameProcessor { ABSL_GUARDED_BY(chunk_update_mutex_) = absl::InfinitePast(); }; -} // namespace connections -} // namespace nearby +} // namespace nearby::connections #endif // CORE_INTERNAL_PAYLOAD_MANAGER_H_ diff --git a/connections/payload.cc b/connections/payload.cc index baae0663..88188f27 100644 --- a/connections/payload.cc +++ b/connections/payload.cc @@ -28,9 +28,9 @@ #include "internal/platform/byte_array.h" #include "internal/platform/file.h" #include "internal/platform/input_stream.h" +#include "internal/platform/logging.h" -namespace nearby { -namespace connections { +namespace nearby::connections { namespace { @@ -151,5 +151,4 @@ const std::string& Payload::GetParentFolder() const { return parent_folder_; } const std::string& Payload::GetFileName() const { return file_name_; } -} // namespace connections -} // namespace nearby +} // namespace nearby::connections diff --git a/connections/payload.h b/connections/payload.h index d40b1ba4..17b448d0 100644 --- a/connections/payload.h +++ b/connections/payload.h @@ -15,26 +15,20 @@ #ifndef CORE_PAYLOAD_H_ #define CORE_PAYLOAD_H_ -#include -#include +#include #include #include -#include #include #include "absl/time/clock.h" #include "absl/time/time.h" -#include "absl/types/variant.h" #include "connections/payload_type.h" #include "internal/platform/byte_array.h" #include "internal/platform/file.h" #include "internal/platform/input_stream.h" -#include "internal/platform/logging.h" #include "internal/platform/payload_id.h" -#include "internal/platform/prng.h" -namespace nearby { -namespace connections { +namespace nearby::connections { // Payload is default-constructible, and moveable, but not copyable container // that holds at most one instance of one of: @@ -124,7 +118,6 @@ class Payload { Content content_; }; -} // namespace connections -} // namespace nearby +} // namespace nearby::connections #endif // CORE_PAYLOAD_H_ diff --git a/connections/payload_test.cc b/connections/payload_test.cc index 3c31f762..7b0666c7 100644 --- a/connections/payload_test.cc +++ b/connections/payload_test.cc @@ -21,6 +21,7 @@ #include #include "gtest/gtest.h" +#include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "connections/payload_type.h" #include "internal/platform/byte_array.h" @@ -28,8 +29,7 @@ #include "internal/platform/input_stream.h" #include "internal/platform/pipe.h" -namespace nearby { -namespace connections { +namespace nearby::connections { TEST(PayloadTest, DefaultPayloadHasUnknownType) { Payload payload; @@ -132,5 +132,20 @@ TEST(PayloadTest, PayloadIsNotCopyable) { EXPECT_FALSE(std::is_copy_assignable_v); } -} // namespace connections -} // namespace nearby +TEST(PayloadTypeTest, Stringify) { + EXPECT_EQ(absl::StrCat(PayloadType::kUnknown), "Unknown"); + EXPECT_EQ(absl::StrCat(PayloadType::kBytes), "Bytes"); + EXPECT_EQ(absl::StrCat(PayloadType::kFile), "File"); + EXPECT_EQ(absl::StrCat(PayloadType::kStream), "Stream"); +} + +TEST(PayloadDirectionTest, Stringify) { + EXPECT_EQ(absl::StrCat(PayloadDirection::UNKNOWN_DIRECTION_PAYLOAD), + "UNKNOWN_DIRECTION_PAYLOAD"); + EXPECT_EQ(absl::StrCat(PayloadDirection::INCOMING_PAYLOAD), + "INCOMING_PAYLOAD"); + EXPECT_EQ(absl::StrCat(PayloadDirection::OUTGOING_PAYLOAD), + "OUTGOING_PAYLOAD"); +} + +} // namespace nearby::connections diff --git a/connections/payload_type.h b/connections/payload_type.h index 5efcbb7f..914fc4bb 100644 --- a/connections/payload_type.h +++ b/connections/payload_type.h @@ -16,59 +16,62 @@ #define CORE_PAYLOAD_TYPE_H_ #include +#include "absl/strings/str_cat.h" -namespace nearby { -namespace connections { +namespace nearby::connections { enum class PayloadType { kUnknown = 0, kBytes = 1, kFile = 2, kStream = 3 }; +// Support logging of PayloadType. +template +void AbslStringify(Sink& sink, PayloadType payload_type) { + switch (payload_type) { + case PayloadType::kBytes: + sink.Append("Bytes"); + break; + case PayloadType::kStream: + sink.Append("Stream"); + break; + case PayloadType::kFile: + sink.Append("File"); + break; + case PayloadType::kUnknown: + sink.Append("Unknown"); + break; + } +} + +inline std::ostream& operator<<(std::ostream& os, PayloadType payload_type) { + return os << absl::StrCat(payload_type); +} + enum class PayloadDirection { UNKNOWN_DIRECTION_PAYLOAD = 0, INCOMING_PAYLOAD = 1, OUTGOING_PAYLOAD = 2, }; -inline std::ostream& operator<<(std::ostream& os, PayloadType payload_type) { - switch (payload_type) { - case PayloadType::kUnknown: - os << "kUnknown"; +// Support logging of PayloadDirection. +template +void AbslStringify(Sink& sink, PayloadDirection payload_direction) { + switch (payload_direction) { + case PayloadDirection::UNKNOWN_DIRECTION_PAYLOAD: + sink.Append("UNKNOWN_DIRECTION_PAYLOAD"); break; - case PayloadType::kBytes: - os << "kBytes"; + case PayloadDirection::INCOMING_PAYLOAD: + sink.Append("INCOMING_PAYLOAD"); break; - case PayloadType::kFile: - os << "kFile"; - break; - case PayloadType::kStream: - os << "kStream"; - break; - default: - os << "Invalid PayloadType"; + case PayloadDirection::OUTGOING_PAYLOAD: + sink.Append("OUTGOING_PAYLOAD"); break; } - return os; } inline std::ostream& operator<<(std::ostream& os, - PayloadDirection payload_direction) { - switch (payload_direction) { - case PayloadDirection::UNKNOWN_DIRECTION_PAYLOAD: - os << "UNKNOWN_DIRECTION_PAYLOAD"; - break; - case PayloadDirection::INCOMING_PAYLOAD: - os << "INCOMING_PAYLOAD"; - break; - case PayloadDirection::OUTGOING_PAYLOAD: - os << "OUTGOING_PAYLOAD"; - break; - default: - os << "Invalid PayloadDirection"; - break; - } - return os; + PayloadDirection payload_direction) { + return os << absl::StrCat(payload_direction); } -} // namespace connections -} // namespace nearby +} // namespace nearby::connections #endif // CORE_PAYLOAD_TYPE_H_ From b8dd6b3e27a713c90f6ffff229842ced6c9e3de7 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 8 Jun 2026 14:03:27 -0700 Subject: [PATCH 145/151] Remove unused code. PiperOrigin-RevId: 928758355 --- .../implementation/base_pcp_handler.cc | 26 +--------- .../implementation/base_pcp_handler_test.cc | 4 +- connections/implementation/client_proxy.cc | 50 ------------------- connections/implementation/client_proxy.h | 22 -------- .../implementation/client_proxy_test.cc | 30 ----------- connections/implementation/offline_frames.cc | 5 +- connections/implementation/offline_frames.h | 3 +- .../implementation/offline_frames_test.cc | 5 +- .../offline_frames_validator.cc | 7 --- .../offline_frames_validator_test.cc | 9 ++-- 10 files changed, 12 insertions(+), 149 deletions(-) diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 81bb0181..ae833f73 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -1585,8 +1585,7 @@ Status BasePcpHandler::AcceptConnection(ClientProxy* client, Exception write_exception = channel->Write(parser::ForConnectionResponse( - Status::kSuccess, client->GetLocalOsInfo(), - client->GetLocalMultiplexSocketBitmask())); + Status::kSuccess, client->GetLocalOsInfo())); if (!write_exception.Ok()) { LOG(INFO) << "AcceptConnection: failed to send response: endpoint_id=" << endpoint_id; @@ -1647,8 +1646,7 @@ Status BasePcpHandler::RejectConnection(ClientProxy* client, Exception write_exception = channel->Write(parser::ForConnectionResponse( - Status::kConnectionRejected, client->GetLocalOsInfo(), - client->GetLocalMultiplexSocketBitmask())); + Status::kConnectionRejected, client->GetLocalOsInfo())); if (!write_exception.Ok()) { LOG(INFO) << "RejectConnection: failed to send response: endpoint_id=" << endpoint_id; @@ -2463,26 +2461,6 @@ void BasePcpHandler::EvaluateConnectionResult(ClientProxy* client, std::move(context))) { response_code = {Status::kEndpointUnknown}; } - - std::shared_ptr channel = - channel_manager_->GetChannelForEndpoint(endpoint_id); - if (channel != nullptr) { - if (client->IsMultiplexSocketSupported(endpoint_id, - channel->GetMedium())) { - if (!channel->EnableMultiplexSocket()) { - LOG(INFO) << "MultiplexSocket is not implemented for Medium: " - << location::nearby::proto::connections::Medium_Name( - channel->GetMedium()); - } else { - LOG(INFO) << "MultiplexSocket is supported for Medium: " - << location::nearby::proto::connections::Medium_Name( - channel->GetMedium()) - << " on both sides."; - } - } - } else { - LOG(INFO) << "channel is null"; - } } else { LOG(INFO) << "Pending connection rejected; endpoint_id=" << endpoint_id; response_code = {Status::kConnectionRejected}; diff --git a/connections/implementation/base_pcp_handler_test.cc b/connections/implementation/base_pcp_handler_test.cc index b8cef7e5..93f29a5e 100644 --- a/connections/implementation/base_pcp_handler_test.cc +++ b/connections/implementation/base_pcp_handler_test.cc @@ -1609,8 +1609,8 @@ TEST_P(BasePcpHandlerTest, OnIncomingFrameChangesState) { Status{Status::kSuccess}); LOG(INFO) << "Simulating remote accept: id=" << endpoint_id; OsInfo os_info; - auto frame = parser::FromBytes(parser::ForConnectionResponse( - Status::kSuccess, os_info, /*multiplex_socket_bitmask=*/0)); + auto frame = parser::FromBytes( + parser::ForConnectionResponse(Status::kSuccess, os_info)); EXPECT_CALL(mock_connection_listener_.bandwidth_changed_cb, Call).Times(1); pcp_handler.OnIncomingFrame(frame.result(), endpoint_id, client_.get(), connect_medium); diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index f9890267..aa6c4557 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -1365,11 +1365,6 @@ OsInfo::OsType ClientProxy::OSNameToOsInfoType(api::OSName osName) { } } -std::int32_t ClientProxy::GetLocalMultiplexSocketBitmask() const { - MutexLock lock(&mutex_); - return 0; -} - void ClientProxy::SetRemoteMultiplexSocketBitmask( absl::string_view endpoint_id, int remote_multiplex_socket_bitmask) { MutexLock lock(&mutex_); @@ -1382,51 +1377,6 @@ void ClientProxy::SetRemoteMultiplexSocketBitmask( } } -bool ClientProxy::IsLocalMultiplexSocketSupported(Medium medium) { - MutexLock lock(&mutex_); - int bitmask = GetLocalMultiplexSocketBitmask(); - switch (medium) { - case Medium::BLUETOOTH: - LOG(INFO) << "ClientProxy [IsLocalMultiplexSocketSupported]: " - << (bitmask & kBtMultiplexEnabled); - return (bitmask & kBtMultiplexEnabled) != 0; - case Medium::WIFI_LAN: - return (bitmask & kWifiLanMultiplexEnabled) != 0; - default: - return false; - } -} - -std::optional ClientProxy::GetRemoteMultiplexSocketBitmask( - absl::string_view endpoint_id) const { - MutexLock lock(&mutex_); - const ConnectionPair* item = LookupConnection(endpoint_id); - if (item != nullptr) { - return item->first.remote_multiplex_socket_bitmask; - } - return std::nullopt; -} - -bool ClientProxy::IsMultiplexSocketSupported(absl::string_view endpoint_id, - Medium medium) { - MutexLock lock(&mutex_); - ConnectionPair* item = LookupConnection(endpoint_id); - if (item == nullptr) { - return false; - } - int combined_result = GetLocalMultiplexSocketBitmask() & - item->first.remote_multiplex_socket_bitmask; - - switch (medium) { - case Medium::BLUETOOTH: - return (combined_result & kBtMultiplexEnabled) != 0; - case Medium::WIFI_LAN: - return (combined_result & kWifiLanMultiplexEnabled) != 0; - default: - return false; - } -} - bool ClientProxy::GetWebRtcNonCellular() { MutexLock lock(&mutex_); return webrtc_non_cellular_; diff --git a/connections/implementation/client_proxy.h b/connections/implementation/client_proxy.h index c5400fe5..e40ba901 100644 --- a/connections/implementation/client_proxy.h +++ b/connections/implementation/client_proxy.h @@ -309,19 +309,9 @@ class ClientProxy final { bool IsSafeToDisconnectEnabled(absl::string_view endpoint_id); bool IsPayloadReceivedAckEnabled(absl::string_view endpoint_id); - // Returns the multiplex socket supports status for local device. - std::int32_t GetLocalMultiplexSocketBitmask() const; // Sets the multiplex socket supports status for remote device. void SetRemoteMultiplexSocketBitmask(absl::string_view endpoint_id, int remote_multiplex_socket_bitmask); - // Returns true if the multiplex socket is supported for the given medium. - bool IsLocalMultiplexSocketSupported(Medium medium); - - // Gets the multiplex socket supports status for remote device. - std::optional GetRemoteMultiplexSocketBitmask( - absl::string_view endpoint_id) const; - // Returns true if the multiplex socket is supported for the given medium. - bool IsMultiplexSocketSupported(absl::string_view endpoint_id, Medium medium); // Gets the WebRTC non cellular network status. bool GetWebRtcNonCellular(); @@ -343,18 +333,6 @@ class ClientProxy final { std::optional GetMediumRole( absl::string_view endpoint_id) const; - /** Bitmask for bt multiplex connection support. */ - // Note. Deprecates the first and second bit of BT_MULTIPLEX_ENABLED and - // WIFI_LAN_MULTIPLEX_ENABLED and shift them to the third and the forth bit. - // The reason is we need to escape the (0, 1) bit which has been set in some - // devices without salt enabled. If accompany with the devices with salted - // enabled, the frames passed cannot be decrypted and the connection shall be - // failed. Please refer to b/295925531#comment#14 for the details. - enum MultiplexSocketBitmask : uint32_t { - kBtMultiplexEnabled = 1 << 2, - kWifiLanMultiplexEnabled = 1 << 3, - }; - // Forces client to regenerate a new local endpoint id. void ClearCachedLocalEndpointId(); diff --git a/connections/implementation/client_proxy_test.cc b/connections/implementation/client_proxy_test.cc index d54a236b..2e3a5ac6 100644 --- a/connections/implementation/client_proxy_test.cc +++ b/connections/implementation/client_proxy_test.cc @@ -61,9 +61,6 @@ namespace connections { namespace { using ::location::nearby::connections::OsInfo; -using ::location::nearby::proto::connections::CLIENT_SESSION; -using ::location::nearby::proto::connections::START_CLIENT_SESSION; -using ::location::nearby::proto::connections::STOP_CLIENT_SESSION; using ::testing::_; using ::testing::IsEmpty; using ::testing::MockFunction; @@ -1501,33 +1498,6 @@ TEST_F(ClientProxyTest, TestAutoBwuWhenListeningWithAutoBwu) { EXPECT_TRUE(client1()->AutoUpgradeBandwidth()); } -TEST_F(ClientProxyTest, TestMultiplexSocketBitmask) { - EXPECT_EQ(client1()->GetLocalMultiplexSocketBitmask(), 0); -} - -TEST_F(ClientProxyTest, TestRemoteMultiplexSocketBitmask) { - Endpoint advertising_endpoint = - StartAdvertising(client1(), advertising_connection_listener_); - OnAdvertisingConnectionInitiated(client1(), advertising_endpoint); - client1()->SetRemoteMultiplexSocketBitmask( - advertising_endpoint.id, - ClientProxy::kBtMultiplexEnabled | ClientProxy::kWifiLanMultiplexEnabled); - ASSERT_TRUE(client1() - ->GetRemoteMultiplexSocketBitmask(advertising_endpoint.id) - .has_value()); - EXPECT_EQ( - client1() - ->GetRemoteMultiplexSocketBitmask(advertising_endpoint.id) - .value(), - ClientProxy::kBtMultiplexEnabled | ClientProxy::kWifiLanMultiplexEnabled); - EXPECT_FALSE(client1()->IsMultiplexSocketSupported(advertising_endpoint.id, - Medium::BLUETOOTH)); - EXPECT_FALSE(client1()->IsMultiplexSocketSupported(advertising_endpoint.id, - Medium::WIFI_LAN)); - EXPECT_FALSE(client1()->IsMultiplexSocketSupported(advertising_endpoint.id, - Medium::WIFI_AWARE)); -} - TEST_F(ClientProxyTest, SaveClientInfoFromPreferences) { NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature:: diff --git a/connections/implementation/offline_frames.cc b/connections/implementation/offline_frames.cc index aef8c3dd..cf92803f 100644 --- a/connections/implementation/offline_frames.cc +++ b/connections/implementation/offline_frames.cc @@ -180,8 +180,7 @@ std::string ForConnectionRequestPresence( return frame.SerializeAsString(); } -std::string ForConnectionResponse(std::int32_t status, const OsInfo& os_info, - std::int32_t multiplex_socket_bitmask) { +std::string ForConnectionResponse(std::int32_t status, const OsInfo& os_info) { OfflineFrame frame; frame.set_version(OfflineFrame::V1); @@ -197,7 +196,7 @@ std::string ForConnectionResponse(std::int32_t status, const OsInfo& os_info, ? ConnectionResponseFrame::ACCEPT : ConnectionResponseFrame::REJECT); *sub_frame->mutable_os_info() = os_info; - sub_frame->set_multiplex_socket_bitmask(multiplex_socket_bitmask); + sub_frame->set_multiplex_socket_bitmask(0); sub_frame->set_safe_to_disconnect_version( NearbyFlags::GetInstance().GetInt64Flag( config_package_nearby::nearby_connections_feature:: diff --git a/connections/implementation/offline_frames.h b/connections/implementation/offline_frames.h index bf7248b7..d56dba36 100644 --- a/connections/implementation/offline_frames.h +++ b/connections/implementation/offline_frames.h @@ -59,8 +59,7 @@ std::string ForConnectionRequestPresence( const location::nearby::connections::PresenceDevice& proto_presence_device, const ConnectionInfo& connection_info); std::string ForConnectionResponse( - std::int32_t status, const location::nearby::connections::OsInfo& os_info, - std::int32_t multiplex_socket_bitmask); + std::int32_t status, const location::nearby::connections::OsInfo& os_info); // Builds Payload transfer messages. std::string ForDataPayloadTransfer( diff --git a/connections/implementation/offline_frames_test.cc b/connections/implementation/offline_frames_test.cc index 10fc9f07..022673b2 100644 --- a/connections/implementation/offline_frames_test.cc +++ b/connections/implementation/offline_frames_test.cc @@ -350,7 +350,7 @@ TEST(OfflineFramesTest, CanGenerateConnectionResponse) { status: 1 response: REJECT os_info { type: LINUX } - multiplex_socket_bitmask: 0x01 + multiplex_socket_bitmask: 0 safe_to_disconnect_version: 5 > >)pb"; @@ -361,8 +361,7 @@ TEST(OfflineFramesTest, CanGenerateConnectionResponse) { config_package_nearby::nearby_connections_feature:: kSafeToDisconnectVersion, 5); - auto response = FromBytes( - ForConnectionResponse(1, os_info, /*multiplex_socket_bitmask=*/0x01)); + auto response = FromBytes(ForConnectionResponse(1, os_info)); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); EXPECT_THAT(message, EqualsProto(kExpected)); diff --git a/connections/implementation/offline_frames_validator.cc b/connections/implementation/offline_frames_validator.cc index 813d0b87..786bcb3c 100644 --- a/connections/implementation/offline_frames_validator.cc +++ b/connections/implementation/offline_frames_validator.cc @@ -56,13 +56,6 @@ constexpr absl::string_view kIpv4PatternString{ "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"}; -constexpr absl::string_view kIpv6PatternString{ - "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." - "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." - "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." - "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." - "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." - "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"}; constexpr absl::string_view kWifiDirectSsidPatternString{ "^DIRECT-[a-zA-Z0-9]{2}.*$"}; constexpr int kWifiDirectSsidMaxLength = 32; diff --git a/connections/implementation/offline_frames_validator_test.cc b/connections/implementation/offline_frames_validator_test.cc index 0a1376d7..b20cbc5b 100644 --- a/connections/implementation/offline_frames_validator_test.cc +++ b/connections/implementation/offline_frames_validator_test.cc @@ -179,8 +179,7 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; OsInfo os_info; - std::string bytes = ForConnectionResponse(kStatusAccepted, os_info, - /*multiplex_socket_bitmask=*/0); + std::string bytes = ForConnectionResponse(kStatusAccepted, os_info); offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -193,8 +192,7 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; OsInfo os_info; - std::string bytes = ForConnectionResponse(kStatusAccepted, os_info, - /*multiplex_socket_bitmask=*/0); + std::string bytes = ForConnectionResponse(kStatusAccepted, os_info); offline_frame.ParseFromString(bytes); auto* v1_frame = offline_frame.mutable_v1(); @@ -210,8 +208,7 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; OsInfo os_info; - std::string bytes = - ForConnectionResponse(-1, os_info, /*multiplex_socket_bitmask=*/0); + std::string bytes = ForConnectionResponse(-1, os_info); offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); From 1f7408b33a628f7ee501556dcc46354430206e7d Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 8 Jun 2026 15:29:00 -0700 Subject: [PATCH 146/151] Refresh public certificates after successful pairing. PiperOrigin-RevId: 928803074 --- sharing/nearby_sharing_service_impl.cc | 3 +++ sharing/nearby_sharing_service_impl_test.cc | 2 ++ 2 files changed, 5 insertions(+) diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 27575d31..03fb483b 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -2690,6 +2690,9 @@ void NearbySharingServiceImpl::OnPeerSyncBindingComplete( .set_binding_id(binding_id) .set_status(TransferMetadata::Status::kComplete) .build()); + + // Download public certificates again to update the newly added sync binding. + certificate_manager_->DownloadPublicCertificates(); } void NearbySharingServiceImpl::OnReceivedIntroduction( diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index 23d3c1e8..6814ec81 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -5219,6 +5219,8 @@ TEST_F(NearbySharingServiceImplTest, InitiatePairingSuccess) { EXPECT_FALSE( fake_nearby_connections_manager_->connection_endpoint_info(kEndpointId) .has_value()); + // Once from RegisterSendSurface and once from OnPeerSyncBindingComplete. + EXPECT_EQ(certificate_manager()->num_download_public_certificates_calls(), 2); std::optional binding = preference_manager_.GetSyncBindingValue(); From 7d647f8a85191fe739a5a8d34f503931a05620db Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 9 Jun 2026 19:46:36 -0700 Subject: [PATCH 147/151] internal PiperOrigin-RevId: 929547374 --- sharing/flags/generated/nearby_sharing_feature_flags.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sharing/flags/generated/nearby_sharing_feature_flags.h b/sharing/flags/generated/nearby_sharing_feature_flags.h index 25beaeb5..6e61e601 100755 --- a/sharing/flags/generated/nearby_sharing_feature_flags.h +++ b/sharing/flags/generated/nearby_sharing_feature_flags.h @@ -98,9 +98,6 @@ constexpr auto kEnableMiniPulse = // When true, enables notifications implemented in native code. constexpr auto kEnableNativeNotifications = flags::Flag(kConfigPackage, "45743135", false); -// When true, enables responsive UI. -constexpr auto kEnableResponsiveUi = - flags::Flag(kConfigPackage, "45727212", true); inline absl::btree_map&> GetBoolFlags() { return { @@ -120,7 +117,6 @@ inline absl::btree_map&> GetBoolFlags() { {45720206, kEnableFlutterHooks}, {45724244, kEnableMiniPulse}, {45743135, kEnableNativeNotifications}, - {45727212, kEnableResponsiveUi}, }; } From e205d8a08f133d0bf61bce2f4e2eb45dfdbef3f2 Mon Sep 17 00:00:00 2001 From: edwinwugoog <94415942+edwinwugoog@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:25:28 -0700 Subject: [PATCH 148/151] =?UTF-8?q?PR=20#4395:=20Update=20proto=20definiti?= =?UTF-8?q?ons=20-=20offline=5Fwire=5Fformats.proto=20and=20connections?= =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Imported from GitHub PR https://github.com/google/nearby/pull/4395 …_enums.proto for WiFi Direct ## Summary Update proto definitions - offline_wire_formats.proto and connections_enums.proto for WiFi Direct ## How did you test this change? on test only update the proto definitions. Copybara import of the project: -- 71aa603d4557652d87667455dc3233b8f7fd262a by Edwin Wu : Update proto definitions - offline_wire_formats.proto and connections_enums.proto for WiFi Direct Merging this change closes #4395 PiperOrigin-RevId: 929606397 --- .../proto/offline_wire_formats.pb.cc | 121 +- .../proto/offline_wire_formats.pb.h | 131 ++- compiled_proto/proto/connections_enums.pb.cc | 1026 +++++++++-------- compiled_proto/proto/connections_enums.pb.h | 50 +- .../proto/offline_wire_formats.proto | 16 +- proto/connections_enums.proto | 7 +- 6 files changed, 818 insertions(+), 533 deletions(-) diff --git a/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.cc b/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.cc index 5c907238..2da3e87d 100644 --- a/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.cc +++ b/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.cc @@ -562,6 +562,9 @@ inline constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCred pin_( &::google::protobuf::internal::fixed_address_empty_string, ::_pbi::ConstantInitialized()), + device_name_( + &::google::protobuf::internal::fixed_address_empty_string, + ::_pbi::ConstantInitialized()), port_{0}, frequency_{0} {} @@ -2056,44 +2059,47 @@ bool AutoReconnectFrame_EventType_Parse(::absl::string_view name, AutoReconnectF return success; } PROTOBUF_CONSTINIT const uint32_t MediumMetadata_WifiDirectAuthType_internal_data_[] = { - 196608u, 0u, }; + 262144u, 0u, }; static ::google::protobuf::internal::ExplicitlyConstructed<::std::string> - MediumMetadata_WifiDirectAuthType_strings[3] = {}; + MediumMetadata_WifiDirectAuthType_strings[4] = {}; static const char MediumMetadata_WifiDirectAuthType_names[] = { "WIFI_DIRECT_TYPE_UNKNOWN" + "WIFI_DIRECT_WITH_DEVICE_NAME" "WIFI_DIRECT_WITH_PASSWORD" "WIFI_DIRECT_WITH_PIN" }; static const ::google::protobuf::internal::EnumEntry MediumMetadata_WifiDirectAuthType_entries[] = { {{&MediumMetadata_WifiDirectAuthType_names[0], 24}, 0}, - {{&MediumMetadata_WifiDirectAuthType_names[24], 25}, 1}, - {{&MediumMetadata_WifiDirectAuthType_names[49], 20}, 2}, + {{&MediumMetadata_WifiDirectAuthType_names[24], 28}, 3}, + {{&MediumMetadata_WifiDirectAuthType_names[52], 25}, 1}, + {{&MediumMetadata_WifiDirectAuthType_names[77], 20}, 2}, }; static const int MediumMetadata_WifiDirectAuthType_entries_by_number[] = { 0, // 0 -> WIFI_DIRECT_TYPE_UNKNOWN - 1, // 1 -> WIFI_DIRECT_WITH_PASSWORD - 2, // 2 -> WIFI_DIRECT_WITH_PIN + 2, // 1 -> WIFI_DIRECT_WITH_PASSWORD + 3, // 2 -> WIFI_DIRECT_WITH_PIN + 1, // 3 -> WIFI_DIRECT_WITH_DEVICE_NAME }; const ::std::string& MediumMetadata_WifiDirectAuthType_Name(MediumMetadata_WifiDirectAuthType value) { static const bool kDummy = ::google::protobuf::internal::InitializeEnumStrings( - MediumMetadata_WifiDirectAuthType_entries, MediumMetadata_WifiDirectAuthType_entries_by_number, 3, + MediumMetadata_WifiDirectAuthType_entries, MediumMetadata_WifiDirectAuthType_entries_by_number, 4, MediumMetadata_WifiDirectAuthType_strings); (void)kDummy; int idx = ::google::protobuf::internal::LookUpEnumName(MediumMetadata_WifiDirectAuthType_entries, MediumMetadata_WifiDirectAuthType_entries_by_number, - 3, value); + 4, value); return idx == -1 ? ::google::protobuf::internal::GetEmptyString() : MediumMetadata_WifiDirectAuthType_strings[idx].get(); } bool MediumMetadata_WifiDirectAuthType_Parse(::absl::string_view name, MediumMetadata_WifiDirectAuthType* PROTOBUF_NONNULL value) { int int_value; bool success = ::google::protobuf::internal::LookUpEnumValue( - MediumMetadata_WifiDirectAuthType_entries, 3, name, &int_value); + MediumMetadata_WifiDirectAuthType_entries, 4, name, &int_value); if (success) { *value = static_cast(int_value); } @@ -7696,7 +7702,8 @@ PROTOBUF_NDEBUG_INLINE BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDire gateway_(arena, from.gateway_, _i_give_permission_to_break_this_code_default_gateway_), ip_v6_address_(arena, from.ip_v6_address_), service_name_(arena, from.service_name_), - pin_(arena, from.pin_) {} + pin_(arena, from.pin_), + device_name_(arena, from.device_name_) {} BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, @@ -7730,7 +7737,8 @@ PROTOBUF_NDEBUG_INLINE BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDire gateway_(arena, Impl_::_i_give_permission_to_break_this_code_default_gateway_), ip_v6_address_(arena), service_name_(arena), - pin_(arena) {} + pin_(arena), + device_name_(arena) {} inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { new (&_impl_) Impl_(internal_visibility(), arena); @@ -7758,6 +7766,7 @@ inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia this_._impl_.ip_v6_address_.Destroy(); this_._impl_.service_name_.Destroy(); this_._impl_.pin_.Destroy(); + this_._impl_.device_name_.Destroy(); this_._impl_.~Impl_(); } @@ -7801,16 +7810,16 @@ BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::GetClass return BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials_class_data_.base(); } PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 -const ::_pbi::TcParseTable<3, 8, 0, 0, 2> +const ::_pbi::TcParseTable<4, 9, 0, 0, 2> BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_table_ = { { PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_._has_bits_), 0, // no _extensions_ - 8, 56, // max_field_number, fast_idx_mask + 9, 120, // max_field_number, fast_idx_mask offsetof(decltype(_table_), field_lookup_table), - 4294967040, // skipmap + 4294966784, // skipmap offsetof(decltype(_table_), field_entries), - 8, // num_field_entries + 9, // num_field_entries 0, // num_aux_entries offsetof(decltype(_table_), field_names), // no aux_entries BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials_class_data_.base(), @@ -7820,10 +7829,7 @@ BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_table_ ::_pbi::TcParser::GetTable<::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials>(), // to_prefetch #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ - // optional string pin = 8; - {::_pbi::TcParser::FastBS1, - {66, 5, 0, - PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.pin_)}}, + {::_pbi::TcParser::MiniParse, {}}, // optional string ssid = 1; {::_pbi::TcParser::FastBS1, {10, 0, 0, @@ -7834,11 +7840,11 @@ BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_table_ PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.password_)}}, // optional int32 port = 3; {::_pbi::TcParser::FastV32S1, - {24, 6, 0, + {24, 7, 0, PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.port_)}}, // optional int32 frequency = 4; {::_pbi::TcParser::FastV32S1, - {32, 7, 0, + {32, 8, 0, PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.frequency_)}}, // optional string gateway = 5 [default = "0.0.0.0"]; {::_pbi::TcParser::FastBS1, @@ -7848,10 +7854,24 @@ BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_table_ {::_pbi::TcParser::FastBS1, {50, 3, 0, PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.ip_v6_address_)}}, - // optional string service_name = 7; + // optional string service_name = 7 [deprecated = true]; {::_pbi::TcParser::FastBS1, {58, 4, 0, PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.service_name_)}}, + // optional string pin = 8; + {::_pbi::TcParser::FastBS1, + {66, 5, 0, + PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.pin_)}}, + // optional string device_name = 9; + {::_pbi::TcParser::FastBS1, + {74, 6, 0, + PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.device_name_)}}, + {::_pbi::TcParser::MiniParse, {}}, + {::_pbi::TcParser::MiniParse, {}}, + {::_pbi::TcParser::MiniParse, {}}, + {::_pbi::TcParser::MiniParse, {}}, + {::_pbi::TcParser::MiniParse, {}}, + {::_pbi::TcParser::MiniParse, {}}, }}, {{ 65535, 65535 }}, {{ @@ -7860,17 +7880,19 @@ BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_table_ // optional string password = 2; {PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.password_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // optional int32 port = 3; - {PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.port_), _Internal::kHasBitsOffset + 6, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, + {PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.port_), _Internal::kHasBitsOffset + 7, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, // optional int32 frequency = 4; - {PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.frequency_), _Internal::kHasBitsOffset + 7, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, + {PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.frequency_), _Internal::kHasBitsOffset + 8, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, // optional string gateway = 5 [default = "0.0.0.0"]; {PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.gateway_), _Internal::kHasBitsOffset + 2, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // optional bytes ip_v6_address = 6; {PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.ip_v6_address_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, - // optional string service_name = 7; + // optional string service_name = 7 [deprecated = true]; {PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.service_name_), _Internal::kHasBitsOffset + 4, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // optional string pin = 8; {PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.pin_), _Internal::kHasBitsOffset + 5, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, + // optional string device_name = 9; + {PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.device_name_), _Internal::kHasBitsOffset + 6, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, }}, // no aux_entries {{ @@ -7884,7 +7906,7 @@ PROTOBUF_NOINLINE void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDire (void) cached_has_bits; cached_has_bits = _impl_._has_bits_[0]; - if (BatchCheckHasBit(cached_has_bits, 0x0000003fU)) { + if (BatchCheckHasBit(cached_has_bits, 0x0000007fU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { _impl_.ssid_.ClearNonDefaultToEmpty(); } @@ -7903,12 +7925,12 @@ PROTOBUF_NOINLINE void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDire if (CheckHasBit(cached_has_bits, 0x00000020U)) { _impl_.pin_.ClearNonDefaultToEmpty(); } + if (CheckHasBit(cached_has_bits, 0x00000040U)) { + _impl_.device_name_.ClearNonDefaultToEmpty(); + } } - if (BatchCheckHasBit(cached_has_bits, 0x000000c0U)) { - ::memset(&_impl_.port_, 0, static_cast<::size_t>( - reinterpret_cast(&_impl_.frequency_) - - reinterpret_cast(&_impl_.port_)) + sizeof(_impl_.frequency_)); - } + _impl_.port_ = 0; + _impl_.frequency_ = 0; _impl_._has_bits_.Clear(); _internal_metadata_.Clear<::std::string>(); } @@ -7945,14 +7967,14 @@ PROTOBUF_NOINLINE void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDire } // optional int32 port = 3; - if (CheckHasBit(cached_has_bits, 0x00000040U)) { + if (CheckHasBit(cached_has_bits, 0x00000080U)) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArrayWithField<3>( stream, this_._internal_port(), target); } // optional int32 frequency = 4; - if (CheckHasBit(cached_has_bits, 0x00000080U)) { + if (CheckHasBit(cached_has_bits, 0x00000100U)) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArrayWithField<4>( stream, this_._internal_frequency(), target); @@ -7970,7 +7992,7 @@ PROTOBUF_NOINLINE void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDire target = stream->WriteBytesMaybeAliased(6, _s, target); } - // optional string service_name = 7; + // optional string service_name = 7 [deprecated = true]; if (CheckHasBit(cached_has_bits, 0x00000010U)) { const ::std::string& _s = this_._internal_service_name(); target = stream->WriteStringMaybeAliased(7, _s, target); @@ -7982,6 +8004,12 @@ PROTOBUF_NOINLINE void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDire target = stream->WriteStringMaybeAliased(8, _s, target); } + // optional string device_name = 9; + if (CheckHasBit(cached_has_bits, 0x00000040U)) { + const ::std::string& _s = this_._internal_device_name(); + target = stream->WriteStringMaybeAliased(9, _s, target); + } + if (ABSL_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) { target = stream->WriteRaw( this_._internal_metadata_.unknown_fields<::std::string>(::google::protobuf::internal::GetEmptyString).data(), @@ -8028,7 +8056,7 @@ PROTOBUF_NOINLINE void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDire total_size += 1 + ::google::protobuf::internal::WireFormatLite::BytesSize( this_._internal_ip_v6_address()); } - // optional string service_name = 7; + // optional string service_name = 7 [deprecated = true]; if (CheckHasBit(cached_has_bits, 0x00000010U)) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( this_._internal_service_name()); @@ -8038,13 +8066,20 @@ PROTOBUF_NOINLINE void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDire total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( this_._internal_pin()); } - // optional int32 port = 3; + // optional string device_name = 9; if (CheckHasBit(cached_has_bits, 0x00000040U)) { + total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( + this_._internal_device_name()); + } + // optional int32 port = 3; + if (CheckHasBit(cached_has_bits, 0x00000080U)) { total_size += ::_pbi::WireFormatLite::Int32SizePlusOne( this_._internal_port()); } + } + { // optional int32 frequency = 4; - if (CheckHasBit(cached_has_bits, 0x00000080U)) { + if (CheckHasBit(cached_has_bits, 0x00000100U)) { total_size += ::_pbi::WireFormatLite::Int32SizePlusOne( this_._internal_frequency()); } @@ -8090,12 +8125,15 @@ void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::Mer _this->_internal_set_pin(from._internal_pin()); } if (CheckHasBit(cached_has_bits, 0x00000040U)) { - _this->_impl_.port_ = from._impl_.port_; + _this->_internal_set_device_name(from._internal_device_name()); } if (CheckHasBit(cached_has_bits, 0x00000080U)) { - _this->_impl_.frequency_ = from._impl_.frequency_; + _this->_impl_.port_ = from._impl_.port_; } } + if (CheckHasBit(cached_has_bits, 0x00000100U)) { + _this->_impl_.frequency_ = from._impl_.frequency_; + } _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::std::string>( from._internal_metadata_); @@ -8121,6 +8159,7 @@ void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::Int ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.ip_v6_address_, &other->_impl_.ip_v6_address_, arena); ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.service_name_, &other->_impl_.service_name_, arena); ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.pin_, &other->_impl_.pin_, arena); + ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.device_name_, &other->_impl_.device_name_, arena); ::google::protobuf::internal::memswap< PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, _impl_.frequency_) + sizeof(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_impl_.frequency_) @@ -13302,7 +13341,7 @@ MediumMetadata::_table_ = { PROTOBUF_FIELD_OFFSET(MediumMetadata, _impl_.medium_role_)}}, // repeated .location.nearby.connections.MediumMetadata.WifiDirectAuthType supported_wifi_direct_auth_types = 13 [packed = true]; {::_pbi::TcParser::FastEr0P1, - {106, 0, 2, + {106, 0, 3, PROTOBUF_FIELD_OFFSET(MediumMetadata, _impl_.supported_wifi_direct_auth_types_)}}, {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, @@ -13343,7 +13382,7 @@ MediumMetadata::_table_ = { {::_pbi::TcParser::GetTable<::location::nearby::connections::WifiAwareUsableChannels>()}, {::_pbi::TcParser::GetTable<::location::nearby::connections::WifiHotspotStaUsableChannels>()}, {::_pbi::TcParser::GetTable<::location::nearby::connections::MediumRole>()}, - {0, 2}, + {0, 3}, }}, {{ }}, diff --git a/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.h b/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.h index 9c8cf9cb..4441f499 100644 --- a/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.h +++ b/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.h @@ -722,18 +722,19 @@ bool AutoReconnectFrame_EventType_Parse( enum MediumMetadata_WifiDirectAuthType : int { MediumMetadata_WifiDirectAuthType_WIFI_DIRECT_TYPE_UNKNOWN = 0, MediumMetadata_WifiDirectAuthType_WIFI_DIRECT_WITH_PASSWORD = 1, - MediumMetadata_WifiDirectAuthType_WIFI_DIRECT_WITH_PIN = 2, + MediumMetadata_WifiDirectAuthType_WIFI_DIRECT_WITH_PIN [[deprecated]] = 2, + MediumMetadata_WifiDirectAuthType_WIFI_DIRECT_WITH_DEVICE_NAME = 3, }; extern const uint32_t MediumMetadata_WifiDirectAuthType_internal_data_[]; inline constexpr MediumMetadata_WifiDirectAuthType MediumMetadata_WifiDirectAuthType_WifiDirectAuthType_MIN = static_cast(0); inline constexpr MediumMetadata_WifiDirectAuthType MediumMetadata_WifiDirectAuthType_WifiDirectAuthType_MAX = - static_cast(2); + static_cast(3); inline bool MediumMetadata_WifiDirectAuthType_IsValid(int value) { - return 0 <= value && value <= 2; + return 0 <= value && value <= 3; } -inline constexpr int MediumMetadata_WifiDirectAuthType_WifiDirectAuthType_ARRAYSIZE = 2 + 1; +inline constexpr int MediumMetadata_WifiDirectAuthType_WifiDirectAuthType_ARRAYSIZE = 3 + 1; const ::std::string& MediumMetadata_WifiDirectAuthType_Name(MediumMetadata_WifiDirectAuthType value); template const ::std::string& MediumMetadata_WifiDirectAuthType_Name(T value) { @@ -4914,6 +4915,7 @@ class BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials fin kIpV6AddressFieldNumber = 6, kServiceNameFieldNumber = 7, kPinFieldNumber = 8, + kDeviceNameFieldNumber = 9, kPortFieldNumber = 3, kFrequencyFieldNumber = 4, }; @@ -4981,15 +4983,15 @@ class BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials fin ::std::string* PROTOBUF_NONNULL _internal_mutable_ip_v6_address(); public: - // optional string service_name = 7; - bool has_service_name() const; - void clear_service_name() ; - const ::std::string& service_name() const; + // optional string service_name = 7 [deprecated = true]; + [[deprecated]] bool has_service_name() const; + [[deprecated]] void clear_service_name() ; + [[deprecated]] const ::std::string& service_name() const; template - void set_service_name(Arg_&& arg, Args_... args); - ::std::string* PROTOBUF_NONNULL mutable_service_name(); - [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_service_name(); - void set_allocated_service_name(::std::string* PROTOBUF_NULLABLE value); + [[deprecated]] void set_service_name(Arg_&& arg, Args_... args); + [[deprecated]] ::std::string* PROTOBUF_NONNULL mutable_service_name(); + [[deprecated]] [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_service_name(); + [[deprecated]] void set_allocated_service_name(::std::string* PROTOBUF_NULLABLE value); private: const ::std::string& _internal_service_name() const; @@ -5012,6 +5014,22 @@ class BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials fin PROTOBUF_ALWAYS_INLINE void _internal_set_pin(const ::std::string& value); ::std::string* PROTOBUF_NONNULL _internal_mutable_pin(); + public: + // optional string device_name = 9; + bool has_device_name() const; + void clear_device_name() ; + const ::std::string& device_name() const; + template + void set_device_name(Arg_&& arg, Args_... args); + ::std::string* PROTOBUF_NONNULL mutable_device_name(); + [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_device_name(); + void set_allocated_device_name(::std::string* PROTOBUF_NULLABLE value); + + private: + const ::std::string& _internal_device_name() const; + PROTOBUF_ALWAYS_INLINE void _internal_set_device_name(const ::std::string& value); + ::std::string* PROTOBUF_NONNULL _internal_mutable_device_name(); + public: // optional int32 port = 3; bool has_port() const; @@ -5039,7 +5057,7 @@ class BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials fin private: class _Internal; friend class ::google::protobuf::internal::TcParser; - static const ::google::protobuf::internal::TcParseTable<3, 8, + static const ::google::protobuf::internal::TcParseTable<4, 9, 0, 0, 2> _table_; @@ -5068,6 +5086,7 @@ class BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials fin ::google::protobuf::internal::ArenaStringPtr ip_v6_address_; ::google::protobuf::internal::ArenaStringPtr service_name_; ::google::protobuf::internal::ArenaStringPtr pin_; + ::google::protobuf::internal::ArenaStringPtr device_name_; ::int32_t port_; ::int32_t frequency_; PROTOBUF_TSAN_DECLARE_MEMBER @@ -7679,7 +7698,8 @@ class MediumMetadata final : public ::google::protobuf::MessageLite using WifiDirectAuthType = MediumMetadata_WifiDirectAuthType; static constexpr WifiDirectAuthType WIFI_DIRECT_TYPE_UNKNOWN = MediumMetadata_WifiDirectAuthType_WIFI_DIRECT_TYPE_UNKNOWN; static constexpr WifiDirectAuthType WIFI_DIRECT_WITH_PASSWORD = MediumMetadata_WifiDirectAuthType_WIFI_DIRECT_WITH_PASSWORD; - static constexpr WifiDirectAuthType WIFI_DIRECT_WITH_PIN = MediumMetadata_WifiDirectAuthType_WIFI_DIRECT_WITH_PIN; + [[deprecated]] static constexpr WifiDirectAuthType WIFI_DIRECT_WITH_PIN = MediumMetadata_WifiDirectAuthType_WIFI_DIRECT_WITH_PIN; + static constexpr WifiDirectAuthType WIFI_DIRECT_WITH_DEVICE_NAME = MediumMetadata_WifiDirectAuthType_WIFI_DIRECT_WITH_DEVICE_NAME; static inline bool WifiDirectAuthType_IsValid(int value) { return MediumMetadata_WifiDirectAuthType_IsValid(value); } @@ -15574,14 +15594,14 @@ inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia // optional int32 port = 3; inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::has_port() const { - bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000040U); + bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000080U); return value; } inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::clear_port() { ::google::protobuf::internal::TSanWrite(&_impl_); _impl_.port_ = 0; ClearHasBit(_impl_._has_bits_[0], - 0x00000040U); + 0x00000080U); } inline ::int32_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::port() const { // @@protoc_insertion_point(field_get:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.port) @@ -15589,7 +15609,7 @@ inline ::int32_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCred } inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::set_port(::int32_t value) { _internal_set_port(value); - SetHasBit(_impl_._has_bits_[0], 0x00000040U); + SetHasBit(_impl_._has_bits_[0], 0x00000080U); // @@protoc_insertion_point(field_set:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.port) } inline ::int32_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_port() const { @@ -15603,14 +15623,14 @@ inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia // optional int32 frequency = 4; inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::has_frequency() const { - bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000080U); + bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000100U); return value; } inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::clear_frequency() { ::google::protobuf::internal::TSanWrite(&_impl_); _impl_.frequency_ = 0; ClearHasBit(_impl_._has_bits_[0], - 0x00000080U); + 0x00000100U); } inline ::int32_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::frequency() const { // @@protoc_insertion_point(field_get:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.frequency) @@ -15618,7 +15638,7 @@ inline ::int32_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCred } inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::set_frequency(::int32_t value) { _internal_set_frequency(value); - SetHasBit(_impl_._has_bits_[0], 0x00000080U); + SetHasBit(_impl_._has_bits_[0], 0x00000100U); // @@protoc_insertion_point(field_set:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.frequency) } inline ::int32_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_frequency() const { @@ -15764,7 +15784,7 @@ inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia // @@protoc_insertion_point(field_set_allocated:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.ip_v6_address) } -// optional string service_name = 7; +// optional string service_name = 7 [deprecated = true]; inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::has_service_name() const { bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000010U); return value; @@ -15833,6 +15853,75 @@ inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia // @@protoc_insertion_point(field_set_allocated:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.service_name) } +// optional string device_name = 9; +inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::has_device_name() const { + bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000040U); + return value; +} +inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::clear_device_name() { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.device_name_.ClearToEmpty(); + ClearHasBit(_impl_._has_bits_[0], + 0x00000040U); +} +inline const ::std::string& BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::device_name() const + ABSL_ATTRIBUTE_LIFETIME_BOUND { + // @@protoc_insertion_point(field_get:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.device_name) + return _internal_device_name(); +} +template +PROTOBUF_ALWAYS_INLINE void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::set_device_name(Arg_&& arg, Args_... args) { + ::google::protobuf::internal::TSanWrite(&_impl_); + SetHasBit(_impl_._has_bits_[0], 0x00000040U); + _impl_.device_name_.Set(static_cast(arg), args..., GetArena()); + // @@protoc_insertion_point(field_set:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.device_name) +} +inline ::std::string* PROTOBUF_NONNULL BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::mutable_device_name() + ABSL_ATTRIBUTE_LIFETIME_BOUND { + SetHasBit(_impl_._has_bits_[0], 0x00000040U); + ::std::string* _s = _internal_mutable_device_name(); + // @@protoc_insertion_point(field_mutable:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.device_name) + return _s; +} +inline const ::std::string& BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_device_name() const { + ::google::protobuf::internal::TSanRead(&_impl_); + return _impl_.device_name_.Get(); +} +inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_set_device_name(const ::std::string& value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.device_name_.Set(value, GetArena()); +} +inline ::std::string* PROTOBUF_NONNULL BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_mutable_device_name() { + ::google::protobuf::internal::TSanWrite(&_impl_); + return _impl_.device_name_.Mutable( GetArena()); +} +inline ::std::string* PROTOBUF_NULLABLE BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::release_device_name() { + ::google::protobuf::internal::TSanWrite(&_impl_); + // @@protoc_insertion_point(field_release:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.device_name) + if (!CheckHasBit(_impl_._has_bits_[0], 0x00000040U)) { + return nullptr; + } + ClearHasBit(_impl_._has_bits_[0], 0x00000040U); + auto* released = _impl_.device_name_.Release(); + if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) { + _impl_.device_name_.Set("", GetArena()); + } + return released; +} +inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::set_allocated_device_name(::std::string* PROTOBUF_NULLABLE value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + if (value != nullptr) { + SetHasBit(_impl_._has_bits_[0], 0x00000040U); + } else { + ClearHasBit(_impl_._has_bits_[0], 0x00000040U); + } + _impl_.device_name_.SetAllocated(value, GetArena()); + if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.device_name_.IsDefault()) { + _impl_.device_name_.Set("", GetArena()); + } + // @@protoc_insertion_point(field_set_allocated:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.device_name) +} + // optional string pin = 8; inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::has_pin() const { bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000020U); diff --git a/compiled_proto/proto/connections_enums.pb.cc b/compiled_proto/proto/connections_enums.pb.cc index bf00c0c3..cd26feb2 100644 --- a/compiled_proto/proto/connections_enums.pb.cc +++ b/compiled_proto/proto/connections_enums.pb.cc @@ -263,44 +263,47 @@ bool Medium_Parse(::absl::string_view name, Medium* PROTOBUF_NONNULL value) { return success; } PROTOBUF_CONSTINIT const uint32_t WifiDirectAuthType_internal_data_[] = { - 196608u, 0u, }; + 262144u, 0u, }; static ::google::protobuf::internal::ExplicitlyConstructed<::std::string> - WifiDirectAuthType_strings[3] = {}; + WifiDirectAuthType_strings[4] = {}; static const char WifiDirectAuthType_names[] = { "WIFI_DIRECT_TYPE_UNKNOWN" + "WIFI_DIRECT_WITH_DEVICE_NAME" "WIFI_DIRECT_WITH_PASSWORD" "WIFI_DIRECT_WITH_PIN" }; static const ::google::protobuf::internal::EnumEntry WifiDirectAuthType_entries[] = { {{&WifiDirectAuthType_names[0], 24}, 0}, - {{&WifiDirectAuthType_names[24], 25}, 1}, - {{&WifiDirectAuthType_names[49], 20}, 2}, + {{&WifiDirectAuthType_names[24], 28}, 3}, + {{&WifiDirectAuthType_names[52], 25}, 1}, + {{&WifiDirectAuthType_names[77], 20}, 2}, }; static const int WifiDirectAuthType_entries_by_number[] = { 0, // 0 -> WIFI_DIRECT_TYPE_UNKNOWN - 1, // 1 -> WIFI_DIRECT_WITH_PASSWORD - 2, // 2 -> WIFI_DIRECT_WITH_PIN + 2, // 1 -> WIFI_DIRECT_WITH_PASSWORD + 3, // 2 -> WIFI_DIRECT_WITH_PIN + 1, // 3 -> WIFI_DIRECT_WITH_DEVICE_NAME }; const ::std::string& WifiDirectAuthType_Name(WifiDirectAuthType value) { static const bool kDummy = ::google::protobuf::internal::InitializeEnumStrings( - WifiDirectAuthType_entries, WifiDirectAuthType_entries_by_number, 3, + WifiDirectAuthType_entries, WifiDirectAuthType_entries_by_number, 4, WifiDirectAuthType_strings); (void)kDummy; int idx = ::google::protobuf::internal::LookUpEnumName(WifiDirectAuthType_entries, WifiDirectAuthType_entries_by_number, - 3, value); + 4, value); return idx == -1 ? ::google::protobuf::internal::GetEmptyString() : WifiDirectAuthType_strings[idx].get(); } bool WifiDirectAuthType_Parse(::absl::string_view name, WifiDirectAuthType* PROTOBUF_NONNULL value) { int int_value; bool success = ::google::protobuf::internal::LookUpEnumValue( - WifiDirectAuthType_entries, 3, name, &int_value); + WifiDirectAuthType_entries, 4, name, &int_value); if (success) { *value = static_cast(int_value); } @@ -1352,9 +1355,9 @@ bool OperationResultCategory_Parse(::absl::string_view name, OperationResultCate return success; } PROTOBUF_CONSTINIT const uint32_t OperationResultCode_internal_data_[] = { - 131072u, 5024u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4294705152u, 4095u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 1984u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4227858432u, 4294967295u, 1023u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4294950912u, 2097151u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 524284u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4290772992u, 31u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4294966272u, 4294967295u, 4294967295u, 33554431u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4294705152u, 4294967295u, 4294967295u, 4294967295u, 7u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 2147483584u, }; + 131072u, 5088u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4294705152u, 4095u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 1984u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4227858432u, 4294967295u, 1023u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4294950912u, 2097151u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 524284u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4290772992u, 31u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4294966272u, 4294967295u, 4294967295u, 33554431u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4294705152u, 4294967295u, 4294967295u, 4294967295u, 7u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4294967232u, 4294967295u, 15u, }; static ::google::protobuf::internal::ExplicitlyConstructed<::std::string> - OperationResultCode_strings[401] = {}; + OperationResultCode_strings[438] = {}; static const char OperationResultCode_names[] = { "CLIENT_ALREADY_CONNECTED_TO_ENDPOINT" @@ -1537,6 +1540,7 @@ static const char OperationResultCode_names[] = { "DCT_ERROR_BLE_DISABLED" "DCT_ERROR_BLE_SCAN_FAILED" "DCT_ERROR_CAPABILITY_MISMATCH" + "DCT_ERROR_CHECKIN_FAILURE" "DCT_ERROR_CONTROL_MESSAGE_EXCHANGE" "DCT_ERROR_ESTABLISHED_CONNECTION_LOST" "DCT_ERROR_HIGH_SPEED_MEDIUM_UNAVAILABLE" @@ -1545,14 +1549,50 @@ static const char OperationResultCode_names[] = { "DCT_ERROR_KEEPALIVE_TIMEOUT" "DCT_ERROR_L2CAP_CLIENT_FAILED" "DCT_ERROR_L2CAP_SERVER_FAILED" + "DCT_ERROR_LOCAL_ATTESTATION_PLAY_INTEGRITY_UNAVAILABLE" + "DCT_ERROR_LOCAL_ATTESTATION_TIMEOUT" "DCT_ERROR_MDNS_DISCOVERY_TIMEOUT" "DCT_ERROR_MDNS_REGISTER_SERVICE" + "DCT_ERROR_PARALLEL_ATTESTATION_TIMEOUT" + "DCT_ERROR_REMOTE_ATTESTATION_APPLE_INTEGRITY_UNAVAILABLE" + "DCT_ERROR_REMOTE_ATTESTATION_HASH_TOO_SHORT" + "DCT_ERROR_REMOTE_ATTESTATION_NULL_PACKET" + "DCT_ERROR_REMOTE_ATTESTATION_STATUS_NOT_AVAILABLE" + "DCT_ERROR_REMOTE_ATTESTATION_TIMEOUT" + "DCT_ERROR_REMOTE_CAPABILITY_MISMATCH" + "DCT_ERROR_REMOTE_CONTROL_MESSAGE_EXCHANGE" + "DCT_ERROR_REMOTE_HIGH_SPEED_MEDIUM_UNAVAILABLE" + "DCT_ERROR_REMOTE_MDNS_DISCOVERY_TIMEOUT" + "DCT_ERROR_REMOTE_MDNS_REGISTER_SERVICE" + "DCT_ERROR_REMOTE_REQUEST_FAILED" + "DCT_ERROR_REMOTE_RESPONSE_FAILED" + "DCT_ERROR_REMOTE_SERVICE_CANCELLED" + "DCT_ERROR_REMOTE_UNVERIFIED_INTEGRITY" + "DCT_ERROR_REMOTE_UPGRADE_HIGH_SPEED_MEDIUM_FAILED" + "DCT_ERROR_REMOTE_USER_CANCELLED" + "DCT_ERROR_REMOTE_WIFI_CREDENTIAL_TRANSFER" + "DCT_ERROR_REMOTE_WIFI_DISABLED" + "DCT_ERROR_REMOTE_WIFI_DISCONNECTED" + "DCT_ERROR_REMOTE_WIFI_INTERNET_CONNECTION" "DCT_ERROR_REQUEST_FAILED" "DCT_ERROR_RESPONSE_FAILED" "DCT_ERROR_SERVICE_CANCELLED" "DCT_ERROR_SUBSEQUENT_TLS_SPAKE" "DCT_ERROR_UNVERIFIED_INTEGRITY" "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_CONNECTION" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_HOST_NETWORK_NOT_AVAILABLE" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_HOST_NOT_STARTED" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_INTERRUPTED" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_LOW_SPEED" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_MDNS_DISCOVERY_NOT_STARTED" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_MEDIUM_NEGOTIATION" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_NO_INCOMING_HTTP_CONNECTION" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_NO_MEDIUM" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NETWORK_NOT_STARTED" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NOT_HOST" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NOT_PLUGGED" + "DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NO_CONNECTED_DEVICE" "DCT_ERROR_USER_CANCELLED" "DCT_ERROR_WIFI_CREDENTIAL_TRANSFER" "DCT_ERROR_WIFI_DISABLED" @@ -1941,232 +1981,269 @@ static const ::google::protobuf::internal::EnumEntry OperationResultCode_entries {{&OperationResultCode_names[8024], 22}, 5000}, {{&OperationResultCode_names[8046], 25}, 5002}, {{&OperationResultCode_names[8071], 29}, 5012}, - {{&OperationResultCode_names[8100], 34}, 5011}, - {{&OperationResultCode_names[8134], 37}, 5020}, - {{&OperationResultCode_names[8171], 39}, 5013}, - {{&OperationResultCode_names[8210], 28}, 5024}, - {{&OperationResultCode_names[8238], 27}, 5007}, - {{&OperationResultCode_names[8265], 27}, 5019}, - {{&OperationResultCode_names[8292], 29}, 5004}, - {{&OperationResultCode_names[8321], 29}, 5003}, - {{&OperationResultCode_names[8350], 32}, 5005}, - {{&OperationResultCode_names[8382], 31}, 5006}, - {{&OperationResultCode_names[8413], 24}, 5009}, - {{&OperationResultCode_names[8437], 25}, 5010}, - {{&OperationResultCode_names[8462], 27}, 5022}, - {{&OperationResultCode_names[8489], 30}, 5008}, - {{&OperationResultCode_names[8519], 30}, 5023}, - {{&OperationResultCode_names[8549], 42}, 5018}, - {{&OperationResultCode_names[8591], 24}, 5021}, - {{&OperationResultCode_names[8615], 34}, 5016}, - {{&OperationResultCode_names[8649], 23}, 5014}, - {{&OperationResultCode_names[8672], 27}, 5015}, - {{&OperationResultCode_names[8699], 34}, 5017}, - {{&OperationResultCode_names[8733], 14}, 1}, - {{&OperationResultCode_names[8747], 14}, 0}, - {{&OperationResultCode_names[8761], 46}, 1000}, - {{&OperationResultCode_names[8807], 39}, 1001}, - {{&OperationResultCode_names[8846], 30}, 1002}, - {{&OperationResultCode_names[8876], 36}, 1003}, - {{&OperationResultCode_names[8912], 35}, 1004}, - {{&OperationResultCode_names[8947], 27}, 3005}, - {{&OperationResultCode_names[8974], 33}, 3006}, - {{&OperationResultCode_names[9007], 26}, 3007}, - {{&OperationResultCode_names[9033], 27}, 3009}, - {{&OperationResultCode_names[9060], 27}, 3013}, - {{&OperationResultCode_names[9087], 27}, 3014}, - {{&OperationResultCode_names[9114], 31}, 3008}, - {{&OperationResultCode_names[9145], 34}, 3012}, - {{&OperationResultCode_names[9179], 35}, 3010}, - {{&OperationResultCode_names[9214], 36}, 3011}, - {{&OperationResultCode_names[9250], 21}, 3000}, - {{&OperationResultCode_names[9271], 21}, 3001}, - {{&OperationResultCode_names[9292], 21}, 3002}, - {{&OperationResultCode_names[9313], 24}, 3003}, - {{&OperationResultCode_names[9337], 29}, 3004}, - {{&OperationResultCode_names[9366], 51}, 1534}, - {{&OperationResultCode_names[9417], 60}, 1535}, - {{&OperationResultCode_names[9477], 37}, 1547}, - {{&OperationResultCode_names[9514], 47}, 1515}, - {{&OperationResultCode_names[9561], 36}, 1505}, - {{&OperationResultCode_names[9597], 42}, 1507}, - {{&OperationResultCode_names[9639], 40}, 1546}, - {{&OperationResultCode_names[9679], 46}, 1516}, - {{&OperationResultCode_names[9725], 45}, 1501}, - {{&OperationResultCode_names[9770], 45}, 1541}, - {{&OperationResultCode_names[9815], 38}, 1506}, - {{&OperationResultCode_names[9853], 30}, 1544}, - {{&OperationResultCode_names[9883], 47}, 1517}, - {{&OperationResultCode_names[9930], 36}, 1513}, - {{&OperationResultCode_names[9966], 54}, 1532}, - {{&OperationResultCode_names[10020], 49}, 1503}, - {{&OperationResultCode_names[10069], 52}, 1504}, - {{&OperationResultCode_names[10121], 37}, 1543}, - {{&OperationResultCode_names[10158], 47}, 1518}, - {{&OperationResultCode_names[10205], 36}, 1512}, - {{&OperationResultCode_names[10241], 36}, 1542}, - {{&OperationResultCode_names[10277], 30}, 1545}, - {{&OperationResultCode_names[10307], 60}, 1536}, - {{&OperationResultCode_names[10367], 43}, 1533}, - {{&OperationResultCode_names[10410], 38}, 1502}, - {{&OperationResultCode_names[10448], 39}, 1539}, - {{&OperationResultCode_names[10487], 37}, 1540}, - {{&OperationResultCode_names[10524], 41}, 1537}, - {{&OperationResultCode_names[10565], 55}, 1526}, - {{&OperationResultCode_names[10620], 54}, 1530}, - {{&OperationResultCode_names[10674], 57}, 1527}, - {{&OperationResultCode_names[10731], 55}, 1529}, - {{&OperationResultCode_names[10786], 55}, 1531}, - {{&OperationResultCode_names[10841], 59}, 1528}, - {{&OperationResultCode_names[10900], 47}, 1519}, - {{&OperationResultCode_names[10947], 36}, 1514}, - {{&OperationResultCode_names[10983], 51}, 1520}, - {{&OperationResultCode_names[11034], 40}, 1508}, - {{&OperationResultCode_names[11074], 38}, 1538}, - {{&OperationResultCode_names[11112], 54}, 1521}, - {{&OperationResultCode_names[11166], 43}, 1509}, - {{&OperationResultCode_names[11209], 52}, 1500}, - {{&OperationResultCode_names[11261], 55}, 1523}, - {{&OperationResultCode_names[11316], 44}, 1511}, - {{&OperationResultCode_names[11360], 57}, 1525}, - {{&OperationResultCode_names[11417], 56}, 1522}, - {{&OperationResultCode_names[11473], 45}, 1510}, - {{&OperationResultCode_names[11518], 58}, 1524}, - {{&OperationResultCode_names[11576], 38}, 2503}, - {{&OperationResultCode_names[11614], 51}, 2514}, - {{&OperationResultCode_names[11665], 41}, 2500}, - {{&OperationResultCode_names[11706], 59}, 2510}, - {{&OperationResultCode_names[11765], 37}, 2505}, - {{&OperationResultCode_names[11802], 40}, 2504}, - {{&OperationResultCode_names[11842], 33}, 2501}, - {{&OperationResultCode_names[11875], 48}, 2513}, - {{&OperationResultCode_names[11923], 52}, 2511}, - {{&OperationResultCode_names[11975], 38}, 2515}, - {{&OperationResultCode_names[12013], 55}, 2512}, - {{&OperationResultCode_names[12068], 45}, 2506}, - {{&OperationResultCode_names[12113], 46}, 2507}, - {{&OperationResultCode_names[12159], 56}, 2502}, - {{&OperationResultCode_names[12215], 47}, 2509}, - {{&OperationResultCode_names[12262], 43}, 2508}, - {{&OperationResultCode_names[12305], 31}, 2516}, - {{&OperationResultCode_names[12336], 29}, 4568}, - {{&OperationResultCode_names[12365], 38}, 4611}, - {{&OperationResultCode_names[12403], 45}, 4612}, - {{&OperationResultCode_names[12448], 60}, 4609}, - {{&OperationResultCode_names[12508], 45}, 4500}, - {{&OperationResultCode_names[12553], 37}, 4571}, - {{&OperationResultCode_names[12590], 44}, 4504}, - {{&OperationResultCode_names[12634], 42}, 4572}, - {{&OperationResultCode_names[12676], 49}, 4515}, - {{&OperationResultCode_names[12725], 29}, 4518}, - {{&OperationResultCode_names[12754], 30}, 4579}, - {{&OperationResultCode_names[12784], 38}, 4536}, - {{&OperationResultCode_names[12822], 43}, 4570}, - {{&OperationResultCode_names[12865], 36}, 4578}, - {{&OperationResultCode_names[12901], 48}, 4501}, - {{&OperationResultCode_names[12949], 44}, 4585}, - {{&OperationResultCode_names[12993], 35}, 4592}, - {{&OperationResultCode_names[13028], 43}, 4506}, - {{&OperationResultCode_names[13071], 35}, 4530}, - {{&OperationResultCode_names[13106], 23}, 4520}, - {{&OperationResultCode_names[13129], 37}, 4538}, - {{&OperationResultCode_names[13166], 41}, 4563}, - {{&OperationResultCode_names[13207], 37}, 4602}, - {{&OperationResultCode_names[13244], 31}, 4610}, - {{&OperationResultCode_names[13275], 38}, 4606}, - {{&OperationResultCode_names[13313], 37}, 4591}, - {{&OperationResultCode_names[13350], 25}, 4567}, - {{&OperationResultCode_names[13375], 27}, 4605}, - {{&OperationResultCode_names[13402], 32}, 4503}, - {{&OperationResultCode_names[13434], 35}, 4514}, - {{&OperationResultCode_names[13469], 48}, 4588}, - {{&OperationResultCode_names[13517], 45}, 4552}, - {{&OperationResultCode_names[13562], 40}, 4532}, - {{&OperationResultCode_names[13602], 40}, 4535}, - {{&OperationResultCode_names[13642], 48}, 4547}, - {{&OperationResultCode_names[13690], 60}, 4556}, - {{&OperationResultCode_names[13750], 56}, 4558}, - {{&OperationResultCode_names[13806], 60}, 4557}, - {{&OperationResultCode_names[13866], 56}, 4553}, - {{&OperationResultCode_names[13922], 52}, 4555}, - {{&OperationResultCode_names[13974], 56}, 4554}, - {{&OperationResultCode_names[14030], 43}, 4559}, - {{&OperationResultCode_names[14073], 43}, 4560}, - {{&OperationResultCode_names[14116], 37}, 4561}, - {{&OperationResultCode_names[14153], 41}, 4562}, - {{&OperationResultCode_names[14194], 49}, 4586}, - {{&OperationResultCode_names[14243], 46}, 4505}, - {{&OperationResultCode_names[14289], 26}, 4519}, - {{&OperationResultCode_names[14315], 40}, 4537}, - {{&OperationResultCode_names[14355], 29}, 4566}, - {{&OperationResultCode_names[14384], 44}, 4507}, - {{&OperationResultCode_names[14428], 36}, 4531}, - {{&OperationResultCode_names[14464], 24}, 4525}, - {{&OperationResultCode_names[14488], 38}, 4539}, - {{&OperationResultCode_names[14526], 41}, 4593}, - {{&OperationResultCode_names[14567], 28}, 4594}, - {{&OperationResultCode_names[14595], 42}, 4564}, - {{&OperationResultCode_names[14637], 30}, 4569}, - {{&OperationResultCode_names[14667], 31}, 4607}, - {{&OperationResultCode_names[14698], 27}, 4587}, - {{&OperationResultCode_names[14725], 37}, 4573}, - {{&OperationResultCode_names[14762], 44}, 4508}, - {{&OperationResultCode_names[14806], 30}, 4577}, - {{&OperationResultCode_names[14836], 24}, 4522}, - {{&OperationResultCode_names[14860], 35}, 4601}, - {{&OperationResultCode_names[14895], 56}, 4608}, - {{&OperationResultCode_names[14951], 29}, 4603}, - {{&OperationResultCode_names[14980], 28}, 4604}, - {{&OperationResultCode_names[15008], 35}, 4590}, - {{&OperationResultCode_names[15043], 37}, 4576}, - {{&OperationResultCode_names[15080], 44}, 4513}, - {{&OperationResultCode_names[15124], 30}, 4582}, - {{&OperationResultCode_names[15154], 24}, 4521}, - {{&OperationResultCode_names[15178], 30}, 4583}, - {{&OperationResultCode_names[15208], 35}, 4502}, - {{&OperationResultCode_names[15243], 48}, 4512}, - {{&OperationResultCode_names[15291], 34}, 4584}, - {{&OperationResultCode_names[15325], 38}, 4589}, - {{&OperationResultCode_names[15363], 28}, 4524}, - {{&OperationResultCode_names[15391], 42}, 4540}, - {{&OperationResultCode_names[15433], 37}, 4599}, - {{&OperationResultCode_names[15470], 44}, 4575}, - {{&OperationResultCode_names[15514], 51}, 4509}, - {{&OperationResultCode_names[15565], 37}, 4581}, - {{&OperationResultCode_names[15602], 31}, 4523}, - {{&OperationResultCode_names[15633], 45}, 4541}, - {{&OperationResultCode_names[15678], 42}, 4600}, - {{&OperationResultCode_names[15720], 52}, 4511}, - {{&OperationResultCode_names[15772], 39}, 4516}, - {{&OperationResultCode_names[15811], 41}, 4533}, - {{&OperationResultCode_names[15852], 32}, 4527}, - {{&OperationResultCode_names[15884], 32}, 4529}, - {{&OperationResultCode_names[15916], 28}, 4528}, - {{&OperationResultCode_names[15944], 46}, 4546}, - {{&OperationResultCode_names[15990], 48}, 4549}, - {{&OperationResultCode_names[16038], 48}, 4551}, - {{&OperationResultCode_names[16086], 51}, 4596}, - {{&OperationResultCode_names[16137], 43}, 4595}, - {{&OperationResultCode_names[16180], 54}, 4545}, - {{&OperationResultCode_names[16234], 54}, 4542}, - {{&OperationResultCode_names[16288], 53}, 4510}, - {{&OperationResultCode_names[16341], 40}, 4517}, - {{&OperationResultCode_names[16381], 52}, 4544}, - {{&OperationResultCode_names[16433], 44}, 4534}, - {{&OperationResultCode_names[16477], 33}, 4526}, - {{&OperationResultCode_names[16510], 49}, 4548}, - {{&OperationResultCode_names[16559], 49}, 4550}, - {{&OperationResultCode_names[16608], 52}, 4598}, - {{&OperationResultCode_names[16660], 44}, 4597}, - {{&OperationResultCode_names[16704], 55}, 4543}, - {{&OperationResultCode_names[16759], 42}, 4574}, - {{&OperationResultCode_names[16801], 35}, 4580}, - {{&OperationResultCode_names[16836], 32}, 4565}, + {{&OperationResultCode_names[8100], 25}, 5025}, + {{&OperationResultCode_names[8125], 34}, 5011}, + {{&OperationResultCode_names[8159], 37}, 5020}, + {{&OperationResultCode_names[8196], 39}, 5013}, + {{&OperationResultCode_names[8235], 28}, 5024}, + {{&OperationResultCode_names[8263], 27}, 5007}, + {{&OperationResultCode_names[8290], 27}, 5019}, + {{&OperationResultCode_names[8317], 29}, 5004}, + {{&OperationResultCode_names[8346], 29}, 5003}, + {{&OperationResultCode_names[8375], 54}, 5031}, + {{&OperationResultCode_names[8429], 35}, 5032}, + {{&OperationResultCode_names[8464], 32}, 5005}, + {{&OperationResultCode_names[8496], 31}, 5006}, + {{&OperationResultCode_names[8527], 38}, 5033}, + {{&OperationResultCode_names[8565], 56}, 5030}, + {{&OperationResultCode_names[8621], 43}, 5029}, + {{&OperationResultCode_names[8664], 40}, 5027}, + {{&OperationResultCode_names[8704], 49}, 5028}, + {{&OperationResultCode_names[8753], 36}, 5026}, + {{&OperationResultCode_names[8789], 36}, 5039}, + {{&OperationResultCode_names[8825], 41}, 5038}, + {{&OperationResultCode_names[8866], 46}, 5040}, + {{&OperationResultCode_names[8912], 39}, 5034}, + {{&OperationResultCode_names[8951], 38}, 5035}, + {{&OperationResultCode_names[8989], 31}, 5036}, + {{&OperationResultCode_names[9020], 32}, 5037}, + {{&OperationResultCode_names[9052], 34}, 5047}, + {{&OperationResultCode_names[9086], 37}, 5048}, + {{&OperationResultCode_names[9123], 49}, 5045}, + {{&OperationResultCode_names[9172], 31}, 5046}, + {{&OperationResultCode_names[9203], 41}, 5043}, + {{&OperationResultCode_names[9244], 30}, 5041}, + {{&OperationResultCode_names[9274], 34}, 5042}, + {{&OperationResultCode_names[9308], 41}, 5044}, + {{&OperationResultCode_names[9349], 24}, 5009}, + {{&OperationResultCode_names[9373], 25}, 5010}, + {{&OperationResultCode_names[9398], 27}, 5022}, + {{&OperationResultCode_names[9425], 30}, 5008}, + {{&OperationResultCode_names[9455], 30}, 5023}, + {{&OperationResultCode_names[9485], 42}, 5018}, + {{&OperationResultCode_names[9527], 53}, 5050}, + {{&OperationResultCode_names[9580], 69}, 5058}, + {{&OperationResultCode_names[9649], 59}, 5057}, + {{&OperationResultCode_names[9708], 54}, 5061}, + {{&OperationResultCode_names[9762], 52}, 5049}, + {{&OperationResultCode_names[9814], 69}, 5053}, + {{&OperationResultCode_names[9883], 61}, 5056}, + {{&OperationResultCode_names[9944], 70}, 5059}, + {{&OperationResultCode_names[10014], 52}, 5054}, + {{&OperationResultCode_names[10066], 66}, 5055}, + {{&OperationResultCode_names[10132], 55}, 5052}, + {{&OperationResultCode_names[10187], 58}, 5051}, + {{&OperationResultCode_names[10245], 66}, 5060}, + {{&OperationResultCode_names[10311], 24}, 5021}, + {{&OperationResultCode_names[10335], 34}, 5016}, + {{&OperationResultCode_names[10369], 23}, 5014}, + {{&OperationResultCode_names[10392], 27}, 5015}, + {{&OperationResultCode_names[10419], 34}, 5017}, + {{&OperationResultCode_names[10453], 14}, 1}, + {{&OperationResultCode_names[10467], 14}, 0}, + {{&OperationResultCode_names[10481], 46}, 1000}, + {{&OperationResultCode_names[10527], 39}, 1001}, + {{&OperationResultCode_names[10566], 30}, 1002}, + {{&OperationResultCode_names[10596], 36}, 1003}, + {{&OperationResultCode_names[10632], 35}, 1004}, + {{&OperationResultCode_names[10667], 27}, 3005}, + {{&OperationResultCode_names[10694], 33}, 3006}, + {{&OperationResultCode_names[10727], 26}, 3007}, + {{&OperationResultCode_names[10753], 27}, 3009}, + {{&OperationResultCode_names[10780], 27}, 3013}, + {{&OperationResultCode_names[10807], 27}, 3014}, + {{&OperationResultCode_names[10834], 31}, 3008}, + {{&OperationResultCode_names[10865], 34}, 3012}, + {{&OperationResultCode_names[10899], 35}, 3010}, + {{&OperationResultCode_names[10934], 36}, 3011}, + {{&OperationResultCode_names[10970], 21}, 3000}, + {{&OperationResultCode_names[10991], 21}, 3001}, + {{&OperationResultCode_names[11012], 21}, 3002}, + {{&OperationResultCode_names[11033], 24}, 3003}, + {{&OperationResultCode_names[11057], 29}, 3004}, + {{&OperationResultCode_names[11086], 51}, 1534}, + {{&OperationResultCode_names[11137], 60}, 1535}, + {{&OperationResultCode_names[11197], 37}, 1547}, + {{&OperationResultCode_names[11234], 47}, 1515}, + {{&OperationResultCode_names[11281], 36}, 1505}, + {{&OperationResultCode_names[11317], 42}, 1507}, + {{&OperationResultCode_names[11359], 40}, 1546}, + {{&OperationResultCode_names[11399], 46}, 1516}, + {{&OperationResultCode_names[11445], 45}, 1501}, + {{&OperationResultCode_names[11490], 45}, 1541}, + {{&OperationResultCode_names[11535], 38}, 1506}, + {{&OperationResultCode_names[11573], 30}, 1544}, + {{&OperationResultCode_names[11603], 47}, 1517}, + {{&OperationResultCode_names[11650], 36}, 1513}, + {{&OperationResultCode_names[11686], 54}, 1532}, + {{&OperationResultCode_names[11740], 49}, 1503}, + {{&OperationResultCode_names[11789], 52}, 1504}, + {{&OperationResultCode_names[11841], 37}, 1543}, + {{&OperationResultCode_names[11878], 47}, 1518}, + {{&OperationResultCode_names[11925], 36}, 1512}, + {{&OperationResultCode_names[11961], 36}, 1542}, + {{&OperationResultCode_names[11997], 30}, 1545}, + {{&OperationResultCode_names[12027], 60}, 1536}, + {{&OperationResultCode_names[12087], 43}, 1533}, + {{&OperationResultCode_names[12130], 38}, 1502}, + {{&OperationResultCode_names[12168], 39}, 1539}, + {{&OperationResultCode_names[12207], 37}, 1540}, + {{&OperationResultCode_names[12244], 41}, 1537}, + {{&OperationResultCode_names[12285], 55}, 1526}, + {{&OperationResultCode_names[12340], 54}, 1530}, + {{&OperationResultCode_names[12394], 57}, 1527}, + {{&OperationResultCode_names[12451], 55}, 1529}, + {{&OperationResultCode_names[12506], 55}, 1531}, + {{&OperationResultCode_names[12561], 59}, 1528}, + {{&OperationResultCode_names[12620], 47}, 1519}, + {{&OperationResultCode_names[12667], 36}, 1514}, + {{&OperationResultCode_names[12703], 51}, 1520}, + {{&OperationResultCode_names[12754], 40}, 1508}, + {{&OperationResultCode_names[12794], 38}, 1538}, + {{&OperationResultCode_names[12832], 54}, 1521}, + {{&OperationResultCode_names[12886], 43}, 1509}, + {{&OperationResultCode_names[12929], 52}, 1500}, + {{&OperationResultCode_names[12981], 55}, 1523}, + {{&OperationResultCode_names[13036], 44}, 1511}, + {{&OperationResultCode_names[13080], 57}, 1525}, + {{&OperationResultCode_names[13137], 56}, 1522}, + {{&OperationResultCode_names[13193], 45}, 1510}, + {{&OperationResultCode_names[13238], 58}, 1524}, + {{&OperationResultCode_names[13296], 38}, 2503}, + {{&OperationResultCode_names[13334], 51}, 2514}, + {{&OperationResultCode_names[13385], 41}, 2500}, + {{&OperationResultCode_names[13426], 59}, 2510}, + {{&OperationResultCode_names[13485], 37}, 2505}, + {{&OperationResultCode_names[13522], 40}, 2504}, + {{&OperationResultCode_names[13562], 33}, 2501}, + {{&OperationResultCode_names[13595], 48}, 2513}, + {{&OperationResultCode_names[13643], 52}, 2511}, + {{&OperationResultCode_names[13695], 38}, 2515}, + {{&OperationResultCode_names[13733], 55}, 2512}, + {{&OperationResultCode_names[13788], 45}, 2506}, + {{&OperationResultCode_names[13833], 46}, 2507}, + {{&OperationResultCode_names[13879], 56}, 2502}, + {{&OperationResultCode_names[13935], 47}, 2509}, + {{&OperationResultCode_names[13982], 43}, 2508}, + {{&OperationResultCode_names[14025], 31}, 2516}, + {{&OperationResultCode_names[14056], 29}, 4568}, + {{&OperationResultCode_names[14085], 38}, 4611}, + {{&OperationResultCode_names[14123], 45}, 4612}, + {{&OperationResultCode_names[14168], 60}, 4609}, + {{&OperationResultCode_names[14228], 45}, 4500}, + {{&OperationResultCode_names[14273], 37}, 4571}, + {{&OperationResultCode_names[14310], 44}, 4504}, + {{&OperationResultCode_names[14354], 42}, 4572}, + {{&OperationResultCode_names[14396], 49}, 4515}, + {{&OperationResultCode_names[14445], 29}, 4518}, + {{&OperationResultCode_names[14474], 30}, 4579}, + {{&OperationResultCode_names[14504], 38}, 4536}, + {{&OperationResultCode_names[14542], 43}, 4570}, + {{&OperationResultCode_names[14585], 36}, 4578}, + {{&OperationResultCode_names[14621], 48}, 4501}, + {{&OperationResultCode_names[14669], 44}, 4585}, + {{&OperationResultCode_names[14713], 35}, 4592}, + {{&OperationResultCode_names[14748], 43}, 4506}, + {{&OperationResultCode_names[14791], 35}, 4530}, + {{&OperationResultCode_names[14826], 23}, 4520}, + {{&OperationResultCode_names[14849], 37}, 4538}, + {{&OperationResultCode_names[14886], 41}, 4563}, + {{&OperationResultCode_names[14927], 37}, 4602}, + {{&OperationResultCode_names[14964], 31}, 4610}, + {{&OperationResultCode_names[14995], 38}, 4606}, + {{&OperationResultCode_names[15033], 37}, 4591}, + {{&OperationResultCode_names[15070], 25}, 4567}, + {{&OperationResultCode_names[15095], 27}, 4605}, + {{&OperationResultCode_names[15122], 32}, 4503}, + {{&OperationResultCode_names[15154], 35}, 4514}, + {{&OperationResultCode_names[15189], 48}, 4588}, + {{&OperationResultCode_names[15237], 45}, 4552}, + {{&OperationResultCode_names[15282], 40}, 4532}, + {{&OperationResultCode_names[15322], 40}, 4535}, + {{&OperationResultCode_names[15362], 48}, 4547}, + {{&OperationResultCode_names[15410], 60}, 4556}, + {{&OperationResultCode_names[15470], 56}, 4558}, + {{&OperationResultCode_names[15526], 60}, 4557}, + {{&OperationResultCode_names[15586], 56}, 4553}, + {{&OperationResultCode_names[15642], 52}, 4555}, + {{&OperationResultCode_names[15694], 56}, 4554}, + {{&OperationResultCode_names[15750], 43}, 4559}, + {{&OperationResultCode_names[15793], 43}, 4560}, + {{&OperationResultCode_names[15836], 37}, 4561}, + {{&OperationResultCode_names[15873], 41}, 4562}, + {{&OperationResultCode_names[15914], 49}, 4586}, + {{&OperationResultCode_names[15963], 46}, 4505}, + {{&OperationResultCode_names[16009], 26}, 4519}, + {{&OperationResultCode_names[16035], 40}, 4537}, + {{&OperationResultCode_names[16075], 29}, 4566}, + {{&OperationResultCode_names[16104], 44}, 4507}, + {{&OperationResultCode_names[16148], 36}, 4531}, + {{&OperationResultCode_names[16184], 24}, 4525}, + {{&OperationResultCode_names[16208], 38}, 4539}, + {{&OperationResultCode_names[16246], 41}, 4593}, + {{&OperationResultCode_names[16287], 28}, 4594}, + {{&OperationResultCode_names[16315], 42}, 4564}, + {{&OperationResultCode_names[16357], 30}, 4569}, + {{&OperationResultCode_names[16387], 31}, 4607}, + {{&OperationResultCode_names[16418], 27}, 4587}, + {{&OperationResultCode_names[16445], 37}, 4573}, + {{&OperationResultCode_names[16482], 44}, 4508}, + {{&OperationResultCode_names[16526], 30}, 4577}, + {{&OperationResultCode_names[16556], 24}, 4522}, + {{&OperationResultCode_names[16580], 35}, 4601}, + {{&OperationResultCode_names[16615], 56}, 4608}, + {{&OperationResultCode_names[16671], 29}, 4603}, + {{&OperationResultCode_names[16700], 28}, 4604}, + {{&OperationResultCode_names[16728], 35}, 4590}, + {{&OperationResultCode_names[16763], 37}, 4576}, + {{&OperationResultCode_names[16800], 44}, 4513}, + {{&OperationResultCode_names[16844], 30}, 4582}, + {{&OperationResultCode_names[16874], 24}, 4521}, + {{&OperationResultCode_names[16898], 30}, 4583}, + {{&OperationResultCode_names[16928], 35}, 4502}, + {{&OperationResultCode_names[16963], 48}, 4512}, + {{&OperationResultCode_names[17011], 34}, 4584}, + {{&OperationResultCode_names[17045], 38}, 4589}, + {{&OperationResultCode_names[17083], 28}, 4524}, + {{&OperationResultCode_names[17111], 42}, 4540}, + {{&OperationResultCode_names[17153], 37}, 4599}, + {{&OperationResultCode_names[17190], 44}, 4575}, + {{&OperationResultCode_names[17234], 51}, 4509}, + {{&OperationResultCode_names[17285], 37}, 4581}, + {{&OperationResultCode_names[17322], 31}, 4523}, + {{&OperationResultCode_names[17353], 45}, 4541}, + {{&OperationResultCode_names[17398], 42}, 4600}, + {{&OperationResultCode_names[17440], 52}, 4511}, + {{&OperationResultCode_names[17492], 39}, 4516}, + {{&OperationResultCode_names[17531], 41}, 4533}, + {{&OperationResultCode_names[17572], 32}, 4527}, + {{&OperationResultCode_names[17604], 32}, 4529}, + {{&OperationResultCode_names[17636], 28}, 4528}, + {{&OperationResultCode_names[17664], 46}, 4546}, + {{&OperationResultCode_names[17710], 48}, 4549}, + {{&OperationResultCode_names[17758], 48}, 4551}, + {{&OperationResultCode_names[17806], 51}, 4596}, + {{&OperationResultCode_names[17857], 43}, 4595}, + {{&OperationResultCode_names[17900], 54}, 4545}, + {{&OperationResultCode_names[17954], 54}, 4542}, + {{&OperationResultCode_names[18008], 53}, 4510}, + {{&OperationResultCode_names[18061], 40}, 4517}, + {{&OperationResultCode_names[18101], 52}, 4544}, + {{&OperationResultCode_names[18153], 44}, 4534}, + {{&OperationResultCode_names[18197], 33}, 4526}, + {{&OperationResultCode_names[18230], 49}, 4548}, + {{&OperationResultCode_names[18279], 49}, 4550}, + {{&OperationResultCode_names[18328], 52}, 4598}, + {{&OperationResultCode_names[18380], 44}, 4597}, + {{&OperationResultCode_names[18424], 55}, 4543}, + {{&OperationResultCode_names[18479], 42}, 4574}, + {{&OperationResultCode_names[18521], 35}, 4580}, + {{&OperationResultCode_names[18556], 32}, 4565}, }; static const int OperationResultCode_entries_by_number[] = { - 202, // 0 -> DETAIL_UNKNOWN - 201, // 1 -> DETAIL_SUCCESS + 239, // 0 -> DETAIL_UNKNOWN + 238, // 1 -> DETAIL_SUCCESS 28, // 500 -> CLIENT_CANCELLATION_REMOTE_IN_CANCELED_STATE 24, // 501 -> CLIENT_CANCELLATION_LOCAL_CANCEL_PAYLOAD 26, // 502 -> CLIENT_CANCELLATION_REMOTE_CANCEL_PAYLOAD @@ -2193,59 +2270,59 @@ static const int OperationResultCode_entries_by_number[] = { 27, // 523 -> CLIENT_CANCELLATION_REMOTE_DISCONNECT 9, // 524 -> CLIENT_CANCELLATION_AWDL_SERVER_SOCKET_CREATION 11, // 525 -> CLIENT_CANCELLATION_CANCEL_AWDL_OUTGOING_CONNECTION - 203, // 1000 -> DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS - 204, // 1001 -> DEVICE_STATE_ERROR_USER_HOTSPOT_ENABLED - 205, // 1002 -> DEVICE_STATE_LOCATION_DISABLED - 206, // 1003 -> DEVICE_STATE_RADIO_DISABLING_FAILURE - 207, // 1004 -> DEVICE_STATE_RADIO_ENABLING_FAILURE - 264, // 1500 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_RESOURCE_NOT_AVAILABLE - 231, // 1501 -> MEDIUM_UNAVAILABLE_DIRECT_HOTSPOT_NOT_SUPPORT - 247, // 1502 -> MEDIUM_UNAVAILABLE_SOFT_AP_NOT_SUPPORT - 238, // 1503 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_NOT_SUPPORT - 239, // 1504 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_NOT_SUPPORT_5G - 227, // 1505 -> MEDIUM_UNAVAILABLE_BLE_NOT_AVAILABLE - 233, // 1506 -> MEDIUM_UNAVAILABLE_L2CAP_NOT_AVAILABLE - 228, // 1507 -> MEDIUM_UNAVAILABLE_BLUETOOTH_NOT_AVAILABLE - 260, // 1508 -> MEDIUM_UNAVAILABLE_WEB_RTC_NOT_AVAILABLE - 263, // 1509 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_NOT_AVAILABLE - 269, // 1510 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_NOT_AVAILABLE - 266, // 1511 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_NOT_AVAILABLE - 242, // 1512 -> MEDIUM_UNAVAILABLE_NFC_NOT_AVAILABLE - 236, // 1513 -> MEDIUM_UNAVAILABLE_LAN_NOT_AVAILABLE - 258, // 1514 -> MEDIUM_UNAVAILABLE_USB_NOT_AVAILABLE - 226, // 1515 -> MEDIUM_UNAVAILABLE_BLE_NC_LOGICAL_NOT_AVAILABLE - 230, // 1516 -> MEDIUM_UNAVAILABLE_BT_NC_LOGICAL_NOT_AVAILABLE - 235, // 1517 -> MEDIUM_UNAVAILABLE_LAN_NC_LOGICAL_NOT_AVAILABLE - 241, // 1518 -> MEDIUM_UNAVAILABLE_NFC_NC_LOGICAL_NOT_AVAILABLE - 257, // 1519 -> MEDIUM_UNAVAILABLE_USB_NC_LOGICAL_NOT_AVAILABLE - 259, // 1520 -> MEDIUM_UNAVAILABLE_WEB_RTC_NC_LOGICAL_NOT_AVAILABLE - 262, // 1521 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_NC_LOGICAL_NOT_AVAILABLE - 268, // 1522 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_NC_LOGICAL_NOT_AVAILABLE - 265, // 1523 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_NC_LOGICAL_NOT_AVAILABLE - 270, // 1524 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_P2P_RESOURCE_NOT_AVAILABLE - 267, // 1525 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_P2P_RESOURCE_NOT_AVAILABLE - 251, // 1526 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_BLE_LOW_QUALITY_MEDIUMS - 253, // 1527 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_L2CAP_LOW_QUALITY_MEDIUMS - 256, // 1528 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_WEB_RTC_LOW_QUALITY_MEDIUMS - 254, // 1529 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_LAN_LOW_QUALITY_MEDIUMS - 252, // 1530 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_BT_LOW_QUALITY_MEDIUMS - 255, // 1531 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_USB_LOW_QUALITY_MEDIUMS - 237, // 1532 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_DISRUPTIVE_FALSE - 246, // 1533 -> MEDIUM_UNAVAILABLE_SOFT_AP_DISRUPTIVE_FALSE - 223, // 1534 -> MEDIUM_UNAVAILABLE_ALREADY_HAVE_A_WIFI_DIRECT_GROUP - 224, // 1535 -> MEDIUM_UNAVAILABLE_ALREADY_HOSTING_HOTSPOT_FOR_OTHER_CLIENTS - 245, // 1536 -> MEDIUM_UNAVAILABLE_REJECT_L2CAP_ON_GATT_MULTIPLEX_CONNECTION - 250, // 1537 -> MEDIUM_UNAVAILABLE_UPGRADE_ON_SAME_MEDIUM - 261, // 1538 -> MEDIUM_UNAVAILABLE_WEB_RTC_NO_INTERNET - 248, // 1539 -> MEDIUM_UNAVAILABLE_STA_DISRUPTIVE_FALSE - 249, // 1540 -> MEDIUM_UNAVAILABLE_STA_USER_NOT_ALLOW - 232, // 1541 -> MEDIUM_UNAVAILABLE_DUPLICATE_FAST_ADVERTISING - 243, // 1542 -> MEDIUM_UNAVAILABLE_NSD_NOT_AVAILABLE - 240, // 1543 -> MEDIUM_UNAVAILABLE_MDNS_NOT_AVAILABLE - 234, // 1544 -> MEDIUM_UNAVAILABLE_LAN_BLOCKED - 244, // 1545 -> MEDIUM_UNAVAILABLE_POOR_SIGNAL - 229, // 1546 -> MEDIUM_UNAVAILABLE_BT_MULTIPLEX_DISABLED - 225, // 1547 -> MEDIUM_UNAVAILABLE_AWDL_NOT_AVAILABLE + 240, // 1000 -> DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS + 241, // 1001 -> DEVICE_STATE_ERROR_USER_HOTSPOT_ENABLED + 242, // 1002 -> DEVICE_STATE_LOCATION_DISABLED + 243, // 1003 -> DEVICE_STATE_RADIO_DISABLING_FAILURE + 244, // 1004 -> DEVICE_STATE_RADIO_ENABLING_FAILURE + 301, // 1500 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_RESOURCE_NOT_AVAILABLE + 268, // 1501 -> MEDIUM_UNAVAILABLE_DIRECT_HOTSPOT_NOT_SUPPORT + 284, // 1502 -> MEDIUM_UNAVAILABLE_SOFT_AP_NOT_SUPPORT + 275, // 1503 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_NOT_SUPPORT + 276, // 1504 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_NOT_SUPPORT_5G + 264, // 1505 -> MEDIUM_UNAVAILABLE_BLE_NOT_AVAILABLE + 270, // 1506 -> MEDIUM_UNAVAILABLE_L2CAP_NOT_AVAILABLE + 265, // 1507 -> MEDIUM_UNAVAILABLE_BLUETOOTH_NOT_AVAILABLE + 297, // 1508 -> MEDIUM_UNAVAILABLE_WEB_RTC_NOT_AVAILABLE + 300, // 1509 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_NOT_AVAILABLE + 306, // 1510 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_NOT_AVAILABLE + 303, // 1511 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_NOT_AVAILABLE + 279, // 1512 -> MEDIUM_UNAVAILABLE_NFC_NOT_AVAILABLE + 273, // 1513 -> MEDIUM_UNAVAILABLE_LAN_NOT_AVAILABLE + 295, // 1514 -> MEDIUM_UNAVAILABLE_USB_NOT_AVAILABLE + 263, // 1515 -> MEDIUM_UNAVAILABLE_BLE_NC_LOGICAL_NOT_AVAILABLE + 267, // 1516 -> MEDIUM_UNAVAILABLE_BT_NC_LOGICAL_NOT_AVAILABLE + 272, // 1517 -> MEDIUM_UNAVAILABLE_LAN_NC_LOGICAL_NOT_AVAILABLE + 278, // 1518 -> MEDIUM_UNAVAILABLE_NFC_NC_LOGICAL_NOT_AVAILABLE + 294, // 1519 -> MEDIUM_UNAVAILABLE_USB_NC_LOGICAL_NOT_AVAILABLE + 296, // 1520 -> MEDIUM_UNAVAILABLE_WEB_RTC_NC_LOGICAL_NOT_AVAILABLE + 299, // 1521 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_NC_LOGICAL_NOT_AVAILABLE + 305, // 1522 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_NC_LOGICAL_NOT_AVAILABLE + 302, // 1523 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_NC_LOGICAL_NOT_AVAILABLE + 307, // 1524 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_P2P_RESOURCE_NOT_AVAILABLE + 304, // 1525 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_P2P_RESOURCE_NOT_AVAILABLE + 288, // 1526 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_BLE_LOW_QUALITY_MEDIUMS + 290, // 1527 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_L2CAP_LOW_QUALITY_MEDIUMS + 293, // 1528 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_WEB_RTC_LOW_QUALITY_MEDIUMS + 291, // 1529 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_LAN_LOW_QUALITY_MEDIUMS + 289, // 1530 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_BT_LOW_QUALITY_MEDIUMS + 292, // 1531 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_USB_LOW_QUALITY_MEDIUMS + 274, // 1532 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_DISRUPTIVE_FALSE + 283, // 1533 -> MEDIUM_UNAVAILABLE_SOFT_AP_DISRUPTIVE_FALSE + 260, // 1534 -> MEDIUM_UNAVAILABLE_ALREADY_HAVE_A_WIFI_DIRECT_GROUP + 261, // 1535 -> MEDIUM_UNAVAILABLE_ALREADY_HOSTING_HOTSPOT_FOR_OTHER_CLIENTS + 282, // 1536 -> MEDIUM_UNAVAILABLE_REJECT_L2CAP_ON_GATT_MULTIPLEX_CONNECTION + 287, // 1537 -> MEDIUM_UNAVAILABLE_UPGRADE_ON_SAME_MEDIUM + 298, // 1538 -> MEDIUM_UNAVAILABLE_WEB_RTC_NO_INTERNET + 285, // 1539 -> MEDIUM_UNAVAILABLE_STA_DISRUPTIVE_FALSE + 286, // 1540 -> MEDIUM_UNAVAILABLE_STA_USER_NOT_ALLOW + 269, // 1541 -> MEDIUM_UNAVAILABLE_DUPLICATE_FAST_ADVERTISING + 280, // 1542 -> MEDIUM_UNAVAILABLE_NSD_NOT_AVAILABLE + 277, // 1543 -> MEDIUM_UNAVAILABLE_MDNS_NOT_AVAILABLE + 271, // 1544 -> MEDIUM_UNAVAILABLE_LAN_BLOCKED + 281, // 1545 -> MEDIUM_UNAVAILABLE_POOR_SIGNAL + 266, // 1546 -> MEDIUM_UNAVAILABLE_BT_MULTIPLEX_DISABLED + 262, // 1547 -> MEDIUM_UNAVAILABLE_AWDL_NOT_AVAILABLE 60, // 2000 -> CLIENT_WIFI_DIRECT_ALREADY_HOSTING_DIRECT_GROUP_FOR_THIS_CLIENT 61, // 2001 -> CLIENT_WIFI_HOTSPOT_ALREADY_HOSTING_HOTSPOT_FOR_THIS_CLIENT 37, // 2002 -> CLIENT_DUPLICATE_ACCEPTING_BLE_CONNECTION_REQUEST @@ -2285,38 +2362,38 @@ static const int OperationResultCode_entries_by_number[] = { 2, // 2036 -> CLIENT_AWDL_DUPLICATE_ADVERTISING 3, // 2037 -> CLIENT_AWDL_DUPLICATE_DISCOVERING 36, // 2038 -> CLIENT_DUPLICATE_ACCEPTING_AWDL_CONNECTION_REQUEST - 273, // 2500 -> MISCELLEANEOUS_BLUETOOTH_MAC_ADDRESS_NULL - 277, // 2501 -> MISCELLEANEOUS_MOVE_TO_NEW_MEDIUM - 284, // 2502 -> MISCELLEANEOUS_WIFI_HOTSPOT_SOFT_AP_BLOCKED_BY_PROVISION - 271, // 2503 -> MISCELLEANEOUS_BLE_SYSTEM_SERVICE_NULL - 276, // 2504 -> MISCELLEANEOUS_L2CAP_SYSTEM_SERVICE_NULL - 275, // 2505 -> MISCELLEANEOUS_BT_SYSTEM_SERVICE_NULL - 282, // 2506 -> MISCELLEANEOUS_WIFI_AWARE_SYSTEM_SERVICE_NULL - 283, // 2507 -> MISCELLEANEOUS_WIFI_DIRECT_SYSTEM_SERVICE_NULL - 286, // 2508 -> MISCELLEANEOUS_WIFI_LAN_SYSTEM_SERVICE_NULL - 285, // 2509 -> MISCELLEANEOUS_WIFI_HOTSPOT_SYSTEM_SERVICE_NULL - 274, // 2510 -> MISCELLEANEOUS_BT_NOT_ACCEPTING_CONNECTION_FOR_WORK_PROFILE - 279, // 2511 -> MISCELLEANEOUS_WEB_RTC_GET_DROIDGUARD_RESULT_FAILURE - 281, // 2512 -> MISCELLEANEOUS_WEB_RTC_TACHYON_SIGNALING_MESSENGER_NULL - 278, // 2513 -> MISCELLEANEOUS_WEB_RTC_FAILED_TO_RECEIVE_MESSAGE - 272, // 2514 -> MISCELLEANEOUS_BLUETOOTH_CHANGE_DEVICE_NAME_FAILURE - 280, // 2515 -> MISCELLEANEOUS_WEB_RTC_ICE_SERVER_NULL - 287, // 2516 -> MISCELLEANEOUS_WORK_SOURCE_NULL - 218, // 3000 -> IO_FILE_OPENING_ERROR - 219, // 3001 -> IO_FILE_READING_ERROR - 220, // 3002 -> IO_FILE_WRITING_ERROR - 221, // 3003 -> IO_FOLDER_CREATION_ERROR - 222, // 3004 -> IO_STREAM_CREATE_PIPE_FAILURE - 208, // 3005 -> IO_ENDPOINT_IO_ERROR_ON_BLE - 209, // 3006 -> IO_ENDPOINT_IO_ERROR_ON_BLE_L2CAP - 210, // 3007 -> IO_ENDPOINT_IO_ERROR_ON_BT - 214, // 3008 -> IO_ENDPOINT_IO_ERROR_ON_WEB_RTC - 211, // 3009 -> IO_ENDPOINT_IO_ERROR_ON_LAN - 216, // 3010 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_DIRECT - 217, // 3011 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_HOTSPOT - 215, // 3012 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_AWARE - 212, // 3013 -> IO_ENDPOINT_IO_ERROR_ON_NFC - 213, // 3014 -> IO_ENDPOINT_IO_ERROR_ON_USB + 310, // 2500 -> MISCELLEANEOUS_BLUETOOTH_MAC_ADDRESS_NULL + 314, // 2501 -> MISCELLEANEOUS_MOVE_TO_NEW_MEDIUM + 321, // 2502 -> MISCELLEANEOUS_WIFI_HOTSPOT_SOFT_AP_BLOCKED_BY_PROVISION + 308, // 2503 -> MISCELLEANEOUS_BLE_SYSTEM_SERVICE_NULL + 313, // 2504 -> MISCELLEANEOUS_L2CAP_SYSTEM_SERVICE_NULL + 312, // 2505 -> MISCELLEANEOUS_BT_SYSTEM_SERVICE_NULL + 319, // 2506 -> MISCELLEANEOUS_WIFI_AWARE_SYSTEM_SERVICE_NULL + 320, // 2507 -> MISCELLEANEOUS_WIFI_DIRECT_SYSTEM_SERVICE_NULL + 323, // 2508 -> MISCELLEANEOUS_WIFI_LAN_SYSTEM_SERVICE_NULL + 322, // 2509 -> MISCELLEANEOUS_WIFI_HOTSPOT_SYSTEM_SERVICE_NULL + 311, // 2510 -> MISCELLEANEOUS_BT_NOT_ACCEPTING_CONNECTION_FOR_WORK_PROFILE + 316, // 2511 -> MISCELLEANEOUS_WEB_RTC_GET_DROIDGUARD_RESULT_FAILURE + 318, // 2512 -> MISCELLEANEOUS_WEB_RTC_TACHYON_SIGNALING_MESSENGER_NULL + 315, // 2513 -> MISCELLEANEOUS_WEB_RTC_FAILED_TO_RECEIVE_MESSAGE + 309, // 2514 -> MISCELLEANEOUS_BLUETOOTH_CHANGE_DEVICE_NAME_FAILURE + 317, // 2515 -> MISCELLEANEOUS_WEB_RTC_ICE_SERVER_NULL + 324, // 2516 -> MISCELLEANEOUS_WORK_SOURCE_NULL + 255, // 3000 -> IO_FILE_OPENING_ERROR + 256, // 3001 -> IO_FILE_READING_ERROR + 257, // 3002 -> IO_FILE_WRITING_ERROR + 258, // 3003 -> IO_FOLDER_CREATION_ERROR + 259, // 3004 -> IO_STREAM_CREATE_PIPE_FAILURE + 245, // 3005 -> IO_ENDPOINT_IO_ERROR_ON_BLE + 246, // 3006 -> IO_ENDPOINT_IO_ERROR_ON_BLE_L2CAP + 247, // 3007 -> IO_ENDPOINT_IO_ERROR_ON_BT + 251, // 3008 -> IO_ENDPOINT_IO_ERROR_ON_WEB_RTC + 248, // 3009 -> IO_ENDPOINT_IO_ERROR_ON_LAN + 253, // 3010 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_DIRECT + 254, // 3011 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_HOTSPOT + 252, // 3012 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_AWARE + 249, // 3013 -> IO_ENDPOINT_IO_ERROR_ON_NFC + 250, // 3014 -> IO_ENDPOINT_IO_ERROR_ON_USB 135, // 3500 -> CONNECTIVITY_WIFI_AWARE_ATTACH_FAILURE 78, // 3501 -> CONNECTIVITY_BLUETOOTH_DEVICE_OBTAIN_FAILURE 71, // 3502 -> CONNECTIVITY_BLE_CLIENT_SOCKET_CREATION_FAILURE @@ -2428,162 +2505,199 @@ static const int OperationResultCode_entries_by_number[] = { 138, // 3608 -> CONNECTIVITY_WIFI_AWARE_DISCOVER_PEER_NULL_SCREEN_OFF 139, // 3609 -> CONNECTIVITY_WIFI_AWARE_DISCOVER_PEER_NULL_TIMEOUT 144, // 3610 -> CONNECTIVITY_WIFI_AWARE_JOIN_NETWORK_FAILED - 292, // 4500 -> NEARBY_BLE_ADVERTISEMENT_MAPPING_TO_MAC_ERROR - 302, // 4501 -> NEARBY_BLUETOOTH_MAC_ADDRESS_INVALID_FOR_CONNECT - 362, // 4502 -> NEARBY_WEB_RTC_CONNECTION_FLOW_NULL - 316, // 4503 -> NEARBY_GENERIC_CONNECTION_CLOSED - 294, // 4504 -> NEARBY_BLE_ENDPOINT_CHANNEL_CREATION_FAILURE - 334, // 4505 -> NEARBY_L2CAP_ENDPOINT_CHANNEL_CREATION_FAILURE - 305, // 4506 -> NEARBY_BT_ENDPOINT_CHANNEL_CREATION_FAILURE - 338, // 4507 -> NEARBY_LAN_ENDPOINT_CHANNEL_CREATION_FAILURE - 349, // 4508 -> NEARBY_NFC_ENDPOINT_CHANNEL_CREATION_FAILURE - 370, // 4509 -> NEARBY_WIFI_AWARE_ENDPOINT_CHANNEL_CREATION_FAILURE - 388, // 4510 -> NEARBY_WIFI_HOTSPOT_ENDPOINT_CHANNEL_CREATION_FAILURE - 375, // 4511 -> NEARBY_WIFI_DIRECT_ENDPOINT_CHANNEL_CREATION_FAILURE - 363, // 4512 -> NEARBY_WEB_RTC_ENDPOINT_CHANNEL_CREATION_FAILURE - 358, // 4513 -> NEARBY_USB_ENDPOINT_CHANNEL_CREATION_FAILURE - 317, // 4514 -> NEARBY_GENERIC_ENDPOINT_UNENCRYPTED - 296, // 4515 -> NEARBY_BLE_GATT_ADVERTISEMENT_NULL_FOR_CONNECTION - 376, // 4516 -> NEARBY_WIFI_DIRECT_HOST_ON_SRD_CHANNELS - 389, // 4517 -> NEARBY_WIFI_HOTSPOT_HOST_ON_SRD_CHANNELS - 297, // 4518 -> NEARBY_BLE_GATT_NULL_CALLBACK - 335, // 4519 -> NEARBY_L2CAP_NULL_CALLBACK - 307, // 4520 -> NEARBY_BT_NULL_CALLBACK - 360, // 4521 -> NEARBY_USB_NULL_CALLBACK - 351, // 4522 -> NEARBY_NFC_NULL_CALLBACK - 372, // 4523 -> NEARBY_WIFI_AWARE_NULL_CALLBACK - 366, // 4524 -> NEARBY_WEB_RTC_NULL_CALLBACK - 340, // 4525 -> NEARBY_LAN_NULL_CALLBACK - 392, // 4526 -> NEARBY_WIFI_HOTSPOT_NULL_CALLBACK - 378, // 4527 -> NEARBY_WIFI_DIRECT_NULL_CALLBACK - 380, // 4528 -> NEARBY_WIFI_DIRECT_NULL_SSID - 379, // 4529 -> NEARBY_WIFI_DIRECT_NULL_PASSWORD - 306, // 4530 -> NEARBY_BT_MULTIPLEX_SOCKET_DISABLED - 339, // 4531 -> NEARBY_LAN_MULTIPLEX_SOCKET_DISABLED - 320, // 4532 -> NEARBY_GENERIC_NEW_ENDPOINT_CHANNEL_NULL - 377, // 4533 -> NEARBY_WIFI_DIRECT_NO_GROUP_FOR_LISTENING - 391, // 4534 -> NEARBY_WIFI_HOTSPOT_NO_HOTSPOT_FOR_LISTENING - 321, // 4535 -> NEARBY_GENERIC_OLD_ENDPOINT_CHANNEL_NULL - 299, // 4536 -> NEARBY_BLE_OPERATION_REGISTERED_FAILED - 336, // 4537 -> NEARBY_L2CAP_OPERATION_REGISTERED_FAILED - 308, // 4538 -> NEARBY_BT_OPERATION_REGISTERED_FAILED - 341, // 4539 -> NEARBY_LAN_OPERATION_REGISTERED_FAILED - 367, // 4540 -> NEARBY_WEB_RTC_OPERATION_REGISTERED_FAILED - 373, // 4541 -> NEARBY_WIFI_AWARE_OPERATION_REGISTERED_FAILED - 387, // 4542 -> NEARBY_WIFI_HOTSPOT_DIRECT_OPERATION_REGISTERED_FAILED - 397, // 4543 -> NEARBY_WIFI_HOTSPOT_SOFT_AP_OPERATION_REGISTERED_FAILED - 390, // 4544 -> NEARBY_WIFI_HOTSPOT_LOHS_OPERATION_REGISTERED_FAILED - 386, // 4545 -> NEARBY_WIFI_HOTSPOT_CLIENT_OPERATION_REGISTERED_FAILED - 381, // 4546 -> NEARBY_WIFI_DIRECT_OPERATION_REGISTERED_FAILED - 322, // 4547 -> NEARBY_GENERIC_OUTGOING_PAYLOAD_CREATION_FAILURE - 393, // 4548 -> NEARBY_WIFI_HOTSPOT_P2P_NON_DBS_WANT_2G_BUT_AP_5G - 382, // 4549 -> NEARBY_WIFI_DIRECT_P2P_NON_DBS_WANT_2G_BUT_AP_5G - 394, // 4550 -> NEARBY_WIFI_HOTSPOT_P2P_NON_DBS_WANT_5G_BUT_AP_2G - 383, // 4551 -> NEARBY_WIFI_DIRECT_P2P_NON_DBS_WANT_5G_BUT_AP_2G - 319, // 4552 -> NEARBY_GENERIC_INCOMING_PAYLOAD_NOT_DATA_TYPE - 326, // 4553 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_EVENT_TYPE_ERROR - 328, // 4554 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_FRAME_TYPE_ERROR - 327, // 4555 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_FORMAT_ERROR - 323, // 4556 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_EVENT_TYPE_ERROR - 325, // 4557 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_FRAME_TYPE_ERROR - 324, // 4558 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_FORMAT_ERROR - 329, // 4559 -> NEARBY_GENERIC_REMOTE_ENDPOINT_STATUS_ERROR - 330, // 4560 -> NEARBY_GENERIC_REMOTE_REPORT_PAYLOADS_ERROR - 331, // 4561 -> NEARBY_GENERIC_REMOTE_UPGRADE_FAILURE - 332, // 4562 -> NEARBY_GENERIC_SEND_PAYLOAD_EXECUTOR_NULL - 309, // 4563 -> NEARBY_BT_VIRTUAL_SOCKET_CREATION_FAILURE - 344, // 4564 -> NEARBY_LAN_VIRTUAL_SOCKET_CREATION_FAILURE - 400, // 4565 -> NEARBY_WIFI_LAN_IP_ADDRESS_ERROR - 337, // 4566 -> NEARBY_L2CAP_PSM_NOT_POSITIVE - 314, // 4567 -> NEARBY_ENCRYPTION_FAILURE - 288, // 4568 -> NEARBY_AUTHENTICATION_FAILURE - 345, // 4569 -> NEARBY_LAN_VIRTUAL_SOCKET_NULL - 300, // 4570 -> NEARBY_BLUETOOTH_ADVERTISE_TO_BYTES_FAILURE - 293, // 4571 -> NEARBY_BLE_ADVERTISE_TO_BYTES_FAILURE - 295, // 4572 -> NEARBY_BLE_FAST_ADVERTISE_TO_BYTES_FAILURE - 348, // 4573 -> NEARBY_NFC_ADVERTISE_TO_BYTES_FAILURE - 398, // 4574 -> NEARBY_WIFI_LAN_ADVERTISE_TO_BYTES_FAILURE - 369, // 4575 -> NEARBY_WIFI_AWARE_ADVERTISE_TO_BYTES_FAILURE - 357, // 4576 -> NEARBY_USB_ADVERTISE_TO_BYTES_FAILURE - 350, // 4577 -> NEARBY_NFC_INVALID_PCP_OPTIONS - 301, // 4578 -> NEARBY_BLUETOOTH_INVALID_PCP_OPTIONS - 298, // 4579 -> NEARBY_BLE_INVALID_PCP_OPTIONS - 399, // 4580 -> NEARBY_WIFI_LAN_INVALID_PCP_OPTIONS - 371, // 4581 -> NEARBY_WIFI_AWARE_INVALID_PCP_OPTIONS - 359, // 4582 -> NEARBY_USB_INVALID_PCP_OPTIONS - 361, // 4583 -> NEARBY_UWB_INVALID_PCP_OPTIONS - 364, // 4584 -> NEARBY_WEB_RTC_INVALID_PCP_OPTIONS - 303, // 4585 -> NEARBY_BLUETOOTH_NO_CLIENT_REGISTER_FOR_SCAN - 333, // 4586 -> NEARBY_INSTANT_CONNECTION_WRONG_CONNECTIVITY_INFO - 347, // 4587 -> NEARBY_NEED_METHOD_OVERRIDE - 318, // 4588 -> NEARBY_GENERIC_INCOMING_PAYLOAD_CREATION_FAILURE - 365, // 4589 -> NEARBY_WEB_RTC_NO_LISTENING_PEER_FOUND - 356, // 4590 -> NEARBY_UPGRADE_PATH_ON_WRONG_MEDIUM - 313, // 4591 -> NEARBY_CONNECT_TO_ALL_MEDIUMS_FAILURE - 304, // 4592 -> NEARBY_BLUETOOTH_RECONNECT_MAC_NULL - 342, // 4593 -> NEARBY_LAN_RECONNECT_CONNECTION_INFO_NULL - 343, // 4594 -> NEARBY_LAN_RECONNECT_IP_NULL - 385, // 4595 -> NEARBY_WIFI_DIRECT_RECONNECT_META_DATA_NULL - 384, // 4596 -> NEARBY_WIFI_DIRECT_RECONNECT_CONNECT_META_DATA_NULL - 396, // 4597 -> NEARBY_WIFI_HOTSPOT_RECONNECT_META_DATA_NULL - 395, // 4598 -> NEARBY_WIFI_HOTSPOT_RECONNECT_CONNECT_META_DATA_NULL - 368, // 4599 -> NEARBY_WEB_RTC_RECONNECT_PEER_ID_NULL - 374, // 4600 -> NEARBY_WIFI_AWARE_RECONNECT_META_DATA_NULL - 352, // 4601 -> NEARBY_NOT_ADVERTISING_OR_LISTENING - 310, // 4602 -> NEARBY_CAN_NOT_OBTAIN_DEVICE_PROVIDER - 354, // 4603 -> NEARBY_SETUP_STRATEGY_FAILURE - 355, // 4604 -> NEARBY_TX_ADVERTISEMENT_NULL - 315, // 4605 -> NEARBY_ENDPOINT_ID_MISMATCH - 312, // 4606 -> NEARBY_CONNECTIVITY_INFO_NULL_OR_WRONG - 346, // 4607 -> NEARBY_LOCAL_CLIENT_STATE_WRONG - 353, // 4608 -> NEARBY_REMOTE_EXCEPTION_WHEN_PROCESSING_RECEIVED_PAYLOAD - 291, // 4609 -> NEARBY_BAD_FILE_DESCRIPTION_WHEN_PROCESSING_RECEIVED_PAYLOAD - 311, // 4610 -> NEARBY_CONNECTION_LISTENER_NULL - 289, // 4611 -> NEARBY_AWDL_ADVERTISE_TO_BYTES_FAILURE - 290, // 4612 -> NEARBY_AWDL_ENDPOINT_CHANNEL_CREATION_FAILURE + 329, // 4500 -> NEARBY_BLE_ADVERTISEMENT_MAPPING_TO_MAC_ERROR + 339, // 4501 -> NEARBY_BLUETOOTH_MAC_ADDRESS_INVALID_FOR_CONNECT + 399, // 4502 -> NEARBY_WEB_RTC_CONNECTION_FLOW_NULL + 353, // 4503 -> NEARBY_GENERIC_CONNECTION_CLOSED + 331, // 4504 -> NEARBY_BLE_ENDPOINT_CHANNEL_CREATION_FAILURE + 371, // 4505 -> NEARBY_L2CAP_ENDPOINT_CHANNEL_CREATION_FAILURE + 342, // 4506 -> NEARBY_BT_ENDPOINT_CHANNEL_CREATION_FAILURE + 375, // 4507 -> NEARBY_LAN_ENDPOINT_CHANNEL_CREATION_FAILURE + 386, // 4508 -> NEARBY_NFC_ENDPOINT_CHANNEL_CREATION_FAILURE + 407, // 4509 -> NEARBY_WIFI_AWARE_ENDPOINT_CHANNEL_CREATION_FAILURE + 425, // 4510 -> NEARBY_WIFI_HOTSPOT_ENDPOINT_CHANNEL_CREATION_FAILURE + 412, // 4511 -> NEARBY_WIFI_DIRECT_ENDPOINT_CHANNEL_CREATION_FAILURE + 400, // 4512 -> NEARBY_WEB_RTC_ENDPOINT_CHANNEL_CREATION_FAILURE + 395, // 4513 -> NEARBY_USB_ENDPOINT_CHANNEL_CREATION_FAILURE + 354, // 4514 -> NEARBY_GENERIC_ENDPOINT_UNENCRYPTED + 333, // 4515 -> NEARBY_BLE_GATT_ADVERTISEMENT_NULL_FOR_CONNECTION + 413, // 4516 -> NEARBY_WIFI_DIRECT_HOST_ON_SRD_CHANNELS + 426, // 4517 -> NEARBY_WIFI_HOTSPOT_HOST_ON_SRD_CHANNELS + 334, // 4518 -> NEARBY_BLE_GATT_NULL_CALLBACK + 372, // 4519 -> NEARBY_L2CAP_NULL_CALLBACK + 344, // 4520 -> NEARBY_BT_NULL_CALLBACK + 397, // 4521 -> NEARBY_USB_NULL_CALLBACK + 388, // 4522 -> NEARBY_NFC_NULL_CALLBACK + 409, // 4523 -> NEARBY_WIFI_AWARE_NULL_CALLBACK + 403, // 4524 -> NEARBY_WEB_RTC_NULL_CALLBACK + 377, // 4525 -> NEARBY_LAN_NULL_CALLBACK + 429, // 4526 -> NEARBY_WIFI_HOTSPOT_NULL_CALLBACK + 415, // 4527 -> NEARBY_WIFI_DIRECT_NULL_CALLBACK + 417, // 4528 -> NEARBY_WIFI_DIRECT_NULL_SSID + 416, // 4529 -> NEARBY_WIFI_DIRECT_NULL_PASSWORD + 343, // 4530 -> NEARBY_BT_MULTIPLEX_SOCKET_DISABLED + 376, // 4531 -> NEARBY_LAN_MULTIPLEX_SOCKET_DISABLED + 357, // 4532 -> NEARBY_GENERIC_NEW_ENDPOINT_CHANNEL_NULL + 414, // 4533 -> NEARBY_WIFI_DIRECT_NO_GROUP_FOR_LISTENING + 428, // 4534 -> NEARBY_WIFI_HOTSPOT_NO_HOTSPOT_FOR_LISTENING + 358, // 4535 -> NEARBY_GENERIC_OLD_ENDPOINT_CHANNEL_NULL + 336, // 4536 -> NEARBY_BLE_OPERATION_REGISTERED_FAILED + 373, // 4537 -> NEARBY_L2CAP_OPERATION_REGISTERED_FAILED + 345, // 4538 -> NEARBY_BT_OPERATION_REGISTERED_FAILED + 378, // 4539 -> NEARBY_LAN_OPERATION_REGISTERED_FAILED + 404, // 4540 -> NEARBY_WEB_RTC_OPERATION_REGISTERED_FAILED + 410, // 4541 -> NEARBY_WIFI_AWARE_OPERATION_REGISTERED_FAILED + 424, // 4542 -> NEARBY_WIFI_HOTSPOT_DIRECT_OPERATION_REGISTERED_FAILED + 434, // 4543 -> NEARBY_WIFI_HOTSPOT_SOFT_AP_OPERATION_REGISTERED_FAILED + 427, // 4544 -> NEARBY_WIFI_HOTSPOT_LOHS_OPERATION_REGISTERED_FAILED + 423, // 4545 -> NEARBY_WIFI_HOTSPOT_CLIENT_OPERATION_REGISTERED_FAILED + 418, // 4546 -> NEARBY_WIFI_DIRECT_OPERATION_REGISTERED_FAILED + 359, // 4547 -> NEARBY_GENERIC_OUTGOING_PAYLOAD_CREATION_FAILURE + 430, // 4548 -> NEARBY_WIFI_HOTSPOT_P2P_NON_DBS_WANT_2G_BUT_AP_5G + 419, // 4549 -> NEARBY_WIFI_DIRECT_P2P_NON_DBS_WANT_2G_BUT_AP_5G + 431, // 4550 -> NEARBY_WIFI_HOTSPOT_P2P_NON_DBS_WANT_5G_BUT_AP_2G + 420, // 4551 -> NEARBY_WIFI_DIRECT_P2P_NON_DBS_WANT_5G_BUT_AP_2G + 356, // 4552 -> NEARBY_GENERIC_INCOMING_PAYLOAD_NOT_DATA_TYPE + 363, // 4553 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_EVENT_TYPE_ERROR + 365, // 4554 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_FRAME_TYPE_ERROR + 364, // 4555 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_FORMAT_ERROR + 360, // 4556 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_EVENT_TYPE_ERROR + 362, // 4557 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_FRAME_TYPE_ERROR + 361, // 4558 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_FORMAT_ERROR + 366, // 4559 -> NEARBY_GENERIC_REMOTE_ENDPOINT_STATUS_ERROR + 367, // 4560 -> NEARBY_GENERIC_REMOTE_REPORT_PAYLOADS_ERROR + 368, // 4561 -> NEARBY_GENERIC_REMOTE_UPGRADE_FAILURE + 369, // 4562 -> NEARBY_GENERIC_SEND_PAYLOAD_EXECUTOR_NULL + 346, // 4563 -> NEARBY_BT_VIRTUAL_SOCKET_CREATION_FAILURE + 381, // 4564 -> NEARBY_LAN_VIRTUAL_SOCKET_CREATION_FAILURE + 437, // 4565 -> NEARBY_WIFI_LAN_IP_ADDRESS_ERROR + 374, // 4566 -> NEARBY_L2CAP_PSM_NOT_POSITIVE + 351, // 4567 -> NEARBY_ENCRYPTION_FAILURE + 325, // 4568 -> NEARBY_AUTHENTICATION_FAILURE + 382, // 4569 -> NEARBY_LAN_VIRTUAL_SOCKET_NULL + 337, // 4570 -> NEARBY_BLUETOOTH_ADVERTISE_TO_BYTES_FAILURE + 330, // 4571 -> NEARBY_BLE_ADVERTISE_TO_BYTES_FAILURE + 332, // 4572 -> NEARBY_BLE_FAST_ADVERTISE_TO_BYTES_FAILURE + 385, // 4573 -> NEARBY_NFC_ADVERTISE_TO_BYTES_FAILURE + 435, // 4574 -> NEARBY_WIFI_LAN_ADVERTISE_TO_BYTES_FAILURE + 406, // 4575 -> NEARBY_WIFI_AWARE_ADVERTISE_TO_BYTES_FAILURE + 394, // 4576 -> NEARBY_USB_ADVERTISE_TO_BYTES_FAILURE + 387, // 4577 -> NEARBY_NFC_INVALID_PCP_OPTIONS + 338, // 4578 -> NEARBY_BLUETOOTH_INVALID_PCP_OPTIONS + 335, // 4579 -> NEARBY_BLE_INVALID_PCP_OPTIONS + 436, // 4580 -> NEARBY_WIFI_LAN_INVALID_PCP_OPTIONS + 408, // 4581 -> NEARBY_WIFI_AWARE_INVALID_PCP_OPTIONS + 396, // 4582 -> NEARBY_USB_INVALID_PCP_OPTIONS + 398, // 4583 -> NEARBY_UWB_INVALID_PCP_OPTIONS + 401, // 4584 -> NEARBY_WEB_RTC_INVALID_PCP_OPTIONS + 340, // 4585 -> NEARBY_BLUETOOTH_NO_CLIENT_REGISTER_FOR_SCAN + 370, // 4586 -> NEARBY_INSTANT_CONNECTION_WRONG_CONNECTIVITY_INFO + 384, // 4587 -> NEARBY_NEED_METHOD_OVERRIDE + 355, // 4588 -> NEARBY_GENERIC_INCOMING_PAYLOAD_CREATION_FAILURE + 402, // 4589 -> NEARBY_WEB_RTC_NO_LISTENING_PEER_FOUND + 393, // 4590 -> NEARBY_UPGRADE_PATH_ON_WRONG_MEDIUM + 350, // 4591 -> NEARBY_CONNECT_TO_ALL_MEDIUMS_FAILURE + 341, // 4592 -> NEARBY_BLUETOOTH_RECONNECT_MAC_NULL + 379, // 4593 -> NEARBY_LAN_RECONNECT_CONNECTION_INFO_NULL + 380, // 4594 -> NEARBY_LAN_RECONNECT_IP_NULL + 422, // 4595 -> NEARBY_WIFI_DIRECT_RECONNECT_META_DATA_NULL + 421, // 4596 -> NEARBY_WIFI_DIRECT_RECONNECT_CONNECT_META_DATA_NULL + 433, // 4597 -> NEARBY_WIFI_HOTSPOT_RECONNECT_META_DATA_NULL + 432, // 4598 -> NEARBY_WIFI_HOTSPOT_RECONNECT_CONNECT_META_DATA_NULL + 405, // 4599 -> NEARBY_WEB_RTC_RECONNECT_PEER_ID_NULL + 411, // 4600 -> NEARBY_WIFI_AWARE_RECONNECT_META_DATA_NULL + 389, // 4601 -> NEARBY_NOT_ADVERTISING_OR_LISTENING + 347, // 4602 -> NEARBY_CAN_NOT_OBTAIN_DEVICE_PROVIDER + 391, // 4603 -> NEARBY_SETUP_STRATEGY_FAILURE + 392, // 4604 -> NEARBY_TX_ADVERTISEMENT_NULL + 352, // 4605 -> NEARBY_ENDPOINT_ID_MISMATCH + 349, // 4606 -> NEARBY_CONNECTIVITY_INFO_NULL_OR_WRONG + 383, // 4607 -> NEARBY_LOCAL_CLIENT_STATE_WRONG + 390, // 4608 -> NEARBY_REMOTE_EXCEPTION_WHEN_PROCESSING_RECEIVED_PAYLOAD + 328, // 4609 -> NEARBY_BAD_FILE_DESCRIPTION_WHEN_PROCESSING_RECEIVED_PAYLOAD + 348, // 4610 -> NEARBY_CONNECTION_LISTENER_NULL + 326, // 4611 -> NEARBY_AWDL_ADVERTISE_TO_BYTES_FAILURE + 327, // 4612 -> NEARBY_AWDL_ENDPOINT_CHANNEL_CREATION_FAILURE 177, // 5000 -> DCT_ERROR_BLE_DISABLED 176, // 5001 -> DCT_ERROR_BLE_ADV_FAILED 178, // 5002 -> DCT_ERROR_BLE_SCAN_FAILED - 187, // 5003 -> DCT_ERROR_L2CAP_SERVER_FAILED - 186, // 5004 -> DCT_ERROR_L2CAP_CLIENT_FAILED - 188, // 5005 -> DCT_ERROR_MDNS_DISCOVERY_TIMEOUT - 189, // 5006 -> DCT_ERROR_MDNS_REGISTER_SERVICE - 184, // 5007 -> DCT_ERROR_INITIAL_TLS_SPAKE - 193, // 5008 -> DCT_ERROR_SUBSEQUENT_TLS_SPAKE - 190, // 5009 -> DCT_ERROR_REQUEST_FAILED - 191, // 5010 -> DCT_ERROR_RESPONSE_FAILED - 180, // 5011 -> DCT_ERROR_CONTROL_MESSAGE_EXCHANGE + 188, // 5003 -> DCT_ERROR_L2CAP_SERVER_FAILED + 187, // 5004 -> DCT_ERROR_L2CAP_CLIENT_FAILED + 191, // 5005 -> DCT_ERROR_MDNS_DISCOVERY_TIMEOUT + 192, // 5006 -> DCT_ERROR_MDNS_REGISTER_SERVICE + 185, // 5007 -> DCT_ERROR_INITIAL_TLS_SPAKE + 217, // 5008 -> DCT_ERROR_SUBSEQUENT_TLS_SPAKE + 214, // 5009 -> DCT_ERROR_REQUEST_FAILED + 215, // 5010 -> DCT_ERROR_RESPONSE_FAILED + 181, // 5011 -> DCT_ERROR_CONTROL_MESSAGE_EXCHANGE 179, // 5012 -> DCT_ERROR_CAPABILITY_MISMATCH - 182, // 5013 -> DCT_ERROR_HIGH_SPEED_MEDIUM_UNAVAILABLE - 198, // 5014 -> DCT_ERROR_WIFI_DISABLED - 199, // 5015 -> DCT_ERROR_WIFI_DISCONNECTED - 197, // 5016 -> DCT_ERROR_WIFI_CREDENTIAL_TRANSFER - 200, // 5017 -> DCT_ERROR_WIFI_INTERNET_CONNECTION - 195, // 5018 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED - 185, // 5019 -> DCT_ERROR_KEEPALIVE_TIMEOUT - 181, // 5020 -> DCT_ERROR_ESTABLISHED_CONNECTION_LOST - 196, // 5021 -> DCT_ERROR_USER_CANCELLED - 192, // 5022 -> DCT_ERROR_SERVICE_CANCELLED - 194, // 5023 -> DCT_ERROR_UNVERIFIED_INTEGRITY - 183, // 5024 -> DCT_ERROR_HTTP_SERVER_CLOSED + 183, // 5013 -> DCT_ERROR_HIGH_SPEED_MEDIUM_UNAVAILABLE + 235, // 5014 -> DCT_ERROR_WIFI_DISABLED + 236, // 5015 -> DCT_ERROR_WIFI_DISCONNECTED + 234, // 5016 -> DCT_ERROR_WIFI_CREDENTIAL_TRANSFER + 237, // 5017 -> DCT_ERROR_WIFI_INTERNET_CONNECTION + 219, // 5018 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED + 186, // 5019 -> DCT_ERROR_KEEPALIVE_TIMEOUT + 182, // 5020 -> DCT_ERROR_ESTABLISHED_CONNECTION_LOST + 233, // 5021 -> DCT_ERROR_USER_CANCELLED + 216, // 5022 -> DCT_ERROR_SERVICE_CANCELLED + 218, // 5023 -> DCT_ERROR_UNVERIFIED_INTEGRITY + 184, // 5024 -> DCT_ERROR_HTTP_SERVER_CLOSED + 180, // 5025 -> DCT_ERROR_CHECKIN_FAILURE + 198, // 5026 -> DCT_ERROR_REMOTE_ATTESTATION_TIMEOUT + 196, // 5027 -> DCT_ERROR_REMOTE_ATTESTATION_NULL_PACKET + 197, // 5028 -> DCT_ERROR_REMOTE_ATTESTATION_STATUS_NOT_AVAILABLE + 195, // 5029 -> DCT_ERROR_REMOTE_ATTESTATION_HASH_TOO_SHORT + 194, // 5030 -> DCT_ERROR_REMOTE_ATTESTATION_APPLE_INTEGRITY_UNAVAILABLE + 189, // 5031 -> DCT_ERROR_LOCAL_ATTESTATION_PLAY_INTEGRITY_UNAVAILABLE + 190, // 5032 -> DCT_ERROR_LOCAL_ATTESTATION_TIMEOUT + 193, // 5033 -> DCT_ERROR_PARALLEL_ATTESTATION_TIMEOUT + 202, // 5034 -> DCT_ERROR_REMOTE_MDNS_DISCOVERY_TIMEOUT + 203, // 5035 -> DCT_ERROR_REMOTE_MDNS_REGISTER_SERVICE + 204, // 5036 -> DCT_ERROR_REMOTE_REQUEST_FAILED + 205, // 5037 -> DCT_ERROR_REMOTE_RESPONSE_FAILED + 200, // 5038 -> DCT_ERROR_REMOTE_CONTROL_MESSAGE_EXCHANGE + 199, // 5039 -> DCT_ERROR_REMOTE_CAPABILITY_MISMATCH + 201, // 5040 -> DCT_ERROR_REMOTE_HIGH_SPEED_MEDIUM_UNAVAILABLE + 211, // 5041 -> DCT_ERROR_REMOTE_WIFI_DISABLED + 212, // 5042 -> DCT_ERROR_REMOTE_WIFI_DISCONNECTED + 210, // 5043 -> DCT_ERROR_REMOTE_WIFI_CREDENTIAL_TRANSFER + 213, // 5044 -> DCT_ERROR_REMOTE_WIFI_INTERNET_CONNECTION + 208, // 5045 -> DCT_ERROR_REMOTE_UPGRADE_HIGH_SPEED_MEDIUM_FAILED + 209, // 5046 -> DCT_ERROR_REMOTE_USER_CANCELLED + 206, // 5047 -> DCT_ERROR_REMOTE_SERVICE_CANCELLED + 207, // 5048 -> DCT_ERROR_REMOTE_UNVERIFIED_INTEGRITY + 224, // 5049 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_LOW_SPEED + 220, // 5050 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_CONNECTION + 231, // 5051 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NOT_PLUGGED + 230, // 5052 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NOT_HOST + 225, // 5053 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_MDNS_DISCOVERY_NOT_STARTED + 228, // 5054 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_NO_MEDIUM + 229, // 5055 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NETWORK_NOT_STARTED + 226, // 5056 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_MEDIUM_NEGOTIATION + 222, // 5057 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_HOST_NOT_STARTED + 221, // 5058 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_HOST_NETWORK_NOT_AVAILABLE + 227, // 5059 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_NO_INCOMING_HTTP_CONNECTION + 232, // 5060 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NO_CONNECTED_DEVICE + 223, // 5061 -> DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_INTERRUPTED }; const ::std::string& OperationResultCode_Name(OperationResultCode value) { static const bool kDummy = ::google::protobuf::internal::InitializeEnumStrings( - OperationResultCode_entries, OperationResultCode_entries_by_number, 401, + OperationResultCode_entries, OperationResultCode_entries_by_number, 438, OperationResultCode_strings); (void)kDummy; int idx = ::google::protobuf::internal::LookUpEnumName(OperationResultCode_entries, OperationResultCode_entries_by_number, - 401, value); + 438, value); return idx == -1 ? ::google::protobuf::internal::GetEmptyString() : OperationResultCode_strings[idx].get(); } bool OperationResultCode_Parse(::absl::string_view name, OperationResultCode* PROTOBUF_NONNULL value) { int int_value; bool success = ::google::protobuf::internal::LookUpEnumValue( - OperationResultCode_entries, 401, name, &int_value); + OperationResultCode_entries, 438, name, &int_value); if (success) { *value = static_cast(int_value); } diff --git a/compiled_proto/proto/connections_enums.pb.h b/compiled_proto/proto/connections_enums.pb.h index 0d0dcf74..097d4e90 100644 --- a/compiled_proto/proto/connections_enums.pb.h +++ b/compiled_proto/proto/connections_enums.pb.h @@ -324,18 +324,19 @@ bool Medium_Parse( enum WifiDirectAuthType : int { WIFI_DIRECT_TYPE_UNKNOWN = 0, WIFI_DIRECT_WITH_PASSWORD = 1, - WIFI_DIRECT_WITH_PIN = 2, + WIFI_DIRECT_WITH_PIN [[deprecated]] = 2, + WIFI_DIRECT_WITH_DEVICE_NAME = 3, }; extern const uint32_t WifiDirectAuthType_internal_data_[]; inline constexpr WifiDirectAuthType WifiDirectAuthType_MIN = static_cast(0); inline constexpr WifiDirectAuthType WifiDirectAuthType_MAX = - static_cast(2); + static_cast(3); inline bool WifiDirectAuthType_IsValid(int value) { - return 0 <= value && value <= 2; + return 0 <= value && value <= 3; } -inline constexpr int WifiDirectAuthType_ARRAYSIZE = 2 + 1; +inline constexpr int WifiDirectAuthType_ARRAYSIZE = 3 + 1; const ::std::string& WifiDirectAuthType_Name(WifiDirectAuthType value); template const ::std::string& WifiDirectAuthType_Name(T value) { @@ -1272,17 +1273,54 @@ enum OperationResultCode : int { DCT_ERROR_SERVICE_CANCELLED = 5022, DCT_ERROR_UNVERIFIED_INTEGRITY = 5023, DCT_ERROR_HTTP_SERVER_CLOSED = 5024, + DCT_ERROR_CHECKIN_FAILURE = 5025, + DCT_ERROR_REMOTE_ATTESTATION_TIMEOUT = 5026, + DCT_ERROR_REMOTE_ATTESTATION_NULL_PACKET = 5027, + DCT_ERROR_REMOTE_ATTESTATION_STATUS_NOT_AVAILABLE = 5028, + DCT_ERROR_REMOTE_ATTESTATION_HASH_TOO_SHORT = 5029, + DCT_ERROR_REMOTE_ATTESTATION_APPLE_INTEGRITY_UNAVAILABLE = 5030, + DCT_ERROR_LOCAL_ATTESTATION_PLAY_INTEGRITY_UNAVAILABLE = 5031, + DCT_ERROR_LOCAL_ATTESTATION_TIMEOUT = 5032, + DCT_ERROR_PARALLEL_ATTESTATION_TIMEOUT = 5033, + DCT_ERROR_REMOTE_MDNS_DISCOVERY_TIMEOUT = 5034, + DCT_ERROR_REMOTE_MDNS_REGISTER_SERVICE = 5035, + DCT_ERROR_REMOTE_REQUEST_FAILED = 5036, + DCT_ERROR_REMOTE_RESPONSE_FAILED = 5037, + DCT_ERROR_REMOTE_CONTROL_MESSAGE_EXCHANGE = 5038, + DCT_ERROR_REMOTE_CAPABILITY_MISMATCH = 5039, + DCT_ERROR_REMOTE_HIGH_SPEED_MEDIUM_UNAVAILABLE = 5040, + DCT_ERROR_REMOTE_WIFI_DISABLED = 5041, + DCT_ERROR_REMOTE_WIFI_DISCONNECTED = 5042, + DCT_ERROR_REMOTE_WIFI_CREDENTIAL_TRANSFER = 5043, + DCT_ERROR_REMOTE_WIFI_INTERNET_CONNECTION = 5044, + DCT_ERROR_REMOTE_UPGRADE_HIGH_SPEED_MEDIUM_FAILED = 5045, + DCT_ERROR_REMOTE_USER_CANCELLED = 5046, + DCT_ERROR_REMOTE_SERVICE_CANCELLED = 5047, + DCT_ERROR_REMOTE_UNVERIFIED_INTEGRITY = 5048, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_LOW_SPEED = 5049, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_CONNECTION = 5050, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NOT_PLUGGED = 5051, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NOT_HOST = 5052, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_MDNS_DISCOVERY_NOT_STARTED = 5053, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_NO_MEDIUM = 5054, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NETWORK_NOT_STARTED = 5055, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_MEDIUM_NEGOTIATION = 5056, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_HOST_NOT_STARTED = 5057, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_HOST_NETWORK_NOT_AVAILABLE = 5058, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_NO_INCOMING_HTTP_CONNECTION = 5059, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NO_CONNECTED_DEVICE = 5060, + DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_INTERRUPTED = 5061, }; extern const uint32_t OperationResultCode_internal_data_[]; inline constexpr OperationResultCode OperationResultCode_MIN = static_cast(0); inline constexpr OperationResultCode OperationResultCode_MAX = - static_cast(5024); + static_cast(5061); inline bool OperationResultCode_IsValid(int value) { return ::google::protobuf::internal::ValidateEnum(value, OperationResultCode_internal_data_); } -inline constexpr int OperationResultCode_ARRAYSIZE = 5024 + 1; +inline constexpr int OperationResultCode_ARRAYSIZE = 5061 + 1; const ::std::string& OperationResultCode_Name(OperationResultCode value); template const ::std::string& OperationResultCode_Name(T value) { diff --git a/connections/implementation/proto/offline_wire_formats.proto b/connections/implementation/proto/offline_wire_formats.proto index 71ce3ba3..f54287ec 100644 --- a/connections/implementation/proto/offline_wire_formats.proto +++ b/connections/implementation/proto/offline_wire_formats.proto @@ -326,9 +326,10 @@ message BandwidthUpgradeNegotiationFrame { // The GO should listen on both IPv4 and IPv6 addresses. // https://en.wikipedia.org/wiki/Link-local_address#IPv6 optional bytes ip_v6_address = 6; - // Windows only supports WifiDirect with Service Discovey. Its - // credentials is the service_name/pin. - optional string service_name = 7; + // Windows and Android will use Wi-Fi P2P device discovery for WifiDirect. + // Its credentials is the device_name. + optional string service_name = 7 [deprecated = true]; + optional string device_name = 9; // WifiDirect spec requires that pin is exactly 8 digits. The first 7 // digits are the PIN. The last 1 digit is a checksum calculated using a // specific algorithm (CRC-8). However, the Windows WinRT @@ -340,6 +341,8 @@ message BandwidthUpgradeNegotiationFrame { // pin is exchanged in the connection handshake stage, but we create and // save it before starting GO, so we can send it to GC side for // authentication. + // Note: pin is not used for WIFI_DIRECT_WITH_DEVICE_NAME, reserve for + // future expansion. optional string pin = 8; } @@ -512,9 +515,10 @@ message MediumMetadata { // WifiDirect type that uses ssid/password for authentication. Android // supports this type, but Windows does not. WIFI_DIRECT_WITH_PASSWORD = 1; - // WifiDirect type that uses service_name/pin for authentication. Android - // and Windows both support this type. - WIFI_DIRECT_WITH_PIN = 2; + // WifiDirect type that uses device_name for discovery and connect. + // Android and Windows both support this type. + WIFI_DIRECT_WITH_PIN = 2 [deprecated = true]; + WIFI_DIRECT_WITH_DEVICE_NAME = 3; } // LINT.ThenChange(//depot/google3/third_party/nearby/proto/connections_enums.proto) diff --git a/proto/connections_enums.proto b/proto/connections_enums.proto index 4c46ce5b..b31bbe69 100644 --- a/proto/connections_enums.proto +++ b/proto/connections_enums.proto @@ -110,9 +110,10 @@ enum WifiDirectAuthType { // WifiDirect type that uses ssid/password for authentication. Android // supports this type, but Windows does not. WIFI_DIRECT_WITH_PASSWORD = 1; - // WifiDirect type that uses service_name/pin for authentication. Android - // and Windows both support this type. - WIFI_DIRECT_WITH_PIN = 2; + // WifiDirect type that uses device_name for discovery and connect. + // Android and Windows both support this type. + WIFI_DIRECT_WITH_PIN = 2 [deprecated = true]; + WIFI_DIRECT_WITH_DEVICE_NAME = 3; } // LINT.ThenChange(//depot/google3/third_party/nearby/connections/implementation/proto/offline_wire_formats.proto) From a8e604bbe4a7cbeb94ffe66cd62148ea2301b53d Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 10 Jun 2026 01:35:01 -0700 Subject: [PATCH 149/151] Rename proto fields of the WifiDirectAuthType and WifiDirectCredentials PiperOrigin-RevId: 929682564 --- .../implementation/bwu_manager_test.cc | 2 +- connections/implementation/fake_bwu_handler.h | 2 +- .../mediums/wifi_direct_bwu_handler.cc | 14 +++++------ .../mediums/wifi_direct_test.cc | 23 +++++++++--------- connections/implementation/offline_frames.cc | 12 +++++----- connections/implementation/offline_frames.h | 2 +- .../implementation/offline_frames_test.cc | 18 +++++++------- .../offline_frames_validator.cc | 8 +++---- .../offline_frames_validator_test.cc | 20 ++++++++-------- .../platform/implementation/g3/wifi_direct.cc | 12 +++++----- .../platform/implementation/g3/wifi_direct.h | 2 +- .../windows/wifi_direct_medium.cc | 16 ++++++------- .../windows/wifi_direct_test.cc | 4 ++-- internal/platform/medium_environment.cc | 8 +++---- internal/platform/medium_environment.h | 2 +- internal/platform/wifi_credential.h | 12 +++++----- internal/platform/wifi_direct_test.cc | 24 +++++++++---------- 17 files changed, 91 insertions(+), 90 deletions(-) diff --git a/connections/implementation/bwu_manager_test.cc b/connections/implementation/bwu_manager_test.cc index e817ad7c..f622ab5b 100644 --- a/connections/implementation/bwu_manager_test.cc +++ b/connections/implementation/bwu_manager_test.cc @@ -925,7 +925,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_WifiDirect) { std::string bytes = parser::ForBwuWifiDirectPathAvailable( /*ssid=*/"", /*password=*/"", /*port=*/2143, /*frequency=*/2412, /*supports_disabling_encryption=*/false, - /*gateway=*/"123.234.23.1", /*service_name=*/"NC-WifiDirectTest", + /*gateway=*/"123.234.23.1", /*device_name=*/"NC-WifiDirectTest", /*pin=*/"b592f7d3"); frame.ParseFromString(bytes); diff --git a/connections/implementation/fake_bwu_handler.h b/connections/implementation/fake_bwu_handler.h index fd1fb1dc..dee9168b 100644 --- a/connections/implementation/fake_bwu_handler.h +++ b/connections/implementation/fake_bwu_handler.h @@ -178,7 +178,7 @@ class FakeBwuHandler : public BaseBwuHandler { return parser::ForBwuWifiDirectPathAvailable( /*ssid=*/"", /*password=*/"", /*port=*/2143, /*frequency=*/2412, /*supports_disabling_encryption=*/false, - /*gateway=*/"123.234.23.1", /*service_name=*/"NC-WifiDirectTest", + /*gateway=*/"123.234.23.1", /*device_name=*/"NC-WifiDirectTest", /*pin=*/"b592f7d3"); case location::nearby::proto::connections::UNKNOWN_MEDIUM: case location::nearby::proto::connections::MDNS: diff --git a/connections/implementation/mediums/wifi_direct_bwu_handler.cc b/connections/implementation/mediums/wifi_direct_bwu_handler.cc index b9925b84..55346fc7 100644 --- a/connections/implementation/mediums/wifi_direct_bwu_handler.cc +++ b/connections/implementation/mediums/wifi_direct_bwu_handler.cc @@ -86,14 +86,14 @@ std::string WifiDirectBwuHandler::HandleInitializeUpgradedMediumForEndpoint( wifi_direct_medium_.GetCredentials(upgrade_service_id); std::string ssid = wifi_direct_crendential->GetSSID(); std::string password = wifi_direct_crendential->GetPassword(); - std::string service_name = wifi_direct_crendential->GetServiceName(); + std::string device_name = wifi_direct_crendential->GetDeviceName(); std::string pin = wifi_direct_crendential->GetPin(); std::string gateway = wifi_direct_crendential->GetGateway(); int port = wifi_direct_crendential->GetPort(); int freq = wifi_direct_crendential->GetFrequency(); if (ssid.empty()) { - LOG(INFO) << "Start WifiDirect GO with ServiceName: " << service_name + LOG(INFO) << "Start WifiDirect GO with DeviceName: " << device_name << ", pin: " << masker::Mask(pin) << ", Port: " << port << ", Gateway: " << gateway << ", Frequency: " << freq; } else { @@ -108,7 +108,7 @@ std::string WifiDirectBwuHandler::HandleInitializeUpgradedMediumForEndpoint( return parser::ForBwuWifiDirectPathAvailable( ssid, password, port, freq, /* supports_disabling_encryption */ disabling_encryption, gateway, - service_name, pin); + device_name, pin); } void WifiDirectBwuHandler::HandleRevertInitiatorStateForService( @@ -138,8 +138,8 @@ WifiDirectBwuHandler::CreateUpgradedEndpointChannel( const std::string& ssid = upgrade_path_info_credentials.ssid(); const std::string& password = upgrade_path_info_credentials.password(); - const std::string& service_name = - upgrade_path_info_credentials.service_name(); + const std::string& device_name = + upgrade_path_info_credentials.device_name(); const std::string& pin = upgrade_path_info_credentials.pin(); std::int32_t port = upgrade_path_info_credentials.port(); const std::string& gateway = upgrade_path_info_credentials.gateway(); @@ -148,14 +148,14 @@ WifiDirectBwuHandler::CreateUpgradedEndpointChannel( WifiDirectCredentials wifi_direct_credentials; wifi_direct_credentials.SetSSID(ssid); wifi_direct_credentials.SetPassword(password); - wifi_direct_credentials.SetServiceName(service_name); + wifi_direct_credentials.SetDeviceName(device_name); wifi_direct_credentials.SetPin(pin); wifi_direct_credentials.SetPort(port); wifi_direct_credentials.SetGateway(gateway); wifi_direct_credentials.SetFrequency(freq); if (ssid.empty()) { - LOG(INFO) << "Received WifiDirect credential ServiceName: " << service_name + LOG(INFO) << "Received WifiDirect credential DeviceName: " << device_name << ", pin: " << masker::Mask(pin) << ", Port: " << port << ", Gateway: " << gateway << ", Frequency: " << freq; } else { diff --git a/connections/implementation/mediums/wifi_direct_test.cc b/connections/implementation/mediums/wifi_direct_test.cc index c3056442..b121930b 100644 --- a/connections/implementation/mediums/wifi_direct_test.cc +++ b/connections/implementation/mediums/wifi_direct_test.cc @@ -45,7 +45,7 @@ constexpr FeatureFlags kTestCases[] = { }; constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; -constexpr absl::string_view kServiceName{"NC-WifiDirectTest"}; +constexpr absl::string_view kDeviceName{"NC-WifiDirectTest"}; constexpr absl::string_view kPin{"12345678"}; constexpr absl::string_view kIp = "123.234.23.1"; constexpr const size_t kPort = 20; @@ -93,9 +93,9 @@ TEST_F(WifiDirectTest, CanStartStopGO) { TEST_F(WifiDirectTest, GCCanConnectDisconnectGO) { WifiDirectCredentials wifi_direct_credentials; - std::string service_name(kServiceName); + std::string device_name(kDeviceName); std::string pin(kPin); - wifi_direct_credentials.SetServiceName(service_name); + wifi_direct_credentials.SetDeviceName(device_name); wifi_direct_credentials.SetPin(pin); WifiDirect wifi_direct_a; @@ -187,9 +187,9 @@ TEST_F(WifiDirectTest, CanStartGOTheOtherFailConnect) { EXPECT_TRUE(wifi_direct_a.StartWifiDirect()); WifiDirectCredentials wifi_direct_credentials; - std::string service_name(kServiceName); + std::string device_name(kDeviceName); std::string pin(kPin); - wifi_direct_credentials.SetServiceName(service_name); + wifi_direct_credentials.SetDeviceName(device_name); wifi_direct_credentials.SetPin(pin); EXPECT_FALSE(wifi_direct_b.ConnectWifiDirect(wifi_direct_credentials)); EXPECT_TRUE(wifi_direct_b.DisconnectWifiDirect()); @@ -201,23 +201,24 @@ TEST_F(WifiDirectTest, GetSupportedWifiDirectAuthTypes) { auto supported_types = wifi_direct.GetSupportedWifiDirectAuthTypes(); EXPECT_EQ(supported_types.size(), 1); EXPECT_EQ(supported_types[0], - WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_PIN); + WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME); } TEST_F(WifiDirectTest, GetPreferredWifiDirectAuthType_Default) { WifiDirect wifi_direct; - // Default should be the first supported type, which is WIFI_DIRECT_WITH_PIN + // Default should be the first supported type, which is + // WIFI_DIRECT_WITH_DEVICE_NAME EXPECT_EQ(wifi_direct.GetPreferredWifiDirectAuthType(), - WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_PIN); + WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME); } TEST_F(WifiDirectTest, SetPreferredWifiDirectAuthType_Supported) { WifiDirect wifi_direct; // Attempt to set the preferred type to the already default/supported type. EXPECT_TRUE(wifi_direct.SetPreferredWifiDirectAuthType( - WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_PIN)); + WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME)); EXPECT_EQ(wifi_direct.GetPreferredWifiDirectAuthType(), - WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_PIN); + WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME); } TEST_F(WifiDirectTest, SetPreferredWifiDirectAuthType_Unsupported) { @@ -227,7 +228,7 @@ TEST_F(WifiDirectTest, SetPreferredWifiDirectAuthType_Unsupported) { WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD)); // Preferred type should remain the default. EXPECT_EQ(wifi_direct.GetPreferredWifiDirectAuthType(), - WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_PIN); + WifiDirect::WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME); } } // namespace diff --git a/connections/implementation/offline_frames.cc b/connections/implementation/offline_frames.cc index cf92803f..14f2d983 100644 --- a/connections/implementation/offline_frames.cc +++ b/connections/implementation/offline_frames.cc @@ -363,7 +363,7 @@ std::string ForBwuWifiAwarePathAvailable(const std::string& service_id, std::string ForBwuWifiDirectPathAvailable( const std::string& ssid, const std::string& password, std::int32_t port, std::int32_t frequency, bool supports_disabling_encryption, - const std::string& gateway, const std::string& service_name, + const std::string& gateway, const std::string& device_name, const std::string& pin) { OfflineFrame frame; @@ -385,7 +385,7 @@ std::string ForBwuWifiDirectPathAvailable( wifi_direct_credentials->set_port(port); wifi_direct_credentials->set_frequency(frequency); wifi_direct_credentials->set_gateway(gateway); - wifi_direct_credentials->set_service_name(service_name); + wifi_direct_credentials->set_device_name(device_name); wifi_direct_credentials->set_pin(pin); return frame.SerializeAsString(); @@ -709,8 +709,8 @@ MediumMetadata::WifiDirectAuthType WFDAuthTypeToMediumMetadataWFDAuthType( switch (wifi_direct_auth_type) { case WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD: return MediumMetadata::WIFI_DIRECT_WITH_PASSWORD; - case WifiDirectAuthType::WIFI_DIRECT_WITH_PIN: - return MediumMetadata::WIFI_DIRECT_WITH_PIN; + case WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME: + return MediumMetadata::WIFI_DIRECT_WITH_DEVICE_NAME; default: return MediumMetadata::WIFI_DIRECT_TYPE_UNKNOWN; } @@ -721,8 +721,8 @@ WifiDirectAuthType MediumMetadataWFDAuthTypeToWFDAuthType( switch (wifi_direct_auth_type) { case MediumMetadata::WIFI_DIRECT_WITH_PASSWORD: return WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD; - case MediumMetadata::WIFI_DIRECT_WITH_PIN: - return WifiDirectAuthType::WIFI_DIRECT_WITH_PIN; + case MediumMetadata::WIFI_DIRECT_WITH_DEVICE_NAME: + return WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME; default: return WifiDirectAuthType::WIFI_DIRECT_TYPE_UNKNOWN; } diff --git a/connections/implementation/offline_frames.h b/connections/implementation/offline_frames.h index d56dba36..b2fce56f 100644 --- a/connections/implementation/offline_frames.h +++ b/connections/implementation/offline_frames.h @@ -98,7 +98,7 @@ std::string ForBwuWifiDirectPathAvailable(const std::string& ssid, std::int32_t frequency, bool supports_disabling_encryption, const std::string& gateway, - const std::string& service_name, + const std::string& device_name, const std::string& pin); std::string ForBwuBluetoothPathAvailable(const std::string& service_id, MacAddress mac_address); diff --git a/connections/implementation/offline_frames_test.cc b/connections/implementation/offline_frames_test.cc index 022673b2..1bb982f2 100644 --- a/connections/implementation/offline_frames_test.cc +++ b/connections/implementation/offline_frames_test.cc @@ -289,7 +289,7 @@ TEST(OfflineFramesTest, supports_5_ghz: true bssid: "FF:FF:FF:FF:FF:FF" ap_frequency: 2412 - supported_wifi_direct_auth_types: WIFI_DIRECT_WITH_PIN + supported_wifi_direct_auth_types: WIFI_DIRECT_WITH_DEVICE_NAME supported_wifi_direct_auth_types: WIFI_DIRECT_WITH_PASSWORD > mediums: MDNS @@ -324,7 +324,7 @@ TEST(OfflineFramesTest, kKeepAliveIntervalMillis, kKeepAliveTimeoutMillis}; connection_info.supported_wifi_direct_auth_types = { - WifiDirectAuthType::WIFI_DIRECT_WITH_PIN, + WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME, WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD}; location::nearby::connections::ConnectionsDevice connections_device; @@ -596,7 +596,7 @@ TEST(OfflineFramesTest, CanGenerateBwuWifiDirectPathAvailable) { port: 1000 frequency: 2412 gateway: "192.168.1.1" - service_name: "NC-WifiDirectTest" + device_name: "NC-WifiDirectTest" pin: "b592f7d3" > supports_disabling_encryption: false @@ -756,8 +756,8 @@ TEST(OfflineFramesTest, WFDAuthTypeToMediumMetadataWFDAuthType) { WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD), MediumMetadata::WIFI_DIRECT_WITH_PASSWORD); EXPECT_EQ(WFDAuthTypeToMediumMetadataWFDAuthType( - WifiDirectAuthType::WIFI_DIRECT_WITH_PIN), - MediumMetadata::WIFI_DIRECT_WITH_PIN); + WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME), + MediumMetadata::WIFI_DIRECT_WITH_DEVICE_NAME); EXPECT_EQ(WFDAuthTypeToMediumMetadataWFDAuthType( WifiDirectAuthType::WIFI_DIRECT_TYPE_UNKNOWN), MediumMetadata::WIFI_DIRECT_TYPE_UNKNOWN); @@ -768,8 +768,8 @@ TEST(OfflineFramesTest, MediumMetadataWFDAuthTypeToWFDAuthType) { MediumMetadata::WIFI_DIRECT_WITH_PASSWORD), WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD); EXPECT_EQ(MediumMetadataWFDAuthTypeToWFDAuthType( - MediumMetadata::WIFI_DIRECT_WITH_PIN), - WifiDirectAuthType::WIFI_DIRECT_WITH_PIN); + MediumMetadata::WIFI_DIRECT_WITH_DEVICE_NAME), + WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME); EXPECT_EQ(MediumMetadataWFDAuthTypeToWFDAuthType( MediumMetadata::WIFI_DIRECT_TYPE_UNKNOWN), WifiDirectAuthType::WIFI_DIRECT_TYPE_UNKNOWN); @@ -780,11 +780,11 @@ TEST(OfflineFramesTest, MediumMetadataWFDAuthTypesToWFDAuthTypes) { medium_metadata.add_supported_wifi_direct_auth_types( MediumMetadata::WIFI_DIRECT_WITH_PASSWORD); medium_metadata.add_supported_wifi_direct_auth_types( - MediumMetadata::WIFI_DIRECT_WITH_PIN); + MediumMetadata::WIFI_DIRECT_WITH_DEVICE_NAME); std::vector expected = { WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD, - WifiDirectAuthType::WIFI_DIRECT_WITH_PIN}; + WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME}; EXPECT_THAT(MediumMetadataWFDAuthTypesToWFDAuthTypes(medium_metadata), Pointwise(testing::Eq(), expected)); diff --git a/connections/implementation/offline_frames_validator.cc b/connections/implementation/offline_frames_validator.cc index 786bcb3c..62b29a79 100644 --- a/connections/implementation/offline_frames_validator.cc +++ b/connections/implementation/offline_frames_validator.cc @@ -291,16 +291,16 @@ Exception EnsureValidBandwidthUpgradeWifiDirectPathAvailableFrame( wifi_direct_credentials.has_password() && WithinRange(wifi_direct_credentials.password().length(), kWifiPasswordSsidMinLength, kWifiPasswordSsidMaxLength); - bool service_name_valid = - wifi_direct_credentials.has_service_name() && - wifi_direct_credentials.service_name().length() < + bool device_name_valid = + wifi_direct_credentials.has_device_name() && + wifi_direct_credentials.device_name().length() < kWifiDirectSsidMaxLength; bool pin_valid = wifi_direct_credentials.has_pin() && WithinRange(wifi_direct_credentials.pin().length(), kWifiDirectPinMinLength, kWifiDirectPinMaxLength); - if ((ssid_valid && password_valid) || (service_name_valid && pin_valid)) + if ((ssid_valid && password_valid) || (device_name_valid && pin_valid)) return {Exception::kSuccess}; return {Exception::kInvalidProtocolBuffer}; diff --git a/connections/implementation/offline_frames_validator_test.cc b/connections/implementation/offline_frames_validator_test.cc index b20cbc5b..a1f1e21f 100644 --- a/connections/implementation/offline_frames_validator_test.cc +++ b/connections/implementation/offline_frames_validator_test.cc @@ -49,7 +49,7 @@ constexpr absl::string_view kPassword = "password"; constexpr absl::string_view kWifiHotspotGateway = "0.0.0.0"; constexpr absl::string_view kWifiDirectSsid = "DIRECT-A0-0123456789AB"; constexpr absl::string_view kWifiDirectPassword = "WIFIDIRECT123456"; -constexpr absl::string_view kWifiDirectServiceName = "NC-WifiDirectTest"; +constexpr absl::string_view kWifiDirectDeviceName = "NC-WifiDirectTest"; constexpr absl::string_view kWifiDirectPin = "b592f7d3"; constexpr absl::string_view kGateway = "192.168.1.1"; constexpr int kWifiDirectFrequency = 2412; @@ -723,7 +723,7 @@ TEST(OfflineFramesValidatorTest, ValidatesAsOkBandwidthUpgradeWifiDirect) { std::string bytes = ForBwuWifiDirectPathAvailable( std::string(kWifiDirectSsid), std::string(kWifiDirectPassword), kPort, kWifiDirectFrequency, kSupportsDisablingEncryption, std::string(kGateway), - std::string(kWifiDirectServiceName), std::string(kWifiDirectPin)); + std::string(kWifiDirectDeviceName), std::string(kWifiDirectPin)); offline_frame.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame); @@ -740,7 +740,7 @@ TEST(OfflineFramesValidatorTest, std::string bytes = ForBwuWifiDirectPathAvailable( std::string(kWifiDirectSsid), std::string(kWifiDirectPassword), kPort, -2, kSupportsDisablingEncryption, std::string(kGateway), - std::string(kWifiDirectServiceName), std::string(kWifiDirectPin)); + std::string(kWifiDirectDeviceName), std::string(kWifiDirectPin)); offline_frame_1.ParseFromString(bytes); auto ret_value = EnsureValidOfflineFrame(offline_frame_1); @@ -751,7 +751,7 @@ TEST(OfflineFramesValidatorTest, bytes = ForBwuWifiDirectPathAvailable( std::string(kWifiDirectSsid), std::string(kWifiDirectPassword), kPort, -1, kSupportsDisablingEncryption, std::string(kGateway), - std::string(kWifiDirectServiceName), std::string(kWifiDirectPin)); + std::string(kWifiDirectDeviceName), std::string(kWifiDirectPin)); offline_frame_2.ParseFromString(bytes); ret_value = EnsureValidOfflineFrame(offline_frame_2); @@ -769,7 +769,7 @@ TEST(OfflineFramesValidatorTest, std::string bytes = ForBwuWifiDirectPathAvailable( wifi_direct_ssid, std::string(kWifiDirectPassword), kPort, kWifiDirectFrequency, kSupportsDisablingEncryption, - std::string(kGateway), std::string(kWifiDirectServiceName), + std::string(kGateway), std::string(kWifiDirectDeviceName), wifi_direct_pin_wrong_length); offline_frame_1.ParseFromString(bytes); @@ -779,13 +779,13 @@ TEST(OfflineFramesValidatorTest, std::string wifi_direct_ssid_wrong_length = std::string{kWifiDirectSsid} + "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; - std::string wifi_direct_service_name_wrong_length = - std::string{kWifiDirectServiceName} + + std::string wifi_direct_device_name_wrong_length = + std::string{kWifiDirectDeviceName} + "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; bytes = ForBwuWifiDirectPathAvailable( wifi_direct_ssid_wrong_length, std::string(kWifiDirectPassword), kPort, kWifiDirectFrequency, kSupportsDisablingEncryption, - std::string(kGateway), wifi_direct_service_name_wrong_length, + std::string(kGateway), wifi_direct_device_name_wrong_length, std::string(kWifiDirectPin)); offline_frame_2.ParseFromString(bytes); @@ -804,7 +804,7 @@ TEST(OfflineFramesValidatorTest, std::string bytes = ForBwuWifiDirectPathAvailable( std::string(kWifiDirectSsid), short_wifi_direct_password, kPort, kWifiDirectFrequency, kSupportsDisablingEncryption, - std::string(kGateway), std::string(kWifiDirectServiceName), + std::string(kGateway), std::string(kWifiDirectDeviceName), short_wifi_direct_pin); offline_frame_1.ParseFromString(bytes); @@ -821,7 +821,7 @@ TEST(OfflineFramesValidatorTest, bytes = ForBwuWifiDirectPathAvailable( std::string(kWifiDirectSsid), long_wifi_direct_password, kPort, kWifiDirectFrequency, kSupportsDisablingEncryption, - std::string(kGateway), std::string(kWifiDirectServiceName), + std::string(kGateway), std::string(kWifiDirectDeviceName), long_wifi_direct_pin); offline_frame_2.ParseFromString(bytes); diff --git a/internal/platform/implementation/g3/wifi_direct.cc b/internal/platform/implementation/g3/wifi_direct.cc index 5b154f47..0241bf99 100644 --- a/internal/platform/implementation/g3/wifi_direct.cc +++ b/internal/platform/implementation/g3/wifi_direct.cc @@ -135,12 +135,12 @@ bool WifiDirectMedium::StartWifiDirect( WifiDirectCredentials* wifi_direct_credentials) { absl::MutexLock lock(mutex_); - std::string service_name = absl::StrCat("NC-", Prng().NextUint32()); - wifi_direct_credentials->SetServiceName(service_name); + std::string device_name = absl::StrCat("NC-", Prng().NextUint32()); + wifi_direct_credentials->SetDeviceName(device_name); std::string pin = absl::StrFormat("%04x", Prng().NextUint32()); wifi_direct_credentials->SetPin(pin); - LOG(INFO) << "G3 StartWifiDirect GO: service_name:" << service_name + LOG(INFO) << "G3 StartWifiDirect GO: device_name:" << device_name << ", pin:" << pin; auto& env = MediumEnvironment::Instance(); @@ -165,13 +165,13 @@ bool WifiDirectMedium::ConnectWifiDirect( const WifiDirectCredentials& wifi_direct_credentials) { absl::MutexLock lock(mutex_); - LOG(INFO) << "G3 ConnectWifiDirect : service_name:" - << wifi_direct_credentials.GetServiceName() + LOG(INFO) << "G3 ConnectWifiDirect : device_name:" + << wifi_direct_credentials.GetDeviceName() << ", pin:" << wifi_direct_credentials.GetPin(); auto& env = MediumEnvironment::Instance(); auto* remote_medium = static_cast( - env.GetWifiDirectMedium(wifi_direct_credentials.GetServiceName(), "")); + env.GetWifiDirectMedium(wifi_direct_credentials.GetDeviceName(), "")); if (!remote_medium) { env.UpdateWifiDirectMediumForStartOrConnect(*this, &wifi_direct_credentials, /*is_go=*/false, diff --git a/internal/platform/implementation/g3/wifi_direct.h b/internal/platform/implementation/g3/wifi_direct.h index fe9ec31d..9d0a8ea5 100644 --- a/internal/platform/implementation/g3/wifi_direct.h +++ b/internal/platform/implementation/g3/wifi_direct.h @@ -185,7 +185,7 @@ class WifiDirectMedium : public api::WifiDirectMedium { // Returns the supported WifiDirect auth types. std::vector GetSupportedWifiDirectAuthTypes() const override { - return {WifiDirectAuthType::WIFI_DIRECT_WITH_PIN}; + return {WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME}; } private: diff --git a/internal/platform/implementation/windows/wifi_direct_medium.cc b/internal/platform/implementation/windows/wifi_direct_medium.cc index 00e390eb..6ac9f2c8 100644 --- a/internal/platform/implementation/windows/wifi_direct_medium.cc +++ b/internal/platform/implementation/windows/wifi_direct_medium.cc @@ -304,13 +304,13 @@ bool WifiDirectMedium::StartWifiDirect( std::string pin = absl::StrFormat("%04x", prng.NextUint32()); credentials_go_->SetPin(pin); - std::string service_name = + std::string device_name = absl::StrCat(kServiceNamePrefix, std::to_string(prng.NextUint32())); - credentials_go_->SetServiceName(service_name); - LOG(INFO) << "service_name:pin " << service_name << ":" << pin; + credentials_go_->SetDeviceName(device_name); + LOG(INFO) << "device_name:pin " << device_name << ":" << pin; // Create Advertiser object - advertiser_ = WiFiDirectServiceAdvertiser(winrt::to_hstring(service_name)); + advertiser_ = WiFiDirectServiceAdvertiser(winrt::to_hstring(device_name)); advertisement_status_changed_token_ = advertiser_.AdvertisementStatusChanged( {this, &WifiDirectMedium::OnAdvertisementStatusChanged}); auto_accept_session_connected_token_ = advertiser_.AutoAcceptSessionConnected( @@ -572,12 +572,12 @@ bool WifiDirectMedium::ConnectWifiDirect( } credentials_gc_ = credentials; - if (credentials_gc_.GetServiceName().empty()) { - LOG(ERROR) << "GC: Service name is empty, return false"; + if (credentials_gc_.GetDeviceName().empty()) { + LOG(ERROR) << "GC: Device name is empty, return false"; return false; } winrt::hstring device_selector = WiFiDirectService::GetSelector( - winrt::to_hstring(credentials_gc_.GetServiceName())); + winrt::to_hstring(credentials_gc_.GetDeviceName())); const winrt::param::iterable requested_properties = winrt::single_threaded_vector({ winrt::to_hstring("System.Devices.WiFiDirectServices.ServiceAddress"), @@ -762,7 +762,7 @@ bool WifiDirectMedium::DisconnectWifiDirect() { std::vector WifiDirectMedium::GetSupportedWifiDirectAuthTypes() const { // Windows only supports WifiDirect with Service Discovery, which uses a PIN. - return {WifiDirectAuthType::WIFI_DIRECT_WITH_PIN}; + return {WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME}; } } // namespace windows diff --git a/internal/platform/implementation/windows/wifi_direct_test.cc b/internal/platform/implementation/windows/wifi_direct_test.cc index b6d91c1f..6eb5c293 100644 --- a/internal/platform/implementation/windows/wifi_direct_test.cc +++ b/internal/platform/implementation/windows/wifi_direct_test.cc @@ -82,7 +82,7 @@ TEST(WifiDirectMedium, DISABLED_ConnectWifiDirect) { std::cin >> pin; std::string service_name_with_prefix = absl::StrCat(kServiceNamePrefix, service_name); - credentials.SetServiceName(service_name_with_prefix); + credentials.SetDeviceName(service_name_with_prefix); credentials.SetPin(pin); EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect(credentials)); @@ -159,7 +159,7 @@ TEST(WifiDirectMedium, DISABLED_WifiDirectConnectToServiceServer) { std::cin >> pin; std::string service_name_with_prefix = absl::StrCat(kServiceNamePrefix, service_name); - credentials.SetServiceName(service_name_with_prefix); + credentials.SetDeviceName(service_name_with_prefix); credentials.SetPin(pin); EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect(credentials)); diff --git a/internal/platform/medium_environment.cc b/internal/platform/medium_environment.cc index b0e9b98c..46f8142e 100644 --- a/internal/platform/medium_environment.cc +++ b/internal/platform/medium_environment.cc @@ -983,13 +983,13 @@ void MediumEnvironment::RegisterWifiDirectMedium( } api::WifiDirectMedium* MediumEnvironment::GetWifiDirectMedium( - absl::string_view service_name, absl::string_view ip_address) { + absl::string_view device_name, absl::string_view ip_address) { MutexLock lock(&mutex_); for (auto& medium_info : wifi_direct_mediums_) { auto* medium_found = medium_info.first; auto& info = medium_info.second; if (info.is_go && info.is_active) { - if ((info.wifi_direct_credentials->GetServiceName() == service_name) || + if ((info.wifi_direct_credentials->GetDeviceName() == device_name) || (!ip_address.empty() && (info.wifi_direct_credentials->GetGateway() == ip_address))) { LOG(INFO) << "Found Remote WifiDirect medium=" << medium_found; @@ -1020,8 +1020,8 @@ void MediumEnvironment::UpdateWifiDirectMediumForStartOrConnect( if (wifi_direct_credentials) { LOG(INFO) << "Update WifiDirect medium for GO: this=" << this << "; medium=" << &medium << role_status - << "; service_name=" - << wifi_direct_credentials->GetServiceName() + << "; device_name=" + << wifi_direct_credentials->GetDeviceName() << "; pin=" << wifi_direct_credentials->GetPin(); } else { LOG(INFO) << "Reset WifiDirect medium for GO: this=" << this diff --git a/internal/platform/medium_environment.h b/internal/platform/medium_environment.h index 8a4d7e14..4ffce3ad 100644 --- a/internal/platform/medium_environment.h +++ b/internal/platform/medium_environment.h @@ -290,7 +290,7 @@ class MediumEnvironment { // Returns WifiDirect medium that matches ssid or IP address with the role of // the Medium. Returns nullptr if not found. - api::WifiDirectMedium* GetWifiDirectMedium(absl::string_view service_name, + api::WifiDirectMedium* GetWifiDirectMedium(absl::string_view device_name, absl::string_view ip_address); // Updates credential and Medium role(GO or GC) to indicate the current diff --git a/internal/platform/wifi_credential.h b/internal/platform/wifi_credential.h index 7618d4af..cc6c78a3 100644 --- a/internal/platform/wifi_credential.h +++ b/internal/platform/wifi_credential.h @@ -83,10 +83,10 @@ class WifiDirectCredentials { std::string GetPassword() const { return password_; } void SetPassword(const std::string& password) { password_ = password; } - // Get/Set Service Name. - std::string GetServiceName() const { return service_name_; } - void SetServiceName(const std::string& service_name) { - service_name_ = service_name; + // Get/Set Device Name. + std::string GetDeviceName() const { return device_name_; } + void SetDeviceName(const std::string& device_name) { + device_name_ = device_name; } // Get/Set Pin. @@ -126,12 +126,12 @@ class WifiDirectCredentials { private: // There are 2 types of WifiDirectAuthType. // 1. Without Service Discovery: the credentials are ssid/password. - // 2. With Service Discovery: the credentials are service_name/pin. + // 2. With Service Discovery: the credentials are device_name/pin. // Android supports type 1 and 2 in the future, but Windows only supports the // second type. std::string ssid_; std::string password_; - std::string service_name_; + std::string device_name_; std::string pin_; std::string ip_address_; std::string gateway_ = "0.0.0.0"; diff --git a/internal/platform/wifi_direct_test.cc b/internal/platform/wifi_direct_test.cc index fc14c90e..fd6f54cf 100644 --- a/internal/platform/wifi_direct_test.cc +++ b/internal/platform/wifi_direct_test.cc @@ -47,19 +47,19 @@ constexpr FeatureFlags kTestCases[] = { }, }; -constexpr absl::string_view kServiceName = "NC-WifiDirectTest"; +constexpr absl::string_view kDeviceName = "NC-WifiDirectTest"; constexpr absl::string_view kPin = "b592f7d3"; constexpr absl::string_view kIp = "123.234.23.1"; constexpr const size_t kPort = 20; constexpr absl::string_view kData = "ABCD"; constexpr const size_t kChunkSize = 10; -TEST(WifiDirectCredentialsTest, SetGetServiceName) { - std::string service_name(kServiceName); +TEST(WifiDirectCredentialsTest, SetGetDeviceName) { + std::string device_name(kDeviceName); WifiDirectCredentials wifi_direct_credentials; - wifi_direct_credentials.SetServiceName(service_name); + wifi_direct_credentials.SetDeviceName(device_name); - EXPECT_EQ(wifi_direct_credentials.GetServiceName(), kServiceName); + EXPECT_EQ(wifi_direct_credentials.GetDeviceName(), kDeviceName); } TEST(WifiDirectCredentialsTest, SetGetPin) { @@ -116,7 +116,7 @@ TEST_F(WifiDirectMediumTest, CanStartStopWifiDirect) { TEST_F(WifiDirectMediumTest, CanConnectDisconnectWifiDirect) { WifiDirectMedium wifi_direct_a; WifiDirectCredentials credentials; - credentials.SetServiceName(std::string(kServiceName)); + credentials.SetDeviceName(std::string(kDeviceName)); credentials.SetPin(std::string(kPin)); ASSERT_TRUE(wifi_direct_a.IsInterfaceValid()); @@ -136,7 +136,7 @@ TEST_P(WifiDirectMediumTest, CanStartDirectGOThatOtherCanConnect) { WifiDirectCredentials* wifi_direct_credentials = wifi_direct_a.GetCredential(); auto* medium_a = - env_.GetWifiDirectMedium(wifi_direct_credentials->GetServiceName(), {}); + env_.GetWifiDirectMedium(wifi_direct_credentials->GetDeviceName(), {}); EXPECT_NE(medium_a, nullptr); EXPECT_TRUE(wifi_direct_b.ConnectWifiDirect(*wifi_direct_credentials)); @@ -198,7 +198,7 @@ TEST_P(WifiDirectMediumTest, CanStartDirectGOThatOtherCanConnect) { EXPECT_TRUE(wifi_direct_b.DisconnectWifiDirect()); EXPECT_TRUE(wifi_direct_a.StopWifiDirect()); auto* medium_b = - env_.GetWifiDirectMedium(wifi_direct_credentials->GetServiceName(), {}); + env_.GetWifiDirectMedium(wifi_direct_credentials->GetDeviceName(), {}); EXPECT_EQ(medium_b, nullptr); } @@ -278,7 +278,7 @@ TEST_F(WifiDirectMediumTest, CanStartDirectGOThatOtherFailConnect) { ASSERT_TRUE(wifi_direct_b.IsInterfaceValid()); EXPECT_TRUE(wifi_direct_a.StartWifiDirect()); WifiDirectCredentials wifi_direct_credentials; - wifi_direct_credentials.SetServiceName(std::string(kServiceName)); + wifi_direct_credentials.SetDeviceName(std::string(kDeviceName)); wifi_direct_credentials.SetPin(std::string(kPin)); EXPECT_FALSE(wifi_direct_b.ConnectWifiDirect(wifi_direct_credentials)); @@ -289,12 +289,12 @@ TEST_F(WifiDirectMediumTest, CanStartDirectGOThatOtherFailConnect) { TEST_F(WifiDirectMediumTest, GetSupportedWifiDirectAuthTypes) { WifiDirectMedium wifi_direct_a; - // g3 only supports WifiDirect with auth type of PIN. + // g3 only supports WifiDirect with auth type of Device Name. auto supported_types = wifi_direct_a.GetSupportedWifiDirectAuthTypes(); EXPECT_EQ(supported_types.size(), 1); EXPECT_EQ(supported_types[0], - location::nearby::proto::connections:: - WifiDirectAuthType::WIFI_DIRECT_WITH_PIN); + location::nearby::proto::connections::WifiDirectAuthType:: + WIFI_DIRECT_WITH_DEVICE_NAME); } } // namespace From 728a7050a31db2d26d3428d35d77d331ab77e550 Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 12 Jun 2026 14:09:56 -0700 Subject: [PATCH 150/151] Re-implement Windows WifiDirect with Windows.Devices.WiFiDirect Namespace. PiperOrigin-RevId: 931324779 --- .../offline_frames_validator.cc | 5 +- .../offline_frames_validator_test.cc | 19 +- .../implementation/windows/wifi_direct.h | 165 ++- .../windows/wifi_direct_medium.cc | 1112 ++++++++++------- .../windows/wifi_direct_server_socket.cc | 96 +- 5 files changed, 824 insertions(+), 573 deletions(-) diff --git a/connections/implementation/offline_frames_validator.cc b/connections/implementation/offline_frames_validator.cc index 62b29a79..d388d6eb 100644 --- a/connections/implementation/offline_frames_validator.cc +++ b/connections/implementation/offline_frames_validator.cc @@ -61,7 +61,9 @@ constexpr absl::string_view kWifiDirectSsidPatternString{ constexpr int kWifiDirectSsidMaxLength = 32; constexpr int kWifiPasswordSsidMinLength = 8; constexpr int kWifiPasswordSsidMaxLength = 64; -constexpr int kWifiDirectPinMinLength = 4; +// We may use Push Button for WPS, so no pin is required, the min length should +// be 0. +constexpr int kWifiDirectPinMinLength = 0; constexpr int kWifiDirectPinMaxLength = 16; inline bool WithinRange(int value, int min, int max) { @@ -302,7 +304,6 @@ Exception EnsureValidBandwidthUpgradeWifiDirectPathAvailableFrame( if ((ssid_valid && password_valid) || (device_name_valid && pin_valid)) return {Exception::kSuccess}; - return {Exception::kInvalidProtocolBuffer}; // For backwards compatibility reasons, no other fields should be null-checked diff --git a/connections/implementation/offline_frames_validator_test.cc b/connections/implementation/offline_frames_validator_test.cc index a1f1e21f..37d92941 100644 --- a/connections/implementation/offline_frames_validator_test.cc +++ b/connections/implementation/offline_frames_validator_test.cc @@ -765,7 +765,7 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame_2; std::string wifi_direct_ssid{"DIRECT-A*-0123456789AB"}; - std::string wifi_direct_pin_wrong_length = "abc"; + std::string wifi_direct_pin_wrong_length = "abcefghijklmnopqrstuvwxyz"; std::string bytes = ForBwuWifiDirectPathAvailable( wifi_direct_ssid, std::string(kWifiDirectPassword), kPort, kWifiDirectFrequency, kSupportsDisablingEncryption, @@ -799,33 +799,20 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame_1; OfflineFrame offline_frame_2; - std::string short_wifi_direct_password{"Test"}; - std::string short_wifi_direct_pin{"abc"}; - std::string bytes = ForBwuWifiDirectPathAvailable( - std::string(kWifiDirectSsid), short_wifi_direct_password, kPort, - kWifiDirectFrequency, kSupportsDisablingEncryption, - std::string(kGateway), std::string(kWifiDirectDeviceName), - short_wifi_direct_pin); - offline_frame_1.ParseFromString(bytes); - - auto ret_value = EnsureValidOfflineFrame(offline_frame_1); - - ASSERT_FALSE(ret_value.Ok()); - std::string long_wifi_direct_password = std::string{kWifiDirectSsid} + "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789"; std::string long_wifi_direct_pin = std::string{kWifiDirectPin} + "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789"; - bytes = ForBwuWifiDirectPathAvailable( + std::string bytes = ForBwuWifiDirectPathAvailable( std::string(kWifiDirectSsid), long_wifi_direct_password, kPort, kWifiDirectFrequency, kSupportsDisablingEncryption, std::string(kGateway), std::string(kWifiDirectDeviceName), long_wifi_direct_pin); offline_frame_2.ParseFromString(bytes); - ret_value = EnsureValidOfflineFrame(offline_frame_2); + auto ret_value = EnsureValidOfflineFrame(offline_frame_2); EXPECT_FALSE(ret_value.Ok()); } diff --git a/internal/platform/implementation/windows/wifi_direct.h b/internal/platform/implementation/windows/wifi_direct.h index 276ee488..399b3f5d 100644 --- a/internal/platform/implementation/windows/wifi_direct.h +++ b/internal/platform/implementation/windows/wifi_direct.h @@ -17,15 +17,13 @@ // Windows headers #include +#include #include // Standard C/C++ headers -#include -#include #include +#include #include -#include -#include // Nearby connections headers #include "absl/base/nullability.h" @@ -35,6 +33,7 @@ #include "absl/synchronization/mutex.h" #include "absl/types/optional.h" #include "internal/platform/cancellation_flag.h" +#include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" #include "internal/platform/implementation/wifi_direct.h" #include "internal/platform/implementation/windows/nearby_client_socket.h" @@ -46,8 +45,9 @@ #include "internal/platform/wifi_credential.h" // WinRT headers +#include "internal/platform/implementation/windows/generated/winrt/base.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Enumeration.h" -#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.WiFiDirect.Services.h" +#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.WiFiDirect.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.Collections.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.h" @@ -55,33 +55,55 @@ #include "internal/platform/implementation/windows/generated/winrt/Windows.Security.Cryptography.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Storage.Streams.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.System.h" -#include "internal/platform/implementation/windows/generated/winrt/base.h" namespace nearby::windows { +// Windows.Devices.WiFiDirect Namespace contains classes that support connecting +// to associated Wi-Fi Direct devices and associated endpoints for PCs, tablets, +// and phones. +// https://learn.microsoft.com/en-us/uwp/api/windows.devices.wifidirect?view=winrt-22000 using ::winrt::event_token; using ::winrt::fire_and_forget; +using ::winrt::Windows::Devices::WiFiDirect:: + WiFiDirectAdvertisementListenStateDiscoverability; +using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectAdvertisementPublisher; +using ::winrt::Windows::Devices::WiFiDirect:: + WiFiDirectAdvertisementPublisherStatus; +using ::winrt::Windows::Devices::WiFiDirect:: + WiFiDirectAdvertisementPublisherStatusChangedEventArgs; +using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectConfigurationMethod; +using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectConnectionListener; +using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectConnectionParameters; +using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectConnectionRequest; +using ::winrt::Windows::Devices::WiFiDirect:: + WiFiDirectConnectionRequestedEventArgs; +using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectDevice; +using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectDeviceSelectorType; +using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectPairingProcedure; + using ::winrt::Windows::Devices::Enumeration::DeviceInformation; +using ::winrt::Windows::Devices::Enumeration::DeviceInformationCollection; +using ::winrt::Windows::Devices::Enumeration::DeviceInformationCustomPairing; +using ::winrt::Windows::Devices::Enumeration::DeviceInformationKind; +using ::winrt::Windows::Devices::Enumeration::DeviceInformationPairing; using ::winrt::Windows::Devices::Enumeration::DeviceInformationUpdate; +using ::winrt::Windows::Devices::Enumeration::DevicePairingKinds; +using ::winrt::Windows::Devices::Enumeration::DevicePairingProtectionLevel; +using ::winrt::Windows::Devices::Enumeration::DevicePairingRequestedEventArgs; +using ::winrt::Windows::Devices::Enumeration::DevicePairingResult; +using ::winrt::Windows::Devices::Enumeration::DevicePairingResultStatus; +using ::winrt::Windows::Devices::Enumeration::DeviceUnpairingResult; +using ::winrt::Windows::Devices::Enumeration::DeviceUnpairingResultStatus; using ::winrt::Windows::Devices::Enumeration::DeviceWatcher; -using ::winrt::Windows::Devices::WiFiDirect::Services::WiFiDirectService; -using ::winrt::Windows::Devices::WiFiDirect::Services:: - WiFiDirectServiceAdvertisementStatus; -using ::winrt::Windows::Devices::WiFiDirect::Services:: - WiFiDirectServiceAdvertiser; -using ::winrt::Windows::Devices::WiFiDirect::Services:: - WiFiDirectServiceAutoAcceptSessionConnectedEventArgs; -using ::winrt::Windows::Devices::WiFiDirect::Services:: - WiFiDirectServiceConfigurationMethod; -using ::winrt::Windows::Devices::WiFiDirect::Services::WiFiDirectServiceSession; -using ::winrt::Windows::Devices::WiFiDirect::Services:: - WiFiDirectServiceSessionRequestedEventArgs; -using ::winrt::Windows::Devices::WiFiDirect::Services::WiFiDirectServiceStatus; + using ::winrt::Windows::Foundation::AsyncStatus; +using ::winrt::Windows::Foundation::IAsyncOperation; using ::winrt::Windows::Foundation::IInspectable; +using ::winrt::Windows::Foundation::Collections::IVectorView; +using ::winrt::Windows::Networking::EndpointPair; // WifiDirectSocket wraps the socket functions to read and write stream. -// On WiFiDirect GO serverside, a WifiDirectSocket will be passed to +// On WiFiDirect GO server side, a WifiDirectSocket will be passed to // StartAcceptingConnections's callback when Winsock Server Socket receives a // new connection. When client side call API to connect to remote WiFi // WifiDirect GO service, it will return a WifiDirectServiceSocket to caller. @@ -177,6 +199,26 @@ class WifiDirectServerSocket : public api::WifiDirectServerSocket { bool server_socket_accepted_connection_ = false; }; +class WifiDirectDeviceDiscovered { + public: + explicit WifiDirectDeviceDiscovered( + const DeviceInformation& device_info); + + ~WifiDirectDeviceDiscovered() = default; + WifiDirectDeviceDiscovered(WifiDirectDeviceDiscovered&&) = default; + WifiDirectDeviceDiscovered& operator=(WifiDirectDeviceDiscovered&&) = default; + + std::string GetId() { return id_; } + DeviceInformation GetDeviceInformation() { + return windows_wifi_direct_device_; + } + + private: + DeviceInformation windows_wifi_direct_device_; + std::string id_; +}; + +// Container of operations that can be performed over the WifiLan medium. class WifiDirectMedium : public api::WifiDirectMedium { public: WifiDirectMedium(); @@ -217,54 +259,46 @@ class WifiDirectMedium : public api::WifiDirectMedium { const override; private: + // Medium status enum Value : char { kMediumStatusIdle = 0, kMediumStatusAccepting = (1 << 0), - kMediumStatusGOStarted = (1 << 1), + kMediumStatusBeaconing = (1 << 1), kMediumStatusConnecting = (1 << 2), kMediumStatusConnected = (1 << 3), }; // Medium Status int medium_status_ = kMediumStatusIdle; - bool IsWifiDirectServiceSupported(); + bool IsWifiDirectSupported(); bool IsIdle() { return medium_status_ == kMediumStatusIdle; } // Advertiser is accepting connection on server socket bool IsAccepting() { return (medium_status_ & kMediumStatusAccepting) != 0; } - // Advertiser started WifiDirect GO - bool IsGOStarted() { - return (medium_status_ & kMediumStatusGOStarted) != 0; - } - // Discoverer is connecting with the WifiDirect + // GO is starated and sending beacon + bool IsBeaconing() { return (medium_status_ & kMediumStatusBeaconing) != 0; } + // GC is connecting to the GO bool IsConnecting() { return (medium_status_ & kMediumStatusConnecting) != 0; } - // Discoverer is connected with the WifiDirect + // GC is connected to the GO bool IsConnected() { return (medium_status_ & kMediumStatusConnected) != 0; } - // Converts WiFiDirectServiceConfigurationMethod enum to a string. - static std::string ConfigMethodToString( - WiFiDirectServiceConfigurationMethod config_method); + // Advertising properties + WiFiDirectAdvertisementPublisher publisher_{nullptr}; + WiFiDirectConnectionListener listener_{nullptr}; + WiFiDirectDevice wifi_direct_device_{nullptr}; - WiFiDirectServiceAdvertiser advertiser_ = nullptr; - WiFiDirectService service_ = nullptr; - WiFiDirectServiceSession session_ = nullptr; - winrt::Windows::System::DispatcherQueueController controller_ = nullptr; - winrt::Windows::System::DispatcherQueue dispatcher_queue_ = nullptr; - DeviceInformation device_info_ = nullptr; + fire_and_forget OnStatusChanged( + WiFiDirectAdvertisementPublisher sender, + WiFiDirectAdvertisementPublisherStatusChangedEventArgs event); + event_token publisher_status_changed_token_; - fire_and_forget OnAdvertisementStatusChanged( - WiFiDirectServiceAdvertiser sender, IInspectable const& event); - fire_and_forget OnAutoAcceptSessionConnected( - WiFiDirectServiceAdvertiser sender, - WiFiDirectServiceAutoAcceptSessionConnectedEventArgs const& args); - fire_and_forget OnSessionRequested( - WiFiDirectServiceAdvertiser const& sender, - WiFiDirectServiceSessionRequestedEventArgs const& args); + fire_and_forget OnConnectionRequested( + WiFiDirectConnectionListener const& sender, + WiFiDirectConnectionRequestedEventArgs const& event); + event_token connection_requested_token_; - event_token advertisement_status_changed_token_; - event_token auto_accept_session_connected_token_; - event_token session_requested_token_; + bool IsAepPaired(winrt::hstring device_id); // Discovery properties DeviceWatcher device_watcher_{nullptr}; @@ -280,24 +314,43 @@ class WifiDirectMedium : public api::WifiDirectMedium { DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate); fire_and_forget Watcher_DeviceRemoved( DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate); - fire_and_forget Watcher_DeviceEnumerationCompleted(DeviceWatcher sender, - IInspectable inspectable); - fire_and_forget Watcher_DeviceStopped(DeviceWatcher sender, - IInspectable inspectable); + fire_and_forget Watcher_DeviceEnumerationCompleted( + DeviceWatcher sender, IInspectable inspectable); + fire_and_forget Watcher_DeviceStopped( + DeviceWatcher sender, IInspectable inspectable); + + fire_and_forget OnPairingRequested( + DeviceInformationCustomPairing const& sender, + DevicePairingRequestedEventArgs const& e); + void OnConnectionStatusChanged( + WiFiDirectDevice const& sender, + winrt::Windows::Foundation::IInspectable const& e); + // IAsyncOperation RequestPairDeviceAsync( + bool RequestPairDeviceAsync(DeviceInformationPairing pairing, + int group_owner_intent, + WiFiDirectConfigurationMethod config_method); + + std::unique_ptr connection_latch_; + absl::Mutex mutex_; + + absl::flat_hash_map> + discovered_devices_by_id_; + + absl::flat_hash_map> + connection_requested_devices_by_id_; bool is_interface_valid_ = false; WifiDirectCredentials* credentials_go_ = nullptr; WifiDirectCredentials credentials_gc_; std::string ip_address_local_; std::string ip_address_remote_; - - absl::Mutex mutex_; absl::CondVar is_ip_address_ready_; - // Keep the server socket listener pointer + WifiDirectServerSocket* server_socket_ptr_ ABSL_GUARDED_BY(mutex_) = nullptr; SubmittableExecutor listener_executor_; }; - } // namespace nearby::windows #endif // PLATFORM_IMPL_WINDOWS_WIFI_DIRECT_H_ diff --git a/internal/platform/implementation/windows/wifi_direct_medium.cc b/internal/platform/implementation/windows/wifi_direct_medium.cc index 6ac9f2c8..dac7d1a5 100644 --- a/internal/platform/implementation/windows/wifi_direct_medium.cc +++ b/internal/platform/implementation/windows/wifi_direct_medium.cc @@ -14,82 +14,58 @@ #include #include +#include #include +#include #include -#include #include #include -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" +#include "absl/strings/ascii.h" +#include "absl/strings/match.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" +#include "absl/time/clock.h" #include "absl/time/time.h" #include "internal/flags/nearby_flags.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/cancellation_flag_listener.h" +#include "internal/platform/count_down_latch.h" #include "internal/platform/feature_flags.h" #include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/implementation/wifi_direct.h" +#include "internal/platform/implementation/windows/device_info.h" +#include "internal/platform/implementation/windows/generated/winrt/base.h" #include "internal/platform/implementation/windows/socket_address.h" -#include "internal/platform/implementation/windows/utils.h" #include "internal/platform/implementation/windows/wifi_direct.h" #include "internal/platform/logging.h" -#include "internal/platform/prng.h" #include "internal/platform/wifi_credential.h" -namespace nearby { -namespace windows { +namespace nearby::windows { + namespace { -constexpr int kWaitingForConnectionTimeoutSeconds = 90; // seconds -// The prefix of the service name. -// Fully Qualified Service Name (FQSN) must follow reverse-DNS notation to -// ensure uniqueness and cross-platform compatibility. Otherwise, Windows -// prefixes the service name with "org.wi-fi.wfds.", which prevents Android -// devices from discovering the service. -// https://www.wi-fi.org/file-member/wi-fi-peer-to-peer-services-technical-specification-package -// Wi-Fi_Peer-to-Peer_Services_Technical_Specification_v1.2.pdf chapter 3.2 -constexpr absl::string_view kServiceNamePrefix = - "com.google.nearby.connection."; +constexpr int kWaitingForConnectionTimeoutSeconds = 60; // seconds +constexpr int kWaitingForRePair = 3; // seconds } // namespace +WifiDirectDeviceDiscovered::WifiDirectDeviceDiscovered( + const DeviceInformation& device_info) + : windows_wifi_direct_device_(device_info) { + id_ = winrt::to_string(device_info.Id()); +} + +// WifiDirectDeviceDiscovered::~WifiDirectDeviceDiscovered() {} WifiDirectMedium::WifiDirectMedium() { - LOG(INFO) << "WifiDirectMedium::WifiDirectMedium"; - // Create a DispatcherQueue for this thread. - controller_ = winrt::Windows::System::DispatcherQueueController:: - CreateOnDedicatedThread(); - dispatcher_queue_ = controller_.DispatcherQueue(); - if (!dispatcher_queue_) { - LOG(WARNING) << "Failed to get DispatcherQueue for current thread. " - "ConnectAsync might fail if not called from UI thread."; - } - is_interface_valid_ = IsWifiDirectServiceSupported(); + is_interface_valid_ = IsWifiDirectSupported(); } WifiDirectMedium::~WifiDirectMedium() { is_interface_valid_ = false; - listener_executor_.Shutdown(); StopWifiDirect(); DisconnectWifiDirect(); - if (controller_) { - // Asynchronously shut down the dispatcher queue. - winrt::Windows::Foundation::IAsyncAction shutdown_async = - controller_.ShutdownQueueAsync(); - - // Block and wait for the shutdown to complete. This ensures that any - // in-progress event handlers on the dedicated thread are finished - // before this object is fully destroyed. - shutdown_async.get(); - } } -bool WifiDirectMedium::IsWifiDirectServiceSupported() { - if (!IsIntelWifiAdapter()) { - LOG(INFO) << "Intel Wifi adapter is not found, WifiDirectService is not " - "supported."; - return false; - } - +bool WifiDirectMedium::IsWifiDirectSupported() { HANDLE wifi_direct_handle = nullptr; DWORD negotiated_version = 0; DWORD result = 0; @@ -105,9 +81,7 @@ bool WifiDirectMedium::IsWifiDirectServiceSupported() { return true; } -bool WifiDirectMedium::IsInterfaceValid() const { - return is_interface_valid_; -} +bool WifiDirectMedium::IsInterfaceValid() const { return is_interface_valid_; } // Discoverer connects to server socket std::unique_ptr WifiDirectMedium::ConnectToService( @@ -120,27 +94,9 @@ std::unique_ptr WifiDirectMedium::ConnectToService( return nullptr; } - std::string remote_ip_address; - if (ip_address.empty()) { - remote_ip_address = ip_address_remote_; - } else { - remote_ip_address = std::string(ip_address); - } - // when this API is called, GC may not finish connecting to GO, so we need to - // wait the connection is finished and IP address is ready. - if (remote_ip_address.empty()) { - LOG(INFO) << "Waiting for IP address to be ready."; - absl::MutexLock lock(mutex_); - is_ip_address_ready_.WaitWithTimeout( - &mutex_, absl::Seconds(kWaitingForConnectionTimeoutSeconds)); - if (ip_address_remote_.empty()) { - LOG(WARNING) - << "IP address is still empty, probably GC connecting to GO failed."; - return nullptr; - } - LOG(INFO) << "IP address is ready."; - remote_ip_address = ip_address_remote_; - } + LOG(INFO) << "Remote gateway: " << ip_address << ", Port: " << port; + + std::string remote_ip_address = ip_address_remote_; if (remote_ip_address.empty() || port == 0) { LOG(ERROR) << "no valid service address and port to connect: " @@ -149,11 +105,11 @@ std::unique_ptr WifiDirectMedium::ConnectToService( } SocketAddress server_address; - if (!server_address.FromString(server_address, remote_ip_address, port)) { + if (!SocketAddress::FromString(server_address, remote_ip_address, port)) { LOG(ERROR) << "no valid service address and port to connect."; return nullptr; } - VLOG(1) << "ConnectToService server address: " << server_address.ToString(); + LOG(INFO) << "ConnectToService server address: " << server_address.ToString(); // Try connecting to the service up to wifi_direct_max_connection_retries, // because it may fail first time if DHCP procedure is not finished yet. @@ -170,12 +126,16 @@ std::unique_ptr WifiDirectMedium::ConnectToService( platform::config_package_nearby::nearby_platform_feature:: kWifiHotspotConnectionTimeoutMillis); - VLOG(1) << "maximum connection retries=" << wifi_direct_max_connection_retries - << ", connection interval=" << wifi_direct_retry_interval_millis - << "ms, connection timeout=" - << wifi_direct_client_socket_connect_timeout_millis << "ms"; + LOG(INFO) << "maximum connection retries=" + << wifi_direct_max_connection_retries + << ", connection interval=" << wifi_direct_retry_interval_millis + << "ms, connection timeout=" + << wifi_direct_client_socket_connect_timeout_millis << "ms"; LOG(INFO) << "Connect to service "; + // In the test, GO server takes longer to started, so wait for 500ms before + // trying to connect to the service. + absl::SleepFor(absl::Milliseconds(500)); for (int i = 0; i < wifi_direct_max_connection_retries; ++i) { auto wifi_direct_socket = std::make_unique(); @@ -197,14 +157,13 @@ std::unique_ptr WifiDirectMedium::ConnectToService( } bool result = wifi_direct_socket->Connect(server_address); - if (!result) { + if (result) { + LOG(INFO) << "connected to remote service "; + return wifi_direct_socket; + } else { LOG(WARNING) << "reconnect to service at " << (i + 1) << "th times"; Sleep(wifi_direct_retry_interval_millis); - continue; } - - LOG(INFO) << "connected to remote service "; - return wifi_direct_socket; } LOG(ERROR) << "Failed to connect to service "; @@ -218,7 +177,7 @@ std::unique_ptr WifiDirectMedium::ListenForService( << " :Start to listen connection from WiFiDirect client."; absl::MutexLock lock(mutex_); - if (!IsGOStarted()) { + if (!IsBeaconing()) { LOG(WARNING) << "WifiDirect GO is not started, skip."; return nullptr; } @@ -262,8 +221,7 @@ std::unique_ptr WifiDirectMedium::ListenForService( if (port == 0) { port = FeatureFlags::GetInstance().GetFlags().wifi_direct_default_port; } - if (server_socket_ptr_ && - server_socket_ptr_->Listen(port)) { + if (server_socket_ptr_ && server_socket_ptr_->Listen(port)) { medium_status_ |= kMediumStatusAccepting; // Setup close notifier after listen started. @@ -272,6 +230,7 @@ std::unique_ptr WifiDirectMedium::ListenForService( LOG(INFO) << "Server socket was closed."; medium_status_ &= (~kMediumStatusAccepting); server_socket_ptr_ = nullptr; + is_ip_address_ready_.SignalAll(); }); LOG(INFO) << "Started to listen serive on port " << server_socket_ptr_->GetPort(); @@ -285,467 +244,488 @@ std::unique_ptr WifiDirectMedium::ListenForService( }); LOG(INFO) << "Started to listen service on port " << port; - return server_socket; } bool WifiDirectMedium::StartWifiDirect( WifiDirectCredentials* wifi_direct_credentials) { - LOG(INFO) << "WifiDirectMedium::StartWifiDirect"; - absl::MutexLock lock(mutex_); - if (IsGOStarted()) { - LOG(WARNING) << "Already started WifiDirect GO, skip."; + LOG(INFO) << __func__ << ": Start to create WiFiDirect."; + if (IsBeaconing()) { + LOG(WARNING) << "Cannot create WiFiDirect GO again when it is running."; return true; } - - credentials_go_ = wifi_direct_credentials; - Prng prng; - std::string pin = absl::StrFormat("%04x", prng.NextUint32()); - credentials_go_->SetPin(pin); - - std::string device_name = - absl::StrCat(kServiceNamePrefix, std::to_string(prng.NextUint32())); - credentials_go_->SetDeviceName(device_name); - LOG(INFO) << "device_name:pin " << device_name << ":" << pin; - - // Create Advertiser object - advertiser_ = WiFiDirectServiceAdvertiser(winrt::to_hstring(device_name)); - advertisement_status_changed_token_ = advertiser_.AdvertisementStatusChanged( - {this, &WifiDirectMedium::OnAdvertisementStatusChanged}); - auto_accept_session_connected_token_ = advertiser_.AutoAcceptSessionConnected( - {this, &WifiDirectMedium::OnAutoAcceptSessionConnected}); - session_requested_token_ = advertiser_.SessionRequested( - {this, &WifiDirectMedium::OnSessionRequested}); - - advertiser_.AutoAcceptSession(false); - advertiser_.PreferGroupOwnerMode(true); - advertiser_.ServiceStatus(WiFiDirectServiceStatus::Available); - // Config Methods - WiFiDirectServiceConfigurationMethod config_method; - if (pin.empty()) { - config_method = WiFiDirectServiceConfigurationMethod::Default; // NOLINT - } else { - config_method = WiFiDirectServiceConfigurationMethod::PinDisplay; - } - advertiser_.PreferredConfigurationMethods().Clear(); - advertiser_.PreferredConfigurationMethods().Append(config_method); - try { - advertiser_.Start(); - LOG(INFO) << "Start WifiDirect GO Status: " - << (int)advertiser_.AdvertisementStatus(); - if ((advertiser_.AdvertisementStatus() == - WiFiDirectServiceAdvertisementStatus::Created) || - (advertiser_.AdvertisementStatus() == - WiFiDirectServiceAdvertisementStatus::Started)) { - medium_status_ |= kMediumStatusGOStarted; - return true; + publisher_ = WiFiDirectAdvertisementPublisher(); + publisher_status_changed_token_ = + publisher_.StatusChanged({this, &WifiDirectMedium::OnStatusChanged}); + listener_ = WiFiDirectConnectionListener(); + connection_requested_token_ = listener_.ConnectionRequested( + {this, &WifiDirectMedium::OnConnectionRequested}); + // Normal mode: The device is highly discoverable so long as the app is in + // the foreground. + publisher_.Advertisement().ListenStateDiscoverability( + WiFiDirectAdvertisementListenStateDiscoverability::Normal); + // Enable Autonomous GO mode + publisher_.Advertisement().IsAutonomousGroupOwnerEnabled(true); + + publisher_.Start(); + if (publisher_.Status() == + WiFiDirectAdvertisementPublisherStatus::Started) { + LOG(INFO) << "Windows WIFI Direct AutoGO started"; + medium_status_ |= kMediumStatusBeaconing; + + std::optional computer_name = DeviceInfo().GetOsDeviceName(); + if (computer_name.has_value()) { + std::string device_name = absl::AsciiStrToUpper(computer_name.value()); + LOG(INFO) << "GO Device Name(Computer Name) is:" << device_name; + credentials_go_ = wifi_direct_credentials; + // Current pairing scheme uses ConfirmOnly, so pin is empty; + credentials_go_->SetPin(""); + credentials_go_->SetDeviceName(device_name); + return true; + } + LOG(ERROR) << "Windows WIFI Direct AutoGO failed to get computer name"; } - LOG(ERROR) << "Start WifiDirect GO failed."; - return false; + LOG(ERROR) << "Windows WIFI Direct AutoGO fails to start"; } catch (std::exception exception) { - LOG(ERROR) << __func__ << ": Start WifiDirect GO failed. Exception: " + LOG(ERROR) << __func__ << ": Cannot start WifiDirect GO. Exception: " << exception.what(); } catch (const winrt::hresult_error& error) { - LOG(ERROR) << __func__ << ": Start WifiDirect GO failed. WinRT exception: " + LOG(ERROR) << __func__ << ": Cannot start WifiDirect GO. WinRT exception: " << error.code() << ": " << winrt::to_string(error.message()); } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exeption."; + LOG(ERROR) << __func__ << ": Unknown exception."; } - advertiser_.AdvertisementStatusChanged(advertisement_status_changed_token_); - advertiser_.AutoAcceptSessionConnected(auto_accept_session_connected_token_); - advertiser_.SessionRequested(session_requested_token_); - advertiser_.PreferredConfigurationMethods().Clear(); - advertiser_ = nullptr; + + if (listener_) { + listener_.ConnectionRequested(connection_requested_token_); + } + if (publisher_) { + publisher_.StatusChanged(publisher_status_changed_token_); + } + listener_ = nullptr; + publisher_ = nullptr; return false; } bool WifiDirectMedium::StopWifiDirect() { - LOG(INFO) << "WifiDirectMedium::StopWifiDirect"; - absl::MutexLock lock(mutex_); - if (!IsGOStarted()) { - LOG(WARNING) << "Cannot stop Service because no Service is started."; - return true; + std::vector> devices; + { + absl::MutexLock lock(mutex_); + devices.reserve(connection_requested_devices_by_id_.size()); + for (auto& [id, device] : connection_requested_devices_by_id_) { + devices.push_back(std::move(device)); + } + connection_requested_devices_by_id_.clear(); } - try { - if (advertiser_) { - advertiser_.Stop(); - advertiser_.AdvertisementStatusChanged( - advertisement_status_changed_token_); - advertiser_.AutoAcceptSessionConnected( - auto_accept_session_connected_token_); - advertiser_.SessionRequested(session_requested_token_); - advertiser_ = nullptr; - device_info_ = nullptr; - session_ = nullptr; + for (auto& device : devices) { + LOG(INFO) << "Unpair WifiDirect GC: " << device->GetId(); + DeviceInformationPairing pairing = device->GetDeviceInformation().Pairing(); + if (pairing.IsPaired()) { + LOG(INFO) << "GC Paired, unpair it"; + DeviceUnpairingResult unpairing_result = pairing.UnpairAsync().get(); + LOG(INFO) << "GC Unpair result:" + << static_cast(unpairing_result.Status()); + if (unpairing_result.Status() == DeviceUnpairingResultStatus::Unpaired) { + LOG(INFO) << "GC Unpaired successfully"; + } else { + LOG(INFO) << "GC Unpair failed"; + } + } else { + LOG(INFO) << "GC Not Paired, skip"; } - medium_status_ &= (~kMediumStatusGOStarted); + } + + absl::MutexLock lock(mutex_); + is_ip_address_ready_.SignalAll(); + + if (!IsBeaconing()) { + LOG(WARNING) + << "Cannot stop advertising because no advertising is running."; + return true; + } + try { + if (publisher_) { + publisher_.Stop(); + listener_.ConnectionRequested(connection_requested_token_); + publisher_.StatusChanged(publisher_status_changed_token_); + wifi_direct_device_ = nullptr; + listener_ = nullptr; + publisher_ = nullptr; + LOG(INFO) << "succeeded to stop WIFI advertising"; + } + medium_status_ &= (~kMediumStatusBeaconing); medium_status_ &= (~kMediumStatusConnected); medium_status_ &= (~kMediumStatusAccepting); server_socket_ptr_ = nullptr; ip_address_local_.clear(); ip_address_remote_.clear(); return true; - } catch (std::exception exception) { + } catch (const std::exception& exception) { LOG(ERROR) << __func__ << ": Stop WifiDirect GO failed. Exception: " << exception.what(); } catch (const winrt::hresult_error& error) { LOG(ERROR) << __func__ << ": Stop WifiDirect GO failed. WinRT exception: " << error.code() << ": " << winrt::to_string(error.message()); } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exeption."; + LOG(ERROR) << __func__ << ": Unknown exception."; } return false; } -std::string WifiDirectMedium::ConfigMethodToString( - WiFiDirectServiceConfigurationMethod config_method) { - switch (config_method) { - case WiFiDirectServiceConfigurationMethod::Default: - return "Default"; - case WiFiDirectServiceConfigurationMethod::PinDisplay: - return "PinDisplay"; - case WiFiDirectServiceConfigurationMethod::PinEntry: - return "PinEntry"; - default: - return "Unknown"; +fire_and_forget WifiDirectMedium::OnStatusChanged( + WiFiDirectAdvertisementPublisher sender, + WiFiDirectAdvertisementPublisherStatusChangedEventArgs event) { + LOG(INFO) << "WIFI direct PublisherStatusChangedEvent: " + << static_cast(event.Status()); + if (event.Status() == WiFiDirectAdvertisementPublisherStatus::Started) { + LOG(INFO) << "Receive WiFi direct/SoftAP Started event."; + if (sender.Advertisement().LegacySettings().IsEnabled()) { + LOG(INFO) << "WIFI direct Legacy AP ssid: " + << winrt::to_string( + publisher_.Advertisement().LegacySettings().Ssid()); + LOG(INFO) << "WIFI direct Legacy AP pw: " + << winrt::to_string(publisher_.Advertisement() + .LegacySettings() + .Passphrase() + .Password()); + } + return winrt::fire_and_forget(); + } else if (event.Status() == + WiFiDirectAdvertisementPublisherStatus::Created) { + LOG(INFO) << "Receive WiFi direct/SoftAP Created event."; + return winrt::fire_and_forget(); + } else if (event.Status() == + WiFiDirectAdvertisementPublisherStatus::Stopped) { + LOG(INFO) << "Receive WiFi direct/SoftAP Stopped event."; + } else if (event.Status() == + WiFiDirectAdvertisementPublisherStatus::Aborted) { + LOG(INFO) << "Receive WiFi direct/SoftAP Aborted event."; } -} - -fire_and_forget WifiDirectMedium::OnAdvertisementStatusChanged( - WiFiDirectServiceAdvertiser sender, IInspectable const& event) { - LOG(INFO) << "WiFiDirectServiceAdvertiser status changed: " - << (int)sender.AdvertisementStatus(); - auto status = sender.ServiceStatus(); - switch (status) { - case WiFiDirectServiceStatus ::Available: - LOG(INFO) << "WifiDirectAdvertiser service status changed: " - "status: Available"; - break; - case WiFiDirectServiceStatus ::Busy: - LOG(INFO) << "WifiDirectAdvertiser service status changed: " - "status: Busy"; - break; - case WiFiDirectServiceStatus ::Custom: - LOG(INFO) << "WifiDirectAdvertiser service status changed: " - "status: Custom"; - break; - default: - LOG(INFO) << "WifiDirectAdvertiser service status changed: " - "Code: " - << (int)status; - break; + // Publisher is stopped. Need to clean up the publisher. + { + absl::MutexLock lock(mutex_); + if (publisher_ != nullptr) { + LOG(ERROR) << "Windows WiFi Direct cleanup."; + listener_.ConnectionRequested(connection_requested_token_); + publisher_.StatusChanged(publisher_status_changed_token_); + wifi_direct_device_ = nullptr; + listener_ = nullptr; + publisher_ = nullptr; + medium_status_ &= (~kMediumStatusBeaconing); + } } return winrt::fire_and_forget(); } -fire_and_forget WifiDirectMedium::OnAutoAcceptSessionConnected( - WiFiDirectServiceAdvertiser sender, - WiFiDirectServiceAutoAcceptSessionConnectedEventArgs const& args) { - LOG(INFO) << "WifiDirectMedium::OnAutoAcceptSessionConnected"; - try { - auto session = args.Session(); - if (!session) { - LOG(ERROR) << "OnAutoAcceptSessionConnected returned null session"; - co_return; - } - session_ = std::move(session); - LOG(INFO) << "Service Address: " - << winrt::to_string(session_.ServiceAddress()) - << ", Service Name: " << winrt::to_string(session_.ServiceName()) - << ", Advertisement ID: " << session_.AdvertisementId() - << ", Session Address: " - << winrt::to_string(session_.SessionAddress()) - << ", Session ID: " << session_.SessionId(); - // Subscribe to events to prevent early teardown - session_.SessionStatusChanged([](auto const& s, auto const& e) { - LOG(INFO) << "GO: Session status changed"; - }); - co_return; - } catch (std::exception exception) { - LOG(ERROR) << __func__ - << ": Failed to get session. Exception: " << exception.what(); - } catch (const winrt::hresult_error& error) { - LOG(ERROR) << __func__ - << ": Failed to get session. WinRT exception: " << error.code() - << ": " << winrt::to_string(error.message()); - } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exeption."; - } -} +fire_and_forget WifiDirectMedium::OnConnectionRequested( + WiFiDirectConnectionListener const& sender, + WiFiDirectConnectionRequestedEventArgs const& event) { + WiFiDirectConnectionRequest connection_request = event.GetConnectionRequest(); + winrt::hstring device_name = connection_request.DeviceInformation().Name(); + winrt::hstring device_id = connection_request.DeviceInformation().Id(); + LOG(INFO) << "Receive connection request from: " + << winrt::to_string(device_name) + << "; device ID: " << winrt::to_string(device_id); -fire_and_forget WifiDirectMedium::OnSessionRequested( - WiFiDirectServiceAdvertiser const& sender, - WiFiDirectServiceSessionRequestedEventArgs const& args) { - try { - auto request = args.GetSessionRequest(); - if (!request) { - LOG(ERROR) << "OnSessionRequested returned null session request"; - co_return; - } - device_info_ = request.DeviceInformation(); - LOG(INFO) << "GO: OnSessionRequested: " - << winrt::to_string(device_info_.Id()) - << " Is GroupFormationNeeded: " - << request.ProvisioningInfo().IsGroupFormationNeeded() - << ", SelectedConfigurationMethod: " - << ConfigMethodToString( - request.ProvisioningInfo().SelectedConfigurationMethod()); + DeviceInformation windows_device_info(connection_request.DeviceInformation()); + auto deviceInfoP = + std::make_unique(windows_device_info); - LOG(INFO) << "GO: Dispatch to UI thread to call ConnectAsync"; - dispatcher_queue_.TryEnqueue([this]() { - LOG(INFO) << "GO: TryEnqueue: calling ConnectAsync"; - - absl::MutexLock lock(mutex_); - WiFiDirectServiceSession session = nullptr; - auto pin = credentials_go_->GetPin(); - if (pin.empty()) { - session = advertiser_.ConnectAsync(device_info_).get(); // NOLINT - } else { - session = advertiser_.ConnectAsync(device_info_, winrt::to_hstring(pin)) - .get(); - } - LOG(INFO) << "GO: TryEnqueue: Wait for ConnectAsync finish"; - if (!session) { - LOG(ERROR) << "OnSessionRequested returned null session"; - return; - } - LOG(INFO) << "GO: TryEnqueue: OnSessionRequested: ConnectAsync succeeded"; - session_ = std::move(session); - - auto endpoint_pairs = session_.GetConnectionEndpointPairs(); - if (endpoint_pairs.Size() > 0) { - auto const& pair = endpoint_pairs.GetAt(0); - ip_address_local_ = - winrt::to_string(pair.LocalHostName().DisplayName()); - ip_address_remote_ = - winrt::to_string(pair.RemoteHostName().DisplayName()); - LOG(INFO) << "GO: Local IP: " << ip_address_local_ - << ", Remote IP: " << ip_address_remote_; - is_ip_address_ready_.SignalAll(); - } else { - LOG(WARNING) << "GO: No connection endpoint pairs found."; - } - medium_status_ |= kMediumStatusConnected; - - LOG(INFO) << "Service Address: " - << winrt::to_string(session_.ServiceAddress()) - << ", Service Name: " - << winrt::to_string(session_.ServiceName()) - << ", Advertisement ID: " << session_.AdvertisementId() - << ", Session Address: " - << winrt::to_string(session_.SessionAddress()) - << ", Session ID: " << session_.SessionId(); - // Subscribe to events to prevent early teardown - session_.SessionStatusChanged([](auto const& s, auto const& e) { - LOG(INFO) << "GO: TryEnqueue: Session status changed"; - }); - }); - LOG(INFO) << "GO: Dispatch to UI thread to call ConnectAsync finish"; - } catch (std::exception exception) { - LOG(ERROR) << __func__ - << ": Failed to get session. Exception: " << exception.what(); - } catch (const winrt::hresult_error& error) { - LOG(ERROR) << __func__ - << ": Failed to get session. WinRT exception: " << error.code() - << ": " << winrt::to_string(error.message()); - } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exeption."; - } -} - -bool WifiDirectMedium::ConnectWifiDirect( - const WifiDirectCredentials& credentials) { - LOG(INFO) << "WifiDirectMedium::ConnectWifiDirect"; - absl::MutexLock lock(mutex_); - if (IsConnecting()) { - LOG(WARNING) << "Service discovery already running"; - return false; + { + absl::MutexLock lock(&mutex_); + connection_requested_devices_by_id_[device_id] = std::move(deviceInfoP); } - if (device_watcher_) { - LOG(WARNING) - << "Device Watcher has already been set, please investigate! Skip"; - return false; - } + bool is_paired = false; + DeviceInformationPairing pairing = + connection_request.DeviceInformation().Pairing(); + WiFiDirectConfigurationMethod config_method = + WiFiDirectConfigurationMethod::PushButton; - credentials_gc_ = credentials; - if (credentials_gc_.GetDeviceName().empty()) { - LOG(ERROR) << "GC: Device name is empty, return false"; - return false; - } - winrt::hstring device_selector = WiFiDirectService::GetSelector( - winrt::to_hstring(credentials_gc_.GetDeviceName())); - const winrt::param::iterable requested_properties = - winrt::single_threaded_vector({ - winrt::to_hstring("System.Devices.WiFiDirectServices.ServiceAddress"), - winrt::to_hstring("System.Devices.WiFiDirectServices.ServiceName"), - winrt::to_hstring( - "System.Devices.WiFiDirectServices.ServiceInformation"), - winrt::to_hstring( - "System.Devices.WiFiDirectServices.AdvertisementId"), - winrt::to_hstring( - "System.Devices.WiFiDirectServices.ServiceConfigMethods"), - }); - LOG(INFO) << "Create device watcher"; - device_watcher_ = - DeviceInformation::CreateWatcher(device_selector, requested_properties); - device_watcher_added_event_token_ = - device_watcher_.Added({this, &WifiDirectMedium::Watcher_DeviceAdded}); - device_watcher_updated_event_token_ = - device_watcher_.Updated({this, &WifiDirectMedium::Watcher_DeviceUpdated}); - device_watcher_removed_event_token_ = - device_watcher_.Removed({this, &WifiDirectMedium::Watcher_DeviceRemoved}); - device_watcher_enumeration_completed_event_token_ = - device_watcher_.EnumerationCompleted( - {this, &WifiDirectMedium::Watcher_DeviceEnumerationCompleted}); - device_watcher_stopped_event_token_ = - device_watcher_.Stopped({this, &WifiDirectMedium::Watcher_DeviceStopped}); - device_watcher_.Start(); - medium_status_ |= kMediumStatusConnecting; - LOG(INFO) << "Started to discover WifiDirect service and connect."; - return true; -} - -fire_and_forget WifiDirectMedium::Watcher_DeviceAdded( - DeviceWatcher sender, DeviceInformation device_info) { - LOG(INFO) << "Device Service founded for device ID " - << winrt::to_string(device_info.Id()) - << "; device name: " << winrt::to_string(device_info.Name()); - - auto props = device_info.Properties(); - if (props.HasKey(L"System.Devices.WiFiDirectServices.ServiceName")) { - winrt::hstring svc_name = winrt::unbox_value( - props.Lookup(L"System.Devices.WiFiDirectServices.ServiceName")); - LOG(INFO) << "Discovered service: " << winrt::to_string(svc_name); - } - try { - service_ = co_await WiFiDirectService::FromIdAsync(device_info.Id()); - if (!service_) { - LOG(ERROR) << "FromIdAsync returned null service"; - co_return; - } - LOG(INFO) << "GC: ConnectAsync in Watcher_DeviceAdded"; - service_.PreferGroupOwnerMode(false); - - WiFiDirectServiceSession session = nullptr; - auto pin = credentials_gc_.GetPin(); - if (pin.empty()) { - session = service_.ConnectAsync().get(); // NOLINT + if (pairing.IsPaired() || IsAepPaired(device_id)) { + if (pairing.IsPaired()) { + LOG(INFO) << "GO Paired"; } else { - auto prov_info = co_await service_.GetProvisioningInfoAsync( - WiFiDirectServiceConfigurationMethod::PinEntry); + LOG(INFO) << "GO Not Paired, but AEP is paired"; + } + LOG(INFO) << "GO already paired, unpair it first"; + DeviceUnpairingResult unpairing_result = pairing.UnpairAsync().get(); + LOG(INFO) << "GO Unpair result:" + << static_cast(unpairing_result.Status()); + if (unpairing_result.Status() == DeviceUnpairingResultStatus::Unpaired || + unpairing_result.Status() == + DeviceUnpairingResultStatus::AlreadyUnpaired) { + LOG(INFO) << "GO Unpaired GC, Re-pair"; + // Wait for kWaitingForRePair seconds to allow WiFi driver to stabilize. + absl::SleepFor(absl::Seconds(kWaitingForRePair)); + // Refresh device info after unpairing. + DeviceInformation refreshed_device_info = + DeviceInformation::CreateFromIdAsync(device_id).get(); + is_paired = RequestPairDeviceAsync(refreshed_device_info.Pairing(), 14, + config_method); + } else { + is_paired = true; + LOG(INFO) << "GO Unpair failed, skip pairing"; + } + } else { + LOG(INFO) << "GO trying to pair with GC"; + is_paired = RequestPairDeviceAsync(pairing, 14, config_method); + } - if (prov_info.IsGroupFormationNeeded()) { - LOG(INFO) << "GC: Group formation needed"; - } else { - LOG(INFO) << "GC: Group formation not needed"; - } - LOG(INFO) << "GC: SelectedConfigurationMethod: " - << ConfigMethodToString( - prov_info.SelectedConfigurationMethod()); - - session = service_.ConnectAsync(winrt::to_hstring(pin)).get(); + if (is_paired) { + WiFiDirectDevice device = nullptr; + try { + device = WiFiDirectDevice::FromIdAsync(device_id).get(); + } catch (winrt::hresult_error const& ex) { + LOG(ERROR) << __func__ << ": winrt exception: " << ex.code() << ": " + << winrt::to_string(ex.message()); + return winrt::fire_and_forget(); } - if (!session) { - LOG(ERROR) << "GC: ConnectAsync returned null session"; - co_return; - } - LOG(INFO) << "GC: ConnectAsync succeeded"; - session_ = std::move(session); + device.ConnectionStatusChanged( + {this, &WifiDirectMedium::OnConnectionStatusChanged}); + + IVectorView endpoint_pairs = + device.GetConnectionEndpointPairs(); - auto endpoint_pairs = session_.GetConnectionEndpointPairs(); if (endpoint_pairs.Size() > 0) { auto const& pair = endpoint_pairs.GetAt(0); - ip_address_local_ = winrt::to_string(pair.LocalHostName().DisplayName()); - ip_address_remote_ = + std::string local_ip = + winrt::to_string(pair.LocalHostName().DisplayName()); + std::string remote_ip = winrt::to_string(pair.RemoteHostName().DisplayName()); - LOG(INFO) << "GC: Local IP: " << ip_address_local_ + + absl::MutexLock lock(&mutex_); + wifi_direct_device_ = device; + ip_address_local_ = local_ip; + ip_address_remote_ = remote_ip; + LOG(INFO) << "GO: Local IP: " << ip_address_local_ << ", Remote IP: " << ip_address_remote_; - } else { - LOG(WARNING) << "GC: No connection endpoint pairs found."; - } - - LOG(INFO) << "Service Address: " - << winrt::to_string(session_.ServiceAddress()) - << ", Service Name: " << winrt::to_string(session_.ServiceName()) - << ", Advertisement ID: " << session_.AdvertisementId() - << ", Session Address: " - << winrt::to_string(session_.SessionAddress()) - << ", Session ID: " << session_.SessionId(); - { - absl::MutexLock lock(mutex_); is_ip_address_ready_.SignalAll(); + } else { + LOG(WARNING) << "GO: No connection endpoint pairs found."; } - medium_status_ |= kMediumStatusConnected; - - // Subscribe to events to prevent early teardown - session_.SessionStatusChanged([](auto const& s, auto const& e) { - LOG(INFO) << "GC: TryEnqueue: Session status changed"; - }); - } catch (std::exception exception) { - LOG(ERROR) << __func__ - << ": Failed to resolve WiFiDirectService from Id. Exception: " - << exception.what(); - } catch (const winrt::hresult_error& error) { - LOG(ERROR) - << __func__ - << ": Failed to resolve WiFiDirectService from Id. WinRT exception: " - << error.code() << ": " << winrt::to_string(error.message()); - } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exeption."; } + return winrt::fire_and_forget(); } -fire_and_forget WifiDirectMedium::Watcher_DeviceUpdated( - DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { - VLOG(1) << "WifiDirectMedium::Watcher_DeviceUpdated"; - return fire_and_forget(); +// In Windows, a single physical device can appear in the system as multiple +// different "objects" (e.g., a WiFi Direct object, a Bluetooth object, etc.). +// When a WiFi Direct connection request comes in, the code checks if Windows +// already has a "Paired" record for that physical MAC address under a different +// category. If it finds one, it considers the device "already known" to the +// system. The goal is to find and remove any stale pairing records that might +// cause the new WiFi Direct pairing to fail or hang. +bool WifiDirectMedium::IsAepPaired(winrt::hstring device_id) { + try { + DeviceInformation device_info = + DeviceInformation::CreateFromIdAsync( + device_id, {L"System.Devices.Aep.DeviceAddress"}) + .get(); + + auto properties = device_info.Properties(); + if (!properties.HasKey(L"System.Devices.Aep.DeviceAddress")) { + return false; + } + + winrt::hstring aep_device_address = winrt::unbox_value( + properties.Lookup(L"System.Devices.Aep.DeviceAddress")); + LOG(INFO) << "aep_device_address: " << winrt::to_string(aep_device_address); + if (aep_device_address.empty()) { + return false; + } + + winrt::hstring device_selector = + L"System.Devices.Aep.DeviceAddress:=\"" + aep_device_address + L"\""; + LOG(INFO) << "Finding devices with selector: " + << winrt::to_string(device_selector); + DeviceInformationCollection device_collection = + DeviceInformation::FindAllAsync(device_selector, + {L"System.Devices.Aep.IsPaired"}, + DeviceInformationKind::Device) + .get(); + + LOG(INFO) << "Found " << device_collection.Size() + << " devices with that MAC address."; + for (auto const& device : device_collection) { + LOG(INFO) << "Checking device: " << winrt::to_string(device.Name()) + << ", Id: " << winrt::to_string(device.Id()); + auto pairing = device.Pairing(); + if (pairing && pairing.IsPaired()) { + LOG(INFO) << "Device is paired."; + return true; + } + LOG(INFO) << "Device is not paired."; + } + return false; + } catch (std::exception exception) { + LOG(ERROR) << __func__ << " failed. Exception: " << exception.what(); + } catch (const winrt::hresult_error& error) { + LOG(ERROR) << __func__ << " failed. WinRT exception: " << error.code() + << ": " << winrt::to_string(error.message()); + } catch (...) { + LOG(ERROR) << __func__ << ": Unknown exception."; + } + return false; } -fire_and_forget WifiDirectMedium::Watcher_DeviceRemoved( - DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { - LOG(INFO) << "WifiDirectMedium::Watcher_DeviceRemoved"; - return fire_and_forget(); -} +// Returns true once the WifiLan discovery has been initiated. +bool WifiDirectMedium::ConnectWifiDirect( + const WifiDirectCredentials& credentials) { + DisconnectWifiDirect(); + LOG(INFO) << "WifiDirectMedium::ConnectWifiDirect"; + { + absl::MutexLock lock(mutex_); + if (IsConnecting()) { + LOG(WARNING) << "GC discovery already running."; + return false; + } -fire_and_forget WifiDirectMedium::Watcher_DeviceEnumerationCompleted( - DeviceWatcher sender, IInspectable inspectable) { - LOG(INFO) << "WifiDirectMedium::Watcher_DeviceEnumerationCompleted"; - return fire_and_forget(); -} + if (IsBeaconing()) { + LOG(WARNING) << "Already acting as GO, skip discovery."; + return false; + } -fire_and_forget WifiDirectMedium::Watcher_DeviceStopped( - DeviceWatcher sender, IInspectable inspectable) { - medium_status_ &= (~kMediumStatusConnecting); - return fire_and_forget(); + if (device_watcher_) { + LOG(WARNING) + << "Device Watcher has already been set, please investigate! Skip"; + return false; + } + + credentials_gc_ = credentials; + if (credentials_gc_.GetDeviceName().empty()) { + LOG(ERROR) << "GC: Device name is empty, return false"; + return false; + } + + try { + discovered_devices_by_id_.clear(); + connection_requested_devices_by_id_.clear(); + winrt::hstring device_selector = WiFiDirectDevice::GetDeviceSelector( + WiFiDirectDeviceSelectorType::AssociationEndpoint); + const winrt::param::iterable requested_properties = + winrt::single_threaded_vector( + {winrt::to_hstring( + "System.Devices.WiFiDirect.InformationElements"), + winrt::to_hstring("System.Devices.Aep.CanPair"), + winrt::to_hstring("System.Devices.Aep.IsPaired")}); + device_watcher_ = DeviceInformation::CreateWatcher( + device_selector, requested_properties, + DeviceInformationKind::AssociationEndpoint); + device_watcher_added_event_token_ = + device_watcher_.Added({this, &WifiDirectMedium::Watcher_DeviceAdded}); + device_watcher_updated_event_token_ = device_watcher_.Updated( + {this, &WifiDirectMedium::Watcher_DeviceUpdated}); + device_watcher_removed_event_token_ = device_watcher_.Removed( + {this, &WifiDirectMedium::Watcher_DeviceRemoved}); + device_watcher_enumeration_completed_event_token_ = + device_watcher_.EnumerationCompleted( + {this, &WifiDirectMedium::Watcher_DeviceEnumerationCompleted}); + device_watcher_stopped_event_token_ = device_watcher_.Stopped( + {this, &WifiDirectMedium::Watcher_DeviceStopped}); + connection_latch_ = std::make_unique(1); + device_watcher_.Start(); + medium_status_ |= kMediumStatusConnecting; + } catch (const std::exception& exception) { + LOG(ERROR) << __func__ << " failed. Exception: " << exception.what(); + goto error; + } catch (const winrt::hresult_error& error) { + LOG(ERROR) << __func__ << " failed. WinRT exception: " << error.code() + << ": " << winrt::to_string(error.message()); + goto error; + } catch (...) { + LOG(ERROR) << __func__ << ": Unknown exception."; + goto error; + } + } + + LOG(INFO) << "Started to discover and wait 30s for connection."; + connection_latch_->Await(absl::Seconds(30)); + { + absl::MutexLock lock(mutex_); + if (IsConnected()) { + LOG(INFO) << "WifiDirectMedium::ConnectWifiDirect succeeded."; + return true; + } else { + LOG(WARNING) << "WifiDirectMedium::ConnectWifiDirect failed."; + } + } + +error: + { + absl::MutexLock lock(mutex_); + LOG(ERROR) << "GC discovery failed or pairing to GO failed."; + if (device_watcher_) { + device_watcher_.Stop(); + device_watcher_.Added(device_watcher_added_event_token_); + device_watcher_.Updated(device_watcher_updated_event_token_); + device_watcher_.Removed(device_watcher_removed_event_token_); + device_watcher_.EnumerationCompleted( + device_watcher_enumeration_completed_event_token_); + device_watcher_.Stopped(device_watcher_stopped_event_token_); + } + + device_watcher_ = nullptr; + medium_status_ &= (~kMediumStatusConnecting); + medium_status_ &= (~kMediumStatusConnected); + } + return false; } bool WifiDirectMedium::DisconnectWifiDirect() { - LOG(WARNING) << "Stop connecting."; - absl::MutexLock lock(mutex_); - if (!IsConnecting()) { - LOG(WARNING) << "no discovering service to stop."; - return false; + LOG(INFO) << "WifiDirectMedium::DisconnectWifiDirect"; + std::vector> devices; + { + absl::MutexLock lock(mutex_); + devices.reserve(discovered_devices_by_id_.size()); + for (auto& [id, device] : discovered_devices_by_id_) { + devices.push_back(std::move(device)); + } + discovered_devices_by_id_.clear(); } + + for (auto& device : devices) { + LOG(INFO) << "Unpair WifiDirect GO: " << device->GetId(); + DeviceInformationPairing pairing = device->GetDeviceInformation().Pairing(); + if (pairing.IsPaired()) { + LOG(INFO) << "GC Paired, unpair it"; + DeviceUnpairingResult unpairing_result = pairing.UnpairAsync().get(); + LOG(INFO) << "GC Unpair result:" + << static_cast(unpairing_result.Status()); + if (unpairing_result.Status() == DeviceUnpairingResultStatus::Unpaired) { + LOG(INFO) << "GC Unpaired successfully"; + } else { + LOG(INFO) << "GC Unpair failed"; + } + } else { + LOG(INFO) << "GC Not Paired, skip"; + } + } + + absl::MutexLock lock(mutex_); + if (!IsConnecting() && !IsConnected()) { + LOG(WARNING) << "WifiDirect GC is not connecting, skip"; + return true; + } + LOG(WARNING) << "Stop connecting."; try { - device_watcher_.Stop(); - device_watcher_.Added(device_watcher_added_event_token_); - device_watcher_.Updated(device_watcher_updated_event_token_); - device_watcher_.EnumerationCompleted( - device_watcher_enumeration_completed_event_token_); - device_watcher_.Removed(device_watcher_removed_event_token_); - device_watcher_.Stopped(device_watcher_stopped_event_token_); + if (device_watcher_) { + device_watcher_.Stop(); + device_watcher_.Added(device_watcher_added_event_token_); + device_watcher_.Updated(device_watcher_updated_event_token_); + device_watcher_.EnumerationCompleted( + device_watcher_enumeration_completed_event_token_); + device_watcher_.Removed(device_watcher_removed_event_token_); + device_watcher_.Stopped(device_watcher_stopped_event_token_); + device_watcher_ = nullptr; + ip_address_local_.clear(); + ip_address_remote_.clear(); + } medium_status_ &= (~kMediumStatusConnecting); medium_status_ &= (~kMediumStatusConnected); - device_watcher_ = nullptr; - service_ = nullptr; - session_ = nullptr; - ip_address_local_.clear(); - ip_address_remote_.clear(); return true; } catch (std::exception exception) { LOG(ERROR) << __func__ << ": Stop WifiDirect GC failed. Exception: " @@ -754,16 +734,200 @@ bool WifiDirectMedium::DisconnectWifiDirect() { LOG(ERROR) << __func__ << ": Stop WifiDirect GC failed. WinRT exception: " << error.code() << ": " << winrt::to_string(error.message()); } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exeption."; + LOG(ERROR) << __func__ << ": Unknown exception."; } return false; } +fire_and_forget WifiDirectMedium::Watcher_DeviceAdded( + DeviceWatcher sender, DeviceInformation device_info) { + LOG(INFO) << "Device found for device ID " + << winrt::to_string(device_info.Id()) + << "; device name: " << winrt::to_string(device_info.Name()); + winrt::hstring device_id = device_info.Id(); + { + absl::MutexLock lock(&mutex_); + if (discovered_devices_by_id_.contains(device_id)) { + return winrt::fire_and_forget(); + } + std::string device_name_to_match = credentials_gc_.GetDeviceName(); + if (!absl::EqualsIgnoreCase(device_name_to_match, + winrt::to_string(device_info.Name()))) { + LOG(INFO) << "We are looking for device: " << device_name_to_match + << ", but found: " << winrt::to_string(device_info.Name()) + << ", skip."; + return winrt::fire_and_forget(); + } + discovered_devices_by_id_[device_id] = + std::make_unique(device_info); + } + LOG(INFO) << "Connect to device name: " + << winrt::to_string(device_info.Name()); + DeviceInformationPairing pairing = device_info.Pairing(); + // WiFiDirectConfigurationMethod config_method = + // WiFiDirectConfigurationMethod::ProvidePin; + WiFiDirectConfigurationMethod config_method = + WiFiDirectConfigurationMethod::PushButton; + bool is_paired; + if (pairing.IsPaired()) { + LOG(INFO) << "GC Paired, unpair it first to clean up stale state"; + DeviceUnpairingResult unpairing_result = pairing.UnpairAsync().get(); + LOG(INFO) << "GC Unpair result: " + << static_cast(unpairing_result.Status()); + if (unpairing_result.Status() == DeviceUnpairingResultStatus::Unpaired || + unpairing_result.Status() == + DeviceUnpairingResultStatus::AlreadyUnpaired) { + // Wait kWaitingForRePair seconds for the device stabilize before + // re-pairing. This may avoid the possible contention problems in Intel + // WiFi driver. + absl::SleepFor(absl::Seconds(kWaitingForRePair)); + DeviceInformation refreshed_device_info = + DeviceInformation::CreateFromIdAsync(device_id).get(); + is_paired = RequestPairDeviceAsync(refreshed_device_info.Pairing(), 1, + config_method); + LOG(INFO) << "GC Re-Paired after unpair: " << is_paired; + } else { + LOG(INFO) << "GC Unpair failed, assume it's still paired."; + is_paired = + true; // Fallback to true if unpair fails, maybe it's still usable. + } + } else { + LOG(INFO) << "GC Not Paired, start to pair"; + is_paired = RequestPairDeviceAsync(device_info.Pairing(), 1, config_method); + } + // Create a WiFiDirectDevice out of this id + if (!is_paired) { + LOG(INFO) << "GC paired failed!"; + absl::MutexLock lock(&mutex_); + if (connection_latch_) { + connection_latch_->CountDown(); + } + return fire_and_forget(); + } + WiFiDirectDevice::FromIdAsync(device_info.Id()) + .Completed( + [this, device_info]( + IAsyncOperation wifidirectDevice, + AsyncStatus status) { + absl::MutexLock lock(mutex_); + WiFiDirectDevice(wifidirectDevice.get()) + .ConnectionStatusChanged( + {this, &WifiDirectMedium::OnConnectionStatusChanged}); + IVectorView endpoint_pairs = + WiFiDirectDevice(wifidirectDevice.get()) + .GetConnectionEndpointPairs(); + if (endpoint_pairs.Size() > 0) { + auto const& pair = endpoint_pairs.GetAt(0); + ip_address_local_ = + winrt::to_string(pair.LocalHostName().DisplayName()); + ip_address_remote_ = + winrt::to_string(pair.RemoteHostName().DisplayName()); + LOG(INFO) << "GC: Local IP: " << ip_address_local_ + << ", Remote IP: " << ip_address_remote_; + medium_status_ |= kMediumStatusConnected; + if (connection_latch_) { + connection_latch_->CountDown(); + } + } else { + LOG(WARNING) << "GC: No connection endpoint pairs found."; + } + }); + return fire_and_forget(); +} + +fire_and_forget WifiDirectMedium::Watcher_DeviceUpdated( + DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { + LOG(INFO) << "device updated for device ID " + << winrt::to_string(deviceInfoUpdate.Id()); + return fire_and_forget(); +} + +fire_and_forget WifiDirectMedium::Watcher_DeviceRemoved( + DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { + LOG(INFO) << "device removed for device ID " + << winrt::to_string(deviceInfoUpdate.Id()); + return fire_and_forget(); +} + +fire_and_forget WifiDirectMedium::Watcher_DeviceEnumerationCompleted( + DeviceWatcher sender, IInspectable inspectable) { + LOG(INFO) << "DeviceWatcher enumeration completed!"; + return fire_and_forget(); +} + +fire_and_forget WifiDirectMedium::Watcher_DeviceStopped( + DeviceWatcher sender, IInspectable inspectable) { + LOG(INFO) << "DeviceWatcher stopped!"; + return fire_and_forget(); +} + +fire_and_forget WifiDirectMedium::OnPairingRequested( + DeviceInformationCustomPairing const& sender, + DevicePairingRequestedEventArgs const& event) { + LOG(INFO) << "Handle Pairing Kind"; + switch (event.PairingKind()) { + case DevicePairingKinds::DisplayPin: + LOG(INFO) << "Display pin is: " << winrt::to_string(event.Pin()); + event.Accept(); + break; + case DevicePairingKinds::ConfirmOnly: + LOG(INFO) << "DevicePairingKinds::ConfirmOnly"; + event.Accept(); + break; + case DevicePairingKinds::ProvidePin: { + absl::MutexLock lock(mutex_); + std::string pin; + LOG(INFO) << "Enter pin:"; + std::cin >> pin; + LOG(INFO) << "DevicePairingKinds::ProvidePin:" << pin; + event.Accept(winrt::to_hstring(pin)); + } break; + default: + LOG(INFO) << "DevicePairingKinds::" + << static_cast(event.PairingKind()); + break; + } + return winrt::fire_and_forget(); +} +void WifiDirectMedium::OnConnectionStatusChanged( + WiFiDirectDevice const& sender, + winrt::Windows::Foundation::IInspectable const&) { + LOG(INFO) << "Connection status: " + << static_cast(sender.ConnectionStatus()); +} +bool WifiDirectMedium::RequestPairDeviceAsync( + DeviceInformationPairing pairing, int group_owner_intent, + WiFiDirectConfigurationMethod config_method) { + LOG(INFO) << __func__ << " Group Intent: " << group_owner_intent; + WiFiDirectConnectionParameters connectionParams; + connectionParams.GroupOwnerIntent(group_owner_intent); + connectionParams.PreferenceOrderedConfigurationMethods().Append( + config_method); + DevicePairingKinds devicePairingKinds = + WiFiDirectConnectionParameters::GetDevicePairingKinds(config_method); + LOG(INFO) << "DevicePairingKinds: " << static_cast(devicePairingKinds); + connectionParams.PreferredPairingProcedure( + WiFiDirectPairingProcedure::Invitation); + DeviceInformationCustomPairing customPairing = pairing.Custom(); + customPairing.PairingRequested({this, &WifiDirectMedium::OnPairingRequested}); + DevicePairingResult result = + customPairing + .PairAsync(devicePairingKinds, DevicePairingProtectionLevel::Default, + connectionParams) + .get(); + if (result.Status() != DevicePairingResultStatus::Paired && + result.Status() != DevicePairingResultStatus::AlreadyPaired) { + LOG(INFO) << "Pair result: " << static_cast(result.Status()); + return false; + } + LOG(INFO) << "Pair success "; + return true; +} + std::vector WifiDirectMedium::GetSupportedWifiDirectAuthTypes() const { - // Windows only supports WifiDirect with Service Discovery, which uses a PIN. + // Windows only supports WifiDirect with Device Name Discovery. return {WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME}; } -} // namespace windows -} // namespace nearby +} // namespace nearby::windows diff --git a/internal/platform/implementation/windows/wifi_direct_server_socket.cc b/internal/platform/implementation/windows/wifi_direct_server_socket.cc index c32b4b5c..c72a5014 100644 --- a/internal/platform/implementation/windows/wifi_direct_server_socket.cc +++ b/internal/platform/implementation/windows/wifi_direct_server_socket.cc @@ -25,6 +25,7 @@ #include "internal/platform/exception.h" #include "internal/platform/feature_flags.h" #include "internal/platform/implementation/wifi_direct.h" +#include "internal/platform/implementation/windows/network_info.h" #include "internal/platform/implementation/windows/socket_address.h" #include "internal/platform/implementation/windows/wifi_direct.h" #include "internal/platform/logging.h" @@ -32,7 +33,7 @@ namespace nearby::windows { namespace { -constexpr int kWaitingForServerSocketReadyTimeoutSeconds = 90; // seconds +constexpr int kWaitingForServerSocketReadyTimeoutSeconds = 60; // seconds } // namespace WifiDirectServerSocket::~WifiDirectServerSocket() { Close(); } @@ -50,27 +51,32 @@ void WifiDirectServerSocket::SetIPAddress(std::string ip_address) { } std::unique_ptr WifiDirectServerSocket::Accept() { - absl::MutexLock lock(mutex_); - if (server_socket_accepted_connection_) { - LOG(INFO) << "Server socket has already accepted a connection. Return."; - return nullptr; - } - if (!is_listen_started_) { - LOG(INFO) << __func__ - << ": Server socket is not started, wait for server socket is " - "ready."; - is_listen_ready_.WaitWithTimeout( - &mutex_, absl::Seconds(kWaitingForServerSocketReadyTimeoutSeconds)); - if (!is_listen_started_) { - LOG(INFO) << __func__ - << ": Server socket failed to start within timeout."; + { + absl::MutexLock lock(&mutex_); + if (closed_) return nullptr; + if (server_socket_accepted_connection_) { + LOG(INFO) << "Server socket has already accepted a connection. Return."; return nullptr; } + LOG(INFO) << "Check if server socket is ready."; + if (!is_listen_started_) { + LOG(INFO) <<"Server socket is not started, wait for server socket is " + "ready."; + is_listen_ready_.WaitWithTimeout( + &mutex_, absl::Seconds(kWaitingForServerSocketReadyTimeoutSeconds)); + if (closed_ || !is_listen_started_) { + LOG(INFO) << ": Server socket failed to start or was closed."; + return nullptr; + } + } } + LOG(INFO) << "Start to accept connection from WiFiDirect client."; auto client_socket = server_socket_.Accept(); - if (client_socket == nullptr) { - LOG(INFO) << "Accept server socket failed."; + + absl::MutexLock lock(&mutex_); + if (closed_ || client_socket == nullptr) { + LOG(INFO) << "Accept server socket failed or closed."; return nullptr; } @@ -80,9 +86,45 @@ std::unique_ptr WifiDirectServerSocket::Accept() { return std::make_unique(std::move(client_socket)); } +std::string GetWifiDirectGOAddresses() { + for (int i = 0; i < 3; i++) { + // Force refresh network info since assignment of the well known + // static IP address to the hotspot interface does not trigger the IP + // interface change notification in network_monitor.cc. + NetworkInfo::GetNetworkInfo().Refresh(); + for (const auto& net_interface : + NetworkInfo::GetNetworkInfo().GetInterfaces()) { + if (net_interface.type == InterfaceType::kWifiHotspot) { + LOG(INFO) << "Found Wifi Hotspot interface, index: " + << net_interface.index; + for (const SocketAddress& ipaddress : net_interface.ipv6_addresses) { + LOG(INFO) << "Found ipv6 address: " << ipaddress.ToString(); + // IPv6 link-local addresses are allowed and preferred since it skips + // the DHCP wait time. + } + for (const SocketAddress& ipaddress : net_interface.ipv4_addresses) { + LOG(INFO) << "Found ipv4 address: " << ipaddress.ToString(); + // Skip link-local IPv4 addresses. + if (ipaddress.IsV4LinkLocal()) { + LOG(INFO) << "Skip link-local IPv4 address: "; + continue; + } + + return ipaddress.ToString(); + } + } + } + LOG(WARNING) + << "Failed to find Wifi Hotspot interface. Wait 500ms snd try again"; + Sleep(500); + } + return ""; +} + void WifiDirectServerSocket::PopulateWifiDirectCredentials( WifiDirectCredentials& wifi_direct_credentials) { - wifi_direct_credentials.SetGateway(wifi_direct_ipaddr_); + std::string wifi_direct_ipaddr = GetWifiDirectGOAddresses(); + wifi_direct_credentials.SetGateway(wifi_direct_ipaddr); if (GetPort() != 0) { wifi_direct_credentials.SetPort(GetPort()); } else { @@ -93,15 +135,19 @@ void WifiDirectServerSocket::PopulateWifiDirectCredentials( } Exception WifiDirectServerSocket::Close() { - absl::MutexLock lock(mutex_); - if (closed_) { - return {Exception::kSuccess}; + { + absl::MutexLock lock(mutex_); + if (closed_) { + return {Exception::kSuccess}; + } + closed_ = true; + wifi_direct_ipaddr_.clear(); + is_listen_started_ = false; + server_socket_accepted_connection_ = false; + is_listen_ready_.SignalAll(); } - wifi_direct_ipaddr_.clear(); - is_listen_started_ = false; - server_socket_accepted_connection_ = false; + server_socket_.Close(); - closed_ = true; LOG(INFO) << __func__ << ": Close completed succesfully."; return {Exception::kSuccess}; From 396a12c580976156d44e89bae92e68ee2dffabf3 Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 12 Jun 2026 15:28:59 -0700 Subject: [PATCH 151/151] Refine Wifi Direct comments and use a constant for GO start delay. PiperOrigin-RevId: 931363915 --- .../offline_frames_validator.cc | 9 ++++-- .../implementation/windows/wifi_direct.h | 2 +- .../windows/wifi_direct_medium.cc | 28 ++++++++++--------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/connections/implementation/offline_frames_validator.cc b/connections/implementation/offline_frames_validator.cc index d388d6eb..c42cd4a3 100644 --- a/connections/implementation/offline_frames_validator.cc +++ b/connections/implementation/offline_frames_validator.cc @@ -61,8 +61,13 @@ constexpr absl::string_view kWifiDirectSsidPatternString{ constexpr int kWifiDirectSsidMaxLength = 32; constexpr int kWifiPasswordSsidMinLength = 8; constexpr int kWifiPasswordSsidMaxLength = 64; -// We may use Push Button for WPS, so no pin is required, the min length should -// be 0. +// For Windows Wifi Direct based on WinRT Windows.Devices.WiFiDirect, user can't +// choose pin when pairing with the other device. Instead, When GO is created, a +// pin is created by OS. But at this stage, BWU has already sent device name as +// credential to GC for connection. Current BWU design has no way to send second +// ForBwuWifiDirectPathAvailable frame with pin as crdential to GC. To avoid +// major change in BWU structure, we decided to use ConfirmOnly(Push Button) for +// WPS, so no pin is required, the min length should be 0. constexpr int kWifiDirectPinMinLength = 0; constexpr int kWifiDirectPinMaxLength = 16; diff --git a/internal/platform/implementation/windows/wifi_direct.h b/internal/platform/implementation/windows/wifi_direct.h index 399b3f5d..982fa6ba 100644 --- a/internal/platform/implementation/windows/wifi_direct.h +++ b/internal/platform/implementation/windows/wifi_direct.h @@ -274,7 +274,7 @@ class WifiDirectMedium : public api::WifiDirectMedium { bool IsIdle() { return medium_status_ == kMediumStatusIdle; } // Advertiser is accepting connection on server socket bool IsAccepting() { return (medium_status_ & kMediumStatusAccepting) != 0; } - // GO is starated and sending beacon + // GO is started and sending beacon bool IsBeaconing() { return (medium_status_ & kMediumStatusBeaconing) != 0; } // GC is connecting to the GO bool IsConnecting() { diff --git a/internal/platform/implementation/windows/wifi_direct_medium.cc b/internal/platform/implementation/windows/wifi_direct_medium.cc index dac7d1a5..7adc12eb 100644 --- a/internal/platform/implementation/windows/wifi_direct_medium.cc +++ b/internal/platform/implementation/windows/wifi_direct_medium.cc @@ -44,8 +44,10 @@ namespace nearby::windows { namespace { -constexpr int kWaitingForConnectionTimeoutSeconds = 60; // seconds -constexpr int kWaitingForRePair = 3; // seconds +constexpr absl::Duration kServiceConnectionTimeout = absl::Seconds(60); +constexpr absl::Duration kWaitingForRePair = absl::Seconds(3); +constexpr absl::Duration kWaitForGOServerStart = absl::Milliseconds(500); +constexpr absl::Duration kConnectTimeout = absl::Seconds(30); } // namespace WifiDirectDeviceDiscovered::WifiDirectDeviceDiscovered( @@ -135,7 +137,7 @@ std::unique_ptr WifiDirectMedium::ConnectToService( LOG(INFO) << "Connect to service "; // In the test, GO server takes longer to started, so wait for 500ms before // trying to connect to the service. - absl::SleepFor(absl::Milliseconds(500)); + absl::SleepFor(kWaitForGOServerStart); for (int i = 0; i < wifi_direct_max_connection_retries; ++i) { auto wifi_direct_socket = std::make_unique(); @@ -200,8 +202,8 @@ std::unique_ptr WifiDirectMedium::ListenForService( if (ip_address_local_.empty()) { if (server_socket_ptr_) { LOG(INFO) << "Waiting for IP address is ready."; - is_ip_address_ready_.WaitWithTimeout( - &mutex_, absl::Seconds(kWaitingForConnectionTimeoutSeconds)); + is_ip_address_ready_.WaitWithTimeout(&mutex_, + kServiceConnectionTimeout); if (!server_socket_ptr_) { LOG(WARNING) << "Server socket was closed before IP address is ready."; @@ -459,8 +461,8 @@ fire_and_forget WifiDirectMedium::OnConnectionRequested( unpairing_result.Status() == DeviceUnpairingResultStatus::AlreadyUnpaired) { LOG(INFO) << "GO Unpaired GC, Re-pair"; - // Wait for kWaitingForRePair seconds to allow WiFi driver to stabilize. - absl::SleepFor(absl::Seconds(kWaitingForRePair)); + // Wait for kWaitingForRePair to allow WiFi driver to stabilize. + absl::SleepFor(kWaitingForRePair); // Refresh device info after unpairing. DeviceInformation refreshed_device_info = DeviceInformation::CreateFromIdAsync(device_id).get(); @@ -642,8 +644,9 @@ bool WifiDirectMedium::ConnectWifiDirect( } } - LOG(INFO) << "Started to discover and wait 30s for connection."; - connection_latch_->Await(absl::Seconds(30)); + LOG(INFO) << "Started to discover and wait " << kConnectTimeout + << " for connection."; + connection_latch_->Await(kConnectTimeout); { absl::MutexLock lock(mutex_); if (IsConnected()) { @@ -777,10 +780,9 @@ fire_and_forget WifiDirectMedium::Watcher_DeviceAdded( if (unpairing_result.Status() == DeviceUnpairingResultStatus::Unpaired || unpairing_result.Status() == DeviceUnpairingResultStatus::AlreadyUnpaired) { - // Wait kWaitingForRePair seconds for the device stabilize before - // re-pairing. This may avoid the possible contention problems in Intel - // WiFi driver. - absl::SleepFor(absl::Seconds(kWaitingForRePair)); + // Wait kWaitingForRePair for the device stabilize before re-pairing. + // This may avoid the possible contention problems in Intel WiFi driver. + absl::SleepFor(kWaitingForRePair); DeviceInformation refreshed_device_info = DeviceInformation::CreateFromIdAsync(device_id).get(); is_paired = RequestPairDeviceAsync(refreshed_device_info.Pairing(), 1,