From 335b3a8d45ebe52eed22613b01f64e6fca397141 Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 22 Jan 2021 12:13:44 -0800 Subject: [PATCH] Roll forward up to cl/353292511. --- cpp/core/internal/BUILD | 2 + cpp/core/internal/base_pcp_handler.cc | 113 ++++++++++-------- cpp/core/internal/base_pcp_handler.h | 31 +++-- cpp/core/internal/base_pcp_handler_test.cc | 51 ++++---- cpp/core/internal/bluetooth_bwu_handler.cc | 3 +- cpp/core/internal/bwu_manager.cc | 8 -- cpp/core/internal/client_proxy.cc | 62 +++++++++- cpp/core/internal/client_proxy.h | 43 ++++++- cpp/core/internal/client_proxy_test.cc | 76 +++++++++++- cpp/core/internal/endpoint_manager.cc | 2 - cpp/core/internal/fuzzers/BUILD | 12 ++ .../internal/fuzzers/offline_frames_fuzzer.cc | 11 ++ cpp/core/internal/mediums/BUILD | 1 + cpp/core/internal/mediums/ble.cc | 5 +- cpp/core/internal/mediums/ble.h | 4 +- cpp/core/internal/mediums/ble_test.cc | 6 +- .../internal/mediums/bluetooth_classic.cc | 4 +- cpp/core/internal/mediums/bluetooth_classic.h | 4 +- .../mediums/bluetooth_classic_test.cc | 3 +- cpp/core/internal/mediums/webrtc.cc | 3 +- cpp/core/internal/mediums/webrtc.h | 4 +- cpp/core/internal/mediums/webrtc_test.cc | 27 +++-- cpp/core/internal/mediums/wifi_lan.cc | 4 +- cpp/core/internal/mediums/wifi_lan.h | 4 +- cpp/core/internal/mediums/wifi_lan_test.cc | 5 +- cpp/core/internal/p2p_cluster_pcp_handler.cc | 98 +++++++++++++-- cpp/core/internal/p2p_cluster_pcp_handler.h | 3 + .../internal/service_controller_router.cc | 26 +++- cpp/core/internal/webrtc_bwu_handler.cc | 3 +- cpp/core/internal/wifi_lan_bwu_handler.cc | 4 +- cpp/platform/base/BUILD | 33 +++++ cpp/platform/base/cancellation_flag.cc | 32 +++++ cpp/platform/base/cancellation_flag.h | 37 ++++++ cpp/platform/base/cancellation_flag_test.cc | 20 ++++ cpp/platform/impl/g3/webrtc.h | 2 +- cpp/platform/public/BUILD | 1 - 36 files changed, 592 insertions(+), 155 deletions(-) create mode 100644 cpp/core/internal/fuzzers/BUILD create mode 100644 cpp/core/internal/fuzzers/offline_frames_fuzzer.cc create mode 100644 cpp/platform/base/cancellation_flag.cc create mode 100644 cpp/platform/base/cancellation_flag.h create mode 100644 cpp/platform/base/cancellation_flag_test.cc diff --git a/cpp/core/internal/BUILD b/cpp/core/internal/BUILD index c474a456..f6829072 100644 --- a/cpp/core/internal/BUILD +++ b/cpp/core/internal/BUILD @@ -70,6 +70,7 @@ cc_library( ], visibility = [ "//core:__pkg__", + "//core/internal/fuzzers:__pkg__", ], deps = [ ":message_lite", @@ -80,6 +81,7 @@ cc_library( "//proto/connections:offline_wire_formats_portable_proto", "//platform/api:comm", "//platform/base", + "//platform/base:cancellation_flag", "//platform/base:util", "//platform/public:comm", "//platform/public:logging", diff --git a/cpp/core/internal/base_pcp_handler.cc b/cpp/core/internal/base_pcp_handler.cc index 6568a91c..4115eaa2 100644 --- a/cpp/core/internal/base_pcp_handler.cc +++ b/cpp/core/internal/base_pcp_handler.cc @@ -81,14 +81,12 @@ Status BasePcpHandler::StartAdvertising(ClientProxy* client, // Now that we've succeeded, mark the client as advertising. // Save the advertising options for local reference in later process like // upgrading bandwidth. - // TODO(hais): saving advertising_options_ in clientProxy instead of here - // as java implementation does. std::vector supported_mediums = advertising_options.GetMediums(); - advertising_options_ = advertising_options; advertising_listener_ = info.listener; client->StartedAdvertising(service_id, GetStrategy(), info.listener, - absl::MakeSpan(result.mediums)); + absl::MakeSpan(result.mediums), + advertising_options); response.Set({Status::kSuccess}); }); return WaitForResult( @@ -101,7 +99,6 @@ void BasePcpHandler::StopAdvertising(ClientProxy* client) { RunOnPcpHandlerThread([this, client, &latch]() { StopAdvertisingImpl(client); client->StoppedAdvertising(); - // advertising_options_ is purposefully not cleared here. latch.CountDown(); }); WaitForLatch("StopAdvertising", &latch); @@ -128,23 +125,22 @@ Status BasePcpHandler::StartDiscovery(ClientProxy* client, NEARBY_LOG(INFO, "StartDiscovery with supported mediums: %s", GetStringValueOfSupportedMediums(options).c_str()); - RunOnPcpHandlerThread( - [this, client, service_id, discovery_options, &listener, &response]() { - // Ask the implementation to attempt to start discovery. - auto result = StartDiscoveryImpl(client, service_id, discovery_options); - if (!result.status.Ok()) { - response.Set(result.status); - return; - } + RunOnPcpHandlerThread([this, client, service_id, discovery_options, &listener, + &response]() { + // Ask the implementation to attempt to start discovery. + auto result = StartDiscoveryImpl(client, service_id, discovery_options); + if (!result.status.Ok()) { + response.Set(result.status); + return; + } - // Now that we've succeeded, mark the client as discovering and clear - // out any old endpoints we had discovered. - discovery_options_ = discovery_options; - discovered_endpoints_.clear(); - client->StartedDiscovery(service_id, GetStrategy(), listener, - absl::MakeSpan(result.mediums)); - response.Set({Status::kSuccess}); - }); + // Now that we've succeeded, mark the client as discovering and clear + // out any old endpoints we had discovered. + discovered_endpoints_.clear(); + client->StartedDiscovery(service_id, GetStrategy(), listener, + absl::MakeSpan(result.mediums), discovery_options); + response.Set({Status::kSuccess}); + }); return WaitForResult(absl::StrCat("StartDiscovery(", service_id, ")"), client->GetClientId(), &response); } @@ -154,7 +150,6 @@ void BasePcpHandler::StopDiscovery(ClientProxy* client) { RunOnPcpHandlerThread([this, client, &latch]() { StopDiscoveryImpl(client); client->StoppedDiscovery(); - // discovery_options_ is purposefully not cleared here. latch.CountDown(); }); @@ -332,7 +327,7 @@ Status BasePcpHandler::RequestConnection(ClientProxy* client, // If our child class says we can't send any more outgoing connections, // listen to them. - if (ShouldEnforceTopologyConstraints() && + if (ShouldEnforceTopologyConstraints(client->GetAdvertisingOptions()) && !CanSendOutgoingConnection(client)) { NEARBY_LOG(INFO, "Outgoing connection not allowed: id=%s", endpoint_id.c_str()); @@ -351,13 +346,14 @@ Status BasePcpHandler::RequestConnection(ClientProxy* client, auto remote_bluetooth_mac_address = BluetoothUtils::ToString(options.remote_bluetooth_mac_address); if (!remote_bluetooth_mac_address.empty()) { - if (AppendRemoteBluetoothMacAddressEndpoint(endpoint_id, - remote_bluetooth_mac_address)) + if (AppendRemoteBluetoothMacAddressEndpoint( + endpoint_id, remote_bluetooth_mac_address, + client->GetDiscoveryOptions())) NEARBY_LOGS(INFO) << "Appended remote Bluetooth MAC Address endpoint " << "[" << remote_bluetooth_mac_address << "]"; } - if (AppendWebRTCEndpoint(endpoint_id)) + if (AppendWebRTCEndpoint(endpoint_id, client->GetDiscoveryOptions())) NEARBY_LOGS(INFO) << "Appended Web RTC endpoint."; auto discovered_endpoints = GetDiscoveredEndpoints(endpoint_id); @@ -366,7 +362,7 @@ Status BasePcpHandler::RequestConnection(ClientProxy* client, for (auto connect_endpoint : discovered_endpoints) { if (!MediumSupportedByClientOptions(connect_endpoint->medium, - discovery_options_)) + client->GetDiscoveryOptions())) continue; connect_impl_result = ConnectImpl(client, connect_endpoint); if (connect_impl_result.status.Ok()) { @@ -391,7 +387,7 @@ Status BasePcpHandler::RequestConnection(ClientProxy* client, // endpoint about ourselves. Exception write_exception = WriteConnectionRequestFrame( channel.get(), client->GetLocalEndpointId(), info.endpoint_info, nonce, - GetSupportedConnectionMediumsByPriority(discovery_options_)); + GetSupportedConnectionMediumsByPriority(client->GetDiscoveryOptions())); if (!write_exception.Ok()) { NEARBY_LOG(INFO, "Failed to send connection request: id=%s", endpoint_id.c_str()); @@ -453,7 +449,7 @@ bool BasePcpHandler::MediumSupportedByClientOptions( } // Get ordered supported connection medium based on local advertising/discovery -// option. local_option is either advertising_options_ or discovery_options_. +// option. std::vector BasePcpHandler::GetSupportedConnectionMediumsByPriority( const ConnectionOptions& local_option) { @@ -487,6 +483,19 @@ BasePcpHandler::GetDiscoveredEndpoints(const std::string& endpoint_id) { [this](DiscoveredEndpoint* a, DiscoveredEndpoint* b) -> bool { return IsPreferred(*a, *b); }); + + return result; +} + +std::vector +BasePcpHandler::GetDiscoveredEndpoints( + const proto::connections::Medium medium) { + std::vector result; + for (const auto& item : discovered_endpoints_) { + if (item.second->medium == medium) { + result.push_back(item.second.get()); + } + } return result; } @@ -555,22 +564,24 @@ void BasePcpHandler::ProcessPreConnectionResultFailure( client->OnConnectionRejected(endpoint_id, {Status::kError}); } -bool BasePcpHandler::ShouldEnforceTopologyConstraints() const { +bool BasePcpHandler::ShouldEnforceTopologyConstraints( + const ConnectionOptions& local_advertising_options) const { // Topology constraints only matter for the advertiser. // For discoverers, we'll always enforce them. - if (advertising_options_.strategy.IsNone()) { + if (local_advertising_options.strategy.IsNone()) { return true; } - return advertising_options_.enforce_topology_constraints; + return local_advertising_options.enforce_topology_constraints; } -bool BasePcpHandler::AutoUpgradeBandwidth() const { - if (advertising_options_.strategy.IsNone()) { +bool BasePcpHandler::AutoUpgradeBandwidth( + const ConnectionOptions& local_advertising_options) const { + if (local_advertising_options.strategy.IsNone()) { return true; } - return advertising_options_.auto_upgrade_bandwidth; + return local_advertising_options.auto_upgrade_bandwidth; } Status BasePcpHandler::AcceptConnection( @@ -751,14 +762,6 @@ BluetoothDevice BasePcpHandler::GetRemoteBluetoothDevice( remote_bluetooth_mac_address); } -ConnectionOptions BasePcpHandler::GetConnectionOptions() const { - return advertising_options_; -} - -ConnectionOptions BasePcpHandler::GetDiscoveryOptions() const { - return discovery_options_; -} - void BasePcpHandler::OnEndpointFound( ClientProxy* client, std::shared_ptr endpoint) { // Check if we've seen this endpoint ID before. @@ -919,7 +922,7 @@ Exception BasePcpHandler::OnIncomingConnection( // If our child class says we can't accept any more incoming connections, // listen to them. - if (ShouldEnforceTopologyConstraints() && + if (ShouldEnforceTopologyConstraints(client->GetAdvertisingOptions()) && !CanReceiveIncomingConnection(client)) { return {Exception::kIo}; } @@ -1015,15 +1018,18 @@ void BasePcpHandler::InitiateBandwidthUpgrade( // sense to dynamically select the proper medium for upgrading. // TODO(hais): when we add more mediums like Wifi Hotspot, we need to prevent // upgrading interfering with active connections. - Medium bwu_medium = ChooseBestUpgradeMedium(their_supported_mediums); + Medium bwu_medium = ChooseBestUpgradeMedium(their_supported_mediums, + client->GetAdvertisingOptions()); - if (AutoUpgradeBandwidth() && bwu_medium != Medium::UNKNOWN_MEDIUM) { + if (AutoUpgradeBandwidth(client->GetAdvertisingOptions()) && + bwu_medium != Medium::UNKNOWN_MEDIUM) { bwu_manager_->InitiateBwuForEndpoint(client, endpoint_id, bwu_medium); } } proto::connections::Medium BasePcpHandler::ChooseBestUpgradeMedium( - const std::vector& their_supported_mediums) { + const std::vector& their_supported_mediums, + const ConnectionOptions& local_advertising_options) { // If the remote side did not report their supported mediums, choose an // appropriate default. std::vector their_mediums = @@ -1034,7 +1040,7 @@ proto::connections::Medium BasePcpHandler::ChooseBestUpgradeMedium( // Otherwise, pick the best medium we support. std::vector my_mediums = - GetSupportedConnectionMediumsByPriority(advertising_options_); + GetSupportedConnectionMediumsByPriority(local_advertising_options); for (const auto& my_medium : my_mediums) { for (const auto& their_medium : their_mediums) { if (my_medium == their_medium) { @@ -1048,8 +1054,9 @@ proto::connections::Medium BasePcpHandler::ChooseBestUpgradeMedium( bool BasePcpHandler::AppendRemoteBluetoothMacAddressEndpoint( const std::string& endpoint_id, - const std::string& remote_bluetooth_mac_address) { - if (!discovery_options_.allowed.bluetooth) { + const std::string& remote_bluetooth_mac_address, + const ConnectionOptions& local_discovery_options) { + if (!local_discovery_options.allowed.bluetooth) { return false; } @@ -1089,8 +1096,10 @@ bool BasePcpHandler::AppendRemoteBluetoothMacAddressEndpoint( return true; } -bool BasePcpHandler::AppendWebRTCEndpoint(const std::string& endpoint_id) { - if (!discovery_options_.allowed.web_rtc) { +bool BasePcpHandler::AppendWebRTCEndpoint( + const std::string& endpoint_id, + const ConnectionOptions& local_discovery_options) { + if (!local_discovery_options.allowed.web_rtc) { return false; } diff --git a/cpp/core/internal/base_pcp_handler.h b/cpp/core/internal/base_pcp_handler.h index abfc3f4c..313b9cd5 100644 --- a/cpp/core/internal/base_pcp_handler.h +++ b/cpp/core/internal/base_pcp_handler.h @@ -297,6 +297,10 @@ class BasePcpHandler : public PcpHandler, std::vector GetDiscoveredEndpoints( const std::string& endpoint_id); + // Returns a vector of discovered endpoints that share a given Medium. + std::vector GetDiscoveredEndpoints( + const proto::connections::Medium medium); + mediums::PeerId CreatePeerIdFromAdvertisement(const string& service_id, const string& endpoint_id, const ByteArray& endpoint_info); @@ -393,11 +397,13 @@ class BasePcpHandler : public PcpHandler, const BasePcpHandler::DiscoveredEndpoint& old_endpoint); // Returns true, if connection party should respect the specified topology. - bool ShouldEnforceTopologyConstraints() const; + bool ShouldEnforceTopologyConstraints( + const ConnectionOptions& local_advertising_options) const; // Returns true, if connection party should attempt to upgrade itself to // use a higher bandwidth medium, if it is available. - bool AutoUpgradeBandwidth() const; + bool AutoUpgradeBandwidth( + const ConnectionOptions& local_advertising_options) const; // Returns true if the incoming connection should be killed. This only // happens when an incoming connection arrives while we have an outgoing @@ -424,18 +430,21 @@ class BasePcpHandler : public PcpHandler, // Returns the optimal medium supported by both devices. proto::connections::Medium ChooseBestUpgradeMedium( - const std::vector& supported_mediums); + const std::vector& supported_mediums, + const ConnectionOptions& local_advertising_options); // Returns true if the bluetooth endpoint based on remote bluetooth mac // address is created and appended into discovered_endpoints_ with key // endpoint_id. bool AppendRemoteBluetoothMacAddressEndpoint( const std::string& endpoint_id, - const std::string& remote_bluetooth_mac_address); + const std::string& remote_bluetooth_mac_address, + const ConnectionOptions& local_discovery_options); // Returns true if the webrtc endpoint is created and appended into // discovered_endpoints_ with key endpoint_id. - bool AppendWebRTCEndpoint(const std::string& endpoint_id); + bool AppendWebRTCEndpoint(const std::string& endpoint_id, + const ConnectionOptions& local_discovery_options); void ProcessPreConnectionInitiationFailure(const std::string& endpoint_id, EndpointChannel* channel, @@ -492,22 +501,10 @@ class BasePcpHandler : public PcpHandler, // doesn't happen. absl::flat_hash_map pending_alarms_; - // The active ClientProxy's advertising constraints. Empty() - // returns true if the client hasn't started advertising false otherwise. - // Note: this is not cleared when the client stops advertising because it - // might still be useful downstream of advertising (eg: establishing - // connections, performing bandwidth upgrades, etc.) - ConnectionOptions advertising_options_; // The active ClientProxy's connection lifecycle listener. Non-null while // advertising. ConnectionListener advertising_listener_; - // The active ClientProxy's discovery constraints. Null if the client - // hasn't started discovering. Note: this is not cleared when the client - // stops discovering because it might still be useful downstream of - // discovery (eg: connection speed, etc.) - ConnectionOptions discovery_options_; - AtomicBoolean stop_{false}; Pcp pcp_; Strategy strategy_{PcpToStrategy(pcp_)}; diff --git a/cpp/core/internal/base_pcp_handler_test.cc b/cpp/core/internal/base_pcp_handler_test.cc index 5e0a879f..2a9dffbf 100644 --- a/cpp/core/internal/base_pcp_handler_test.cc +++ b/cpp/core/internal/base_pcp_handler_test.cc @@ -116,7 +116,8 @@ class MockPcpHandler : public BasePcpHandler { MOCK_METHOD(Status, StopDiscoveryImpl, (ClientProxy * client), (override)); MOCK_METHOD(Status, InjectEndpointImpl, (ClientProxy * client, const std::string& service_id, - const OutOfBandConnectionMetadata& metadata), (override)); + const OutOfBandConnectionMetadata& metadata), + (override)); MOCK_METHOD(ConnectImplResult, ConnectImpl, (ClientProxy * client, DiscoveredEndpoint* endpoint), (override)); MOCK_METHOD(proto::connections::Medium, GetDefaultUpgradeMedium, (), @@ -124,7 +125,9 @@ class MockPcpHandler : public BasePcpHandler { std::vector GetConnectionMediumsByPriority() override { - return GetDiscoveryMediums(); + return std::vector{ + proto::connections::WIFI_LAN, proto::connections::WEB_RTC, + proto::connections::BLUETOOTH, proto::connections::BLE}; } // Mock adapters for protected non-virtual methods of a base class. @@ -140,9 +143,9 @@ class MockPcpHandler : public BasePcpHandler { return BasePcpHandler::GetDiscoveredEndpoints(endpoint_id); } - std::vector GetDiscoveryMediums() { - auto allowed = - BasePcpHandler::GetDiscoveryOptions().CompatibleOptions().allowed; + std::vector GetDiscoveryMediums( + ClientProxy* client) { + auto allowed = client->GetDiscoveryOptions().CompatibleOptions().allowed; return GetMediumsFromSelector(allowed); } @@ -308,7 +311,7 @@ class BasePcpHandlerTest EXPECT_CALL(mock_connection_listener_.initiated_cb, Call).Times(1); // Simulate successful discovery. auto encryption_runner = std::make_unique(); - auto allowed_mediums = pcp_handler->GetDiscoveryMediums(); + auto allowed_mediums = pcp_handler->GetDiscoveryMediums(client); EXPECT_CALL(*pcp_handler, ConnectImpl) .WillOnce(Invoke([&channel_a, connect_medium]( @@ -443,7 +446,7 @@ TEST_P(BasePcpHandlerTest, RequestConnectionChangesState) { BwuManager bwu(m, em, ecm, {}, {}); MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); - auto mediums = pcp_handler.GetDiscoveryMediums(); + auto mediums = pcp_handler.GetDiscoveryMediums(&client); auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium); auto& channel_a = channel_pair.first; @@ -468,7 +471,7 @@ TEST_P(BasePcpHandlerTest, AcceptConnectionChangesState) { BwuManager bwu(m, em, ecm, {}, {}); MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); - auto mediums = pcp_handler.GetDiscoveryMediums(); + auto mediums = pcp_handler.GetDiscoveryMediums(&client); auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium); auto& channel_a = channel_pair.first; @@ -497,7 +500,7 @@ TEST_P(BasePcpHandlerTest, RejectConnectionChangesState) { BwuManager bwu(m, em, ecm, {}, {}); MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); - auto mediums = pcp_handler.GetDiscoveryMediums(); + auto mediums = pcp_handler.GetDiscoveryMediums(&client); auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium); auto& channel_b = channel_pair.second; @@ -522,7 +525,7 @@ TEST_P(BasePcpHandlerTest, OnIncomingFrameChangesState) { BwuManager bwu(m, em, ecm, {}, {}); MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); - auto mediums = pcp_handler.GetDiscoveryMediums(); + auto mediums = pcp_handler.GetDiscoveryMediums(&client); auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium); auto& channel_a = channel_pair.first; @@ -560,7 +563,7 @@ TEST_P(BasePcpHandlerTest, DestructorIsCalledOnProtocolEndpoint) { BwuManager bwu(m, em, ecm, {}, {}); MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); - auto mediums = pcp_handler.GetDiscoveryMediums(); + auto mediums = pcp_handler.GetDiscoveryMediums(&client); auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium); auto& channel_a = channel_pair.first; @@ -601,7 +604,7 @@ TEST_P(BasePcpHandlerTest, MultipleMediumsProduceSingleEndpointLostEvent) { BwuManager bwu(m, em, ecm, {}, {}); MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); - auto mediums = pcp_handler.GetDiscoveryMediums(); + auto mediums = pcp_handler.GetDiscoveryMediums(&client); auto connect_medium = mediums[mediums.size() - 1]; auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium); auto& channel_a = channel_pair.first; @@ -611,7 +614,7 @@ TEST_P(BasePcpHandlerTest, MultipleMediumsProduceSingleEndpointLostEvent) { EXPECT_CALL(mock_discovery_listener_.endpoint_lost_cb, Call).Times(1); RequestConnection(endpoint_id, std::move(channel_a), channel_b.get(), &client, &pcp_handler, connect_medium, &destroyed_flag); - auto allowed_mediums = pcp_handler.GetDiscoveryMediums(); + auto allowed_mediums = pcp_handler.GetDiscoveryMediums(&client); mediums_count = allowed_mediums.size(); NEARBY_LOG(INFO, "Attempting to accept connection: id=%s", endpoint_id.c_str()); @@ -642,9 +645,11 @@ TEST_F(BasePcpHandlerTest, InjectEndpoint) { EndpointManager em(&ecm); BwuManager bwu(m, em, ecm, {}, {}); MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); - BooleanMediumSelector allowed{ .bluetooth = true, }; + BooleanMediumSelector allowed{ + .bluetooth = true, + }; ConnectionOptions options{ - .allowed = allowed, + .allowed = allowed, .is_out_of_band_connection = true, }; EXPECT_CALL(mock_discovery_listener_.endpoint_found_cb, Call); @@ -660,9 +665,8 @@ TEST_F(BasePcpHandlerTest, InjectEndpoint) { EXPECT_CALL(pcp_handler, InjectEndpointImpl(&client, service_id, _)) .WillOnce(Invoke([&pcp_handler, &endpoint_id]( - ClientProxy* client, - const std::string& service_id, - const OutOfBandConnectionMetadata& metadata) { + ClientProxy* client, const std::string& service_id, + const OutOfBandConnectionMetadata& metadata) { pcp_handler.OnEndpointFound( client, std::make_shared(MockDiscoveredEndpoint{ @@ -677,11 +681,12 @@ TEST_F(BasePcpHandlerTest, InjectEndpoint) { })); return Status{Status::kSuccess}; })); - pcp_handler.InjectEndpoint(&client, service_id, - OutOfBandConnectionMetadata{ - .medium = Medium::BLUETOOTH, - .remote_bluetooth_mac_address = ByteArray(kFakeMacAddress), - }); + pcp_handler.InjectEndpoint( + &client, service_id, + OutOfBandConnectionMetadata{ + .medium = Medium::BLUETOOTH, + .remote_bluetooth_mac_address = ByteArray(kFakeMacAddress), + }); bwu.Shutdown(); } diff --git a/cpp/core/internal/bluetooth_bwu_handler.cc b/cpp/core/internal/bluetooth_bwu_handler.cc index 57b03311..228e12d0 100644 --- a/cpp/core/internal/bluetooth_bwu_handler.cc +++ b/cpp/core/internal/bluetooth_bwu_handler.cc @@ -96,7 +96,8 @@ BluetoothBwuHandler::CreateUpgradedEndpointChannel( return nullptr; } - BluetoothSocket socket = bluetooth_medium_.Connect(device, service_name); + BluetoothSocket socket = bluetooth_medium_.Connect( + device, service_name, client->GetCancellationFlag(endpoint_id)); if (!socket.IsValid()) { return nullptr; } diff --git a/cpp/core/internal/bwu_manager.cc b/cpp/core/internal/bwu_manager.cc index cb32eadb..3582d78f 100644 --- a/cpp/core/internal/bwu_manager.cc +++ b/cpp/core/internal/bwu_manager.cc @@ -18,7 +18,6 @@ namespace location { namespace nearby { namespace connections { -using ::location::nearby::proto::connections::ConnectionAttemptResult; using ::location::nearby::proto::connections::DisconnectionReason; // Required for C++ 14 support in Chrome @@ -377,13 +376,6 @@ void BwuManager::ProcessBwuPathAvailableEvent( auto channel = ProcessBwuPathAvailableEventInternal(client, endpoint_id, upgrade_path_info); - ConnectionAttemptResult connectionAttemptResult; - if (channel != nullptr) { - connectionAttemptResult = ConnectionAttemptResult::RESULT_SUCCESS; - } else { - connectionAttemptResult = ConnectionAttemptResult::RESULT_ERROR; - } - if (channel == nullptr) { RunUpgradeFailedProtocol(client, endpoint_id, upgrade_path_info); return; diff --git a/cpp/core/internal/client_proxy.cc b/cpp/core/internal/client_proxy.cc index 0ab6a155..4aa828f0 100644 --- a/cpp/core/internal/client_proxy.cc +++ b/cpp/core/internal/client_proxy.cc @@ -54,9 +54,11 @@ void ClientProxy::Reset() { void ClientProxy::StartedAdvertising( const std::string& service_id, Strategy strategy, const ConnectionListener& listener, - absl::Span mediums) { + absl::Span mediums, + const ConnectionOptions& advertising_options) { MutexLock lock(&mutex_); advertising_info_ = {service_id, listener}; + advertising_options_ = advertising_options; } void ClientProxy::StoppedAdvertising() { @@ -65,6 +67,7 @@ void ClientProxy::StoppedAdvertising() { if (IsAdvertising()) { advertising_info_.Clear(); } + // advertising_options_ is purposefully not cleared here. ResetLocalEndpointIdIfNeeded(); } @@ -89,9 +92,11 @@ std::string ClientProxy::GetServiceId() const { void ClientProxy::StartedDiscovery( const std::string& service_id, Strategy strategy, const DiscoveryListener& listener, - absl::Span mediums) { + absl::Span mediums, + const ConnectionOptions& discovery_options) { MutexLock lock(&mutex_); discovery_info_ = DiscoveryInfo{service_id, listener}; + discovery_options_ = discovery_options; } void ClientProxy::StoppedDiscovery() { @@ -101,6 +106,7 @@ void ClientProxy::StoppedDiscovery() { discovered_endpoint_ids_.clear(); discovery_info_.Clear(); } + // discovery_options_ is purposefully not cleared here. ResetLocalEndpointIdIfNeeded(); } @@ -188,6 +194,11 @@ void ClientProxy::OnConnectionInitiated(const std::string& endpoint_id, // Note: we allow devices to connect to an advertiser even after it stops // advertising, so no need to check IsAdvertising() here. item.connection_listener.initiated_cb(endpoint_id, info); + + if (info.is_incoming_connection) { + // Add CancellationFlag for advertisers once encryption succeeds. + AddCancellationFlag(endpoint_id); + } } void ClientProxy::OnConnectionAccepted(const std::string& endpoint_id) { @@ -248,6 +259,8 @@ void ClientProxy::OnDisconnected(const std::string& endpoint_id, bool notify) { connections_.erase(endpoint_id); ResetLocalEndpointIdIfNeeded(); } + + CancelEndpoint(endpoint_id); } bool ClientProxy::ConnectionStatusMatches(const std::string& endpoint_id, @@ -443,6 +456,42 @@ bool ClientProxy::RemoteConnectionIsAccepted(std::string endpoint_id) const { endpoint_id, ClientProxy::Connection::kRemoteEndpointAccepted); } +void ClientProxy::AddCancellationFlag(const std::string& endpoint_id) { + auto item = cancellation_flags_.find(endpoint_id); + if (item != cancellation_flags_.end()) { + return; + } + cancellation_flags_.emplace(endpoint_id, + std::make_unique()); +} + +CancellationFlag* ClientProxy::GetCancellationFlag( + const std::string& endpoint_id) { + const auto item = cancellation_flags_.find(endpoint_id); + if (item == cancellation_flags_.end()) { + return default_cancellation_flag_.get(); + } + return item->second.get(); +} + +void ClientProxy::CancelEndpoint(const std::string& endpoint_id) { + const auto item = cancellation_flags_.find(endpoint_id); + if (item == cancellation_flags_.end()) return; + item->second->Cancel(); + cancellation_flags_.erase(item); +} + +void ClientProxy::CancelAllEndpoints() { + for (const auto& item : cancellation_flags_) { + CancellationFlag* cancellation_flag = item.second.get(); + if (cancellation_flag->Cancelled()) { + continue; + } + cancellation_flag->Cancel(); + } + cancellation_flags_.clear(); +} + void ClientProxy::OnPayload(const std::string& endpoint_id, Payload payload) { MutexLock lock(&mutex_); @@ -493,6 +542,7 @@ void ClientProxy::RemoveAllEndpoints() { // endpoint, in the case when this is called from stopAllEndpoints(). For now, // just remove without notifying. connections_.clear(); + cancellation_flags_.clear(); local_endpoint_id_.clear(); } @@ -521,6 +571,14 @@ void ClientProxy::AppendConnectionStatus(const std::string& endpoint_id, } } +ConnectionOptions ClientProxy::GetAdvertisingOptions() const { + return advertising_options_; +} + +ConnectionOptions ClientProxy::GetDiscoveryOptions() const { + return discovery_options_; +} + } // namespace connections } // namespace nearby } // namespace location diff --git a/cpp/core/internal/client_proxy.h b/cpp/core/internal/client_proxy.h index 5559b8f9..497655b9 100644 --- a/cpp/core/internal/client_proxy.h +++ b/cpp/core/internal/client_proxy.h @@ -10,6 +10,7 @@ #include "core/status.h" #include "core/strategy.h" #include "platform/base/byte_array.h" +#include "platform/base/cancellation_flag.h" #include "platform/base/prng.h" #include "platform/public/mutex.h" #include "proto/connections_enums.pb.h" @@ -45,7 +46,8 @@ class ClientProxy final { void StartedAdvertising( const std::string& service_id, Strategy strategy, const ConnectionListener& connection_lifecycle_listener, - absl::Span mediums); + absl::Span mediums, + const ConnectionOptions& advertising_options = ConnectionOptions{}); // Marks this client as not advertising. void StoppedAdvertising(); bool IsAdvertising() const; @@ -56,9 +58,11 @@ class ClientProxy final { std::string GetServiceId() const; // Marks this client as discovering with the given callback. - void StartedDiscovery(const std::string& service_id, Strategy strategy, - const DiscoveryListener& discovery_listener, - absl::Span mediums); + void StartedDiscovery( + const std::string& service_id, Strategy strategy, + const DiscoveryListener& discovery_listener, + absl::Span mediums, + const ConnectionOptions& discovery_options = ConnectionOptions{}); // Marks this client as not discovering at all. void StoppedDiscovery(); bool IsDiscoveringServiceId(const std::string& service_id) const; @@ -139,6 +143,17 @@ class ClientProxy final { bool LocalConnectionIsAccepted(std::string endpoint_id) const; bool RemoteConnectionIsAccepted(std::string endpoint_id) const; + // 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); + // Sets the CancellationFlag to true for endpoint id. + void CancelEndpoint(const std::string& endpoint_id); + // Cancels all CancellationFlags. + void CancelAllEndpoints(); + ConnectionOptions GetAdvertisingOptions() const; + ConnectionOptions GetDiscoveryOptions() const; + private: struct Connection { // Status: may be either: @@ -207,6 +222,19 @@ class ClientProxy final { // If not empty, we are currently discovering for the given service_id. DiscoveryInfo discovery_info_; + // The active ClientProxy's advertising constraints. Empty() + // returns true if the client hasn't started advertising false otherwise. + // Note: this is not cleared when the client stops advertising because it + // might still be useful downstream of advertising (eg: establishing + // connections, performing bandwidth upgrades, etc.) + ConnectionOptions advertising_options_; + + // The active ClientProxy's discovery constraints. Null if the client + // hasn't started discovering. Note: this is not cleared when the client + // stops discovering because it might still be useful downstream of + // discovery (eg: connection speed, etc.) + ConnectionOptions discovery_options_; + // Maps endpoint_id to endpoint connection state. absl::flat_hash_map connections_; @@ -216,6 +244,13 @@ class ClientProxy final { // happen because some mediums (like Bluetooth) repeatedly give us the same // endpoints after each scan. absl::flat_hash_set discovered_endpoint_ids_; + + // Maps endpoint_id to CancellationFlag. + 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); }; // Operator overloads when comparing Ptr. diff --git a/cpp/core/internal/client_proxy_test.cc b/cpp/core/internal/client_proxy_test.cc index 2e7a92cd..5d03df41 100644 --- a/cpp/core/internal/client_proxy_test.cc +++ b/cpp/core/internal/client_proxy_test.cc @@ -79,8 +79,7 @@ class ClientProxyTest : public testing::Test { void OnDiscoveryEndpointFound(ClientProxy* client, const Endpoint& endpoint) { EXPECT_CALL(mock_discovery_.endpoint_found_cb, Call).Times(1); - client->OnEndpointFound(service_id_, endpoint.id, endpoint.info, - medium_); + client->OnEndpointFound(service_id_, endpoint.id, endpoint.info, medium_); } void OnDiscoveryEndpointLost(ClientProxy* client, const Endpoint& endpoint) { @@ -98,6 +97,8 @@ class ClientProxyTest : public testing::Test { connection_options_, discovery_connection_listener_); EXPECT_TRUE(client->HasPendingConnectionToEndpoint(endpoint.id)); + // Cancellation flag has been created and added into map. + EXPECT_FALSE(client->GetCancellationFlag(endpoint.id)->Cancelled()); } void OnDiscoveryConnectionLocalAccepted(ClientProxy* client, @@ -160,6 +161,8 @@ class ClientProxyTest : public testing::Test { const Endpoint& endpoint) { EXPECT_CALL(mock_discovery_connection_.disconnected_cb, Call).Times(1); client->OnDisconnected(endpoint.id, true); + // The Cancelled is always true as the default flag being returned. + EXPECT_TRUE(client->GetCancellationFlag(endpoint.id)->Cancelled()); } void OnPayload(ClientProxy* client, const Endpoint& endpoint) { @@ -221,8 +224,7 @@ TEST_F(ClientProxyTest, ClientIdIsUnique) { } TEST_F(ClientProxyTest, GeneratedEndpointIdIsUnique) { - EXPECT_NE(client1_.GetLocalEndpointId(), - client2_.GetLocalEndpointId()); + EXPECT_NE(client1_.GetLocalEndpointId(), client2_.GetLocalEndpointId()); } TEST_F(ClientProxyTest, ResetClearsState) { @@ -355,6 +357,72 @@ TEST_F(ClientProxyTest, OnPayloadProgressChangesState) { OnPayloadProgress(&client2_, advertising_endpoint); } +TEST_F(ClientProxyTest, CanCancelEndpoint) { + Endpoint advertising_endpoint = + StartAdvertising(&client1_, advertising_connection_listener_); + StartDiscovery(&client2_, discovery_listener_); + OnDiscoveryEndpointFound(&client2_, advertising_endpoint); + OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); + + EXPECT_FALSE( + client2_.GetCancellationFlag(advertising_endpoint.id)->Cancelled()); + + client2_.CancelEndpoint(advertising_endpoint.id); + + // The Cancelled is always true as the default flag being returned. + EXPECT_TRUE( + client2_.GetCancellationFlag(advertising_endpoint.id)->Cancelled()); +} + +TEST_F(ClientProxyTest, CanCancelAllEndpoints) { + Endpoint advertising_endpoint = + StartAdvertising(&client1_, advertising_connection_listener_); + StartDiscovery(&client2_, discovery_listener_); + OnDiscoveryEndpointFound(&client2_, advertising_endpoint); + OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); + + EXPECT_FALSE( + client2_.GetCancellationFlag(advertising_endpoint.id)->Cancelled()); + + client2_.CancelAllEndpoints(); + + // The Cancelled is always true as the default flag being returned. + EXPECT_TRUE( + client2_.GetCancellationFlag(advertising_endpoint.id)->Cancelled()); +} + +TEST_F(ClientProxyTest, CanCancelAllEndpointsWithDifferentEndpoint) { + ConnectionListener advertising_connection_listener_2; + ConnectionListener advertising_connection_listener_3; + ClientProxy client3; + + StartDiscovery(&client1_, discovery_listener_); + Endpoint advertising_endpoint_2 = + StartAdvertising(&client2_, advertising_connection_listener_2); + Endpoint advertising_endpoint_3 = + StartAdvertising(&client3, advertising_connection_listener_3); + OnDiscoveryEndpointFound(&client1_, advertising_endpoint_2); + OnDiscoveryConnectionInitiated(&client1_, advertising_endpoint_2); + OnDiscoveryEndpointFound(&client1_, advertising_endpoint_3); + OnDiscoveryConnectionInitiated(&client1_, advertising_endpoint_3); + + // The CancellationFlag of endpoint_2 and endpoint_3 have been added. Default + // Cancelled is false. + EXPECT_FALSE( + client1_.GetCancellationFlag(advertising_endpoint_2.id)->Cancelled()); + EXPECT_FALSE( + client1_.GetCancellationFlag(advertising_endpoint_3.id)->Cancelled()); + + client1_.CancelAllEndpoints(); + + // Expect the CancellationFlag of endpoint_2 and endpoint_3 has been removed. + // The Cancelled is always true as the default flag being returned. + EXPECT_TRUE( + client1_.GetCancellationFlag(advertising_endpoint_2.id)->Cancelled()); + EXPECT_TRUE( + client1_.GetCancellationFlag(advertising_endpoint_3.id)->Cancelled()); +} + } // namespace } // namespace connections } // namespace nearby diff --git a/cpp/core/internal/endpoint_manager.cc b/cpp/core/internal/endpoint_manager.cc index cc48616a..eb994719 100644 --- a/cpp/core/internal/endpoint_manager.cc +++ b/cpp/core/internal/endpoint_manager.cc @@ -296,8 +296,6 @@ EndpointManager::FrameProcessor* EndpointManager::GetFrameProcessor( latch.CountDown(); }); latch.Await(); - NEARBY_LOG(INFO, "GetFrameProcessor: type=%d; processor=%p", frame_type, - processor); return processor; } diff --git a/cpp/core/internal/fuzzers/BUILD b/cpp/core/internal/fuzzers/BUILD new file mode 100644 index 00000000..0c113e12 --- /dev/null +++ b/cpp/core/internal/fuzzers/BUILD @@ -0,0 +1,12 @@ +load("//security/fuzzing/blaze:cc_fuzz_target.bzl", "cc_fuzz_target") + +cc_fuzz_target( + name = "offline_frames_fuzzer", + srcs = ["offline_frames_fuzzer.cc"], + componentid = 148515, + deps = [ + "//core/internal", + "//platform/base", + "//security/fuzzing/blaze:default_init_google_for_cc_fuzz_target", + ], +) diff --git a/cpp/core/internal/fuzzers/offline_frames_fuzzer.cc b/cpp/core/internal/fuzzers/offline_frames_fuzzer.cc new file mode 100644 index 00000000..50a6062d --- /dev/null +++ b/cpp/core/internal/fuzzers/offline_frames_fuzzer.cc @@ -0,0 +1,11 @@ +#include "core/internal/offline_frames.h" +#include "platform/base/byte_array.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + location::nearby::ByteArray byte_array; + byte_array.SetData(reinterpret_cast(data), size); + + location::nearby::connections::parser::FromBytes(byte_array); + + return 0; +} diff --git a/cpp/core/internal/mediums/BUILD b/cpp/core/internal/mediums/BUILD index a1b900d1..9e703b38 100644 --- a/cpp/core/internal/mediums/BUILD +++ b/cpp/core/internal/mediums/BUILD @@ -31,6 +31,7 @@ cc_library( "//core/internal/mediums/webrtc", "//proto/connections:offline_wire_formats_portable_proto", "//platform/base", + "//platform/base:cancellation_flag", "//platform/public:comm", "//platform/public:logging", "//platform/public:types", diff --git a/cpp/core/internal/mediums/ble.cc b/cpp/core/internal/mediums/ble.cc index 5c14dd54..2a850b4b 100644 --- a/cpp/core/internal/mediums/ble.cc +++ b/cpp/core/internal/mediums/ble.cc @@ -290,8 +290,9 @@ bool Ble::IsAcceptingConnectionsLocked(const std::string& service_id) { return accepting_connections_info_.Existed(service_id); } -BleSocket Ble::Connect(BlePeripheral& peripheral, - const std::string& service_id) { +// TODO(b/169303284): Handles Cancellation and registration. +BleSocket Ble::Connect(BlePeripheral& peripheral, const std::string& service_id, + CancellationFlag* cancellation_flag) { MutexLock lock(&mutex_); NEARBY_LOGS(INFO) << "BLE::Connect: service=" << &peripheral; // Socket to return. To allow for NRVO to work, it has to be a single object. diff --git a/cpp/core/internal/mediums/ble.h b/cpp/core/internal/mediums/ble.h index 83f7ed3f..4168392f 100644 --- a/cpp/core/internal/mediums/ble.h +++ b/cpp/core/internal/mediums/ble.h @@ -7,6 +7,7 @@ #include "core/internal/mediums/bluetooth_radio.h" #include "core/listeners.h" #include "platform/base/byte_array.h" +#include "platform/base/cancellation_flag.h" #include "platform/public/ble.h" #include "platform/public/multi_thread_executor.h" #include "platform/public/mutex.h" @@ -84,7 +85,8 @@ class Ble { // service_id. Blocks until connection is established, or server-side is // terminated. Returns socket instance. On success, BleSocket.IsValid() return // true. - BleSocket Connect(BlePeripheral& peripheral, const std::string& service_id) + BleSocket Connect(BlePeripheral& peripheral, const std::string& service_id, + CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_); private: diff --git a/cpp/core/internal/mediums/ble_test.cc b/cpp/core/internal/mediums/ble_test.cc index d5a9df31..3f5d4f12 100644 --- a/cpp/core/internal/mediums/ble_test.cc +++ b/cpp/core/internal/mediums/ble_test.cc @@ -158,10 +158,8 @@ TEST_F(BleTest, CanStartAcceptingConnectionsAndConnect) { EXPECT_TRUE(found_latch.Await(kWaitDuration).result()); ASSERT_TRUE(discovered_peripheral.IsValid()); - - BleSocket socket = - ble_b.Connect(discovered_peripheral, service_id); - + CancellationFlag flag; + BleSocket socket = ble_b.Connect(discovered_peripheral, service_id, &flag); EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); EXPECT_TRUE(socket.IsValid()); ble_b.StopScanning(service_id); diff --git a/cpp/core/internal/mediums/bluetooth_classic.cc b/cpp/core/internal/mediums/bluetooth_classic.cc index 06aecac6..88a857e0 100644 --- a/cpp/core/internal/mediums/bluetooth_classic.cc +++ b/cpp/core/internal/mediums/bluetooth_classic.cc @@ -330,8 +330,10 @@ bool BluetoothClassic::StopAcceptingConnections( return true; } +// TODO(b/169303284): Handles Cancellation and registration. BluetoothSocket BluetoothClassic::Connect(BluetoothDevice& bluetooth_device, - const std::string& service_name) { + const std::string& service_name, + CancellationFlag* cancellation_flag) { for (int attempts_count = 0; attempts_count < kConnectAttemptsLimit; attempts_count++) { auto wrapper_result = AttemptToConnect(bluetooth_device, service_name); diff --git a/cpp/core/internal/mediums/bluetooth_classic.h b/cpp/core/internal/mediums/bluetooth_classic.h index e1e05094..49fa656c 100644 --- a/cpp/core/internal/mediums/bluetooth_classic.h +++ b/cpp/core/internal/mediums/bluetooth_classic.h @@ -7,6 +7,7 @@ #include "core/internal/mediums/bluetooth_radio.h" #include "core/listeners.h" #include "platform/base/byte_array.h" +#include "platform/base/cancellation_flag.h" #include "platform/public/bluetooth_adapter.h" #include "platform/public/bluetooth_classic.h" #include "platform/public/multi_thread_executor.h" @@ -97,7 +98,8 @@ class BluetoothClassic { // Returns socket instance. On success, BluetoothSocket.IsValid() return true. // Called by client. BluetoothSocket Connect(BluetoothDevice& bluetooth_device, - const std::string& service_name) + const std::string& service_name, + CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_); std::string GetMacAddress() const ABSL_LOCKS_EXCLUDED(mutex_); diff --git a/cpp/core/internal/mediums/bluetooth_classic_test.cc b/cpp/core/internal/mediums/bluetooth_classic_test.cc index 7294c131..131df208 100644 --- a/cpp/core/internal/mediums/bluetooth_classic_test.cc +++ b/cpp/core/internal/mediums/bluetooth_classic_test.cc @@ -180,8 +180,9 @@ TEST_F(BluetoothClassicTest, CanConnect) { accept_latch.CountDown(); }, })); + CancellationFlag flag; BluetoothSocket socket_for_client = - bt_client.Connect(discovered_device, std::string(kServiceName)); + bt_client.Connect(discovered_device, std::string(kServiceName), &flag); EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); EXPECT_TRUE(bt_server.StopAcceptingConnections(std::string(kServiceName))); EXPECT_TRUE(socket_for_server.IsValid()); diff --git a/cpp/core/internal/mediums/webrtc.cc b/cpp/core/internal/mediums/webrtc.cc index 7fc70115..e09de9f8 100644 --- a/cpp/core/internal/mediums/webrtc.cc +++ b/cpp/core/internal/mediums/webrtc.cc @@ -194,7 +194,8 @@ void WebRtc::StopAcceptingConnections(const std::string& service_id) { WebRtcSocketWrapper WebRtc::Connect(const std::string& service_id, const PeerId& remote_peer_id, - const LocationHint& location_hint) { + const LocationHint& location_hint, + CancellationFlag* cancellation_flag) { for (int attempts_count = 0; attempts_count < kConnectAttemptsLimit; attempts_count++) { auto wrapper_result = diff --git a/cpp/core/internal/mediums/webrtc.h b/cpp/core/internal/mediums/webrtc.h index 99cccc69..9d5bcccc 100644 --- a/cpp/core/internal/mediums/webrtc.h +++ b/cpp/core/internal/mediums/webrtc.h @@ -13,6 +13,7 @@ #include "proto/connections/offline_wire_formats.pb.h" #include "proto/connections/offline_wire_formats.pb.h" #include "platform/base/byte_array.h" +#include "platform/base/cancellation_flag.h" #include "platform/base/listeners.h" #include "platform/base/runnable.h" #include "platform/public/atomic_boolean.h" @@ -78,7 +79,8 @@ class WebRtc { // Runs on @MainThread. WebRtcSocketWrapper Connect(const std::string& service_id, const PeerId& peer_id, - const LocationHint& location_hint) + const LocationHint& location_hint, + CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_); private: diff --git a/cpp/core/internal/mediums/webrtc_test.cc b/cpp/core/internal/mediums/webrtc_test.cc index e5d9e36e..2ef0ce3b 100644 --- a/cpp/core/internal/mediums/webrtc_test.cc +++ b/cpp/core/internal/mediums/webrtc_test.cc @@ -61,8 +61,9 @@ TEST_F(WebRtcTest, Connect_DataChannelTimeOut) { LocationHint location_hint; ASSERT_TRUE(webrtc.IsAvailable()); + CancellationFlag flag; WebRtcSocketWrapper wrapper_1 = - webrtc.Connect(service_id, peer_id, location_hint); + webrtc.Connect(service_id, peer_id, location_hint, &flag); EXPECT_FALSE(wrapper_1.IsValid()); EXPECT_TRUE(webrtc.StartAcceptingConnections( @@ -85,8 +86,9 @@ TEST_F(WebRtcTest, StartAcceptingConnection_ThenConnect) { ASSERT_TRUE(webrtc.StartAcceptingConnections( service_id, self_id, location_hint, {mock_accepted_callback_.AsStdFunction()})); - WebRtcSocketWrapper wrapper = - webrtc.Connect(service_id, PeerId("random_peer_id"), location_hint); + CancellationFlag flag; + WebRtcSocketWrapper wrapper = webrtc.Connect( + service_id, PeerId("random_peer_id"), location_hint, &flag); EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); EXPECT_FALSE(wrapper.IsValid()); EXPECT_FALSE(webrtc.StartAcceptingConnections( @@ -136,7 +138,8 @@ TEST_F(WebRtcTest, ConnectTwice) { device_c.StartAcceptingConnections(service_id, other_id, location_hint, {[](WebRtcSocketWrapper wrapper) {}}); - sender_socket = sender.Connect(service_id, self_id, location_hint); + CancellationFlag flag; + sender_socket = sender.Connect(service_id, self_id, location_hint, &flag); EXPECT_TRUE(sender_socket.IsValid()); ExceptionOr devices_connected = connected.Get(); @@ -144,7 +147,7 @@ TEST_F(WebRtcTest, ConnectTwice) { EXPECT_TRUE(devices_connected.result()); WebRtcSocketWrapper socket = - sender.Connect(service_id, other_id, location_hint); + sender.Connect(service_id, other_id, location_hint, &flag); EXPECT_TRUE(socket.IsValid()); socket.Close(); @@ -178,7 +181,8 @@ TEST_F(WebRtcTest, ConnectBothDevicesAndAbort) { connected.Set(receiver_socket.IsValid()); }}); - sender_socket = sender.Connect(service_id, self_id, location_hint); + CancellationFlag flag; + sender_socket = sender.Connect(service_id, self_id, location_hint, &flag); EXPECT_TRUE(sender_socket.IsValid()); ExceptionOr devices_connected = connected.Get(); @@ -206,7 +210,8 @@ TEST_F(WebRtcTest, ConnectBothDevicesAndSendData) { connected.Set(receiver_socket.IsValid()); }}); - sender_socket = sender.Connect(service_id, self_id, location_hint); + CancellationFlag flag; + sender_socket = sender.Connect(service_id, self_id, location_hint, &flag); EXPECT_TRUE(sender_socket.IsValid()); ExceptionOr devices_connected = connected.Get(); @@ -240,7 +245,8 @@ TEST_F(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) { connected.Set(receiver_socket.IsValid()); }}); - sender_socket = sender.Connect(service_id, self_id, location_hint); + CancellationFlag flag; + sender_socket = sender.Connect(service_id, self_id, location_hint, &flag); EXPECT_TRUE(sender_socket.IsValid()); ExceptionOr devices_connected = connected.Get(); @@ -271,8 +277,9 @@ TEST_F(WebRtcTest, Connect_NullPeerConnection) { LocationHint location_hint; ASSERT_TRUE(webrtc.IsAvailable()); - WebRtcSocketWrapper wrapper = - webrtc.Connect(service_id, PeerId("random_peer_id"), location_hint); + CancellationFlag flag; + WebRtcSocketWrapper wrapper = webrtc.Connect( + service_id, PeerId("random_peer_id"), location_hint, &flag); EXPECT_FALSE(wrapper.IsValid()); } diff --git a/cpp/core/internal/mediums/wifi_lan.cc b/cpp/core/internal/mediums/wifi_lan.cc index 70057c11..7d45fa0f 100644 --- a/cpp/core/internal/mediums/wifi_lan.cc +++ b/cpp/core/internal/mediums/wifi_lan.cc @@ -208,8 +208,10 @@ bool WifiLan::IsAcceptingConnectionsLocked(const std::string& service_id) { return accepting_connections_info_.Existed(service_id); } +// TODO(b/169303284): Handles Cancellation and registration. WifiLanSocket WifiLan::Connect(WifiLanService& wifi_lan_service, - const std::string& service_id) { + const std::string& service_id, + CancellationFlag* cancellation_flag) { MutexLock lock(&mutex_); NEARBY_LOGS(INFO) << "WifiLan::Connect: wifi_lan_service=" << &wifi_lan_service << ", service_info_name=" diff --git a/cpp/core/internal/mediums/wifi_lan.h b/cpp/core/internal/mediums/wifi_lan.h index 6e9c47ac..7d890ca3 100644 --- a/cpp/core/internal/mediums/wifi_lan.h +++ b/cpp/core/internal/mediums/wifi_lan.h @@ -5,6 +5,7 @@ #include #include "platform/base/byte_array.h" +#include "platform/base/cancellation_flag.h" #include "platform/public/multi_thread_executor.h" #include "platform/public/mutex.h" #include "platform/public/wifi_lan.h" @@ -67,7 +68,8 @@ class WifiLan { // Blocks until connection is established, or server-side is terminated. // Returns socket instance. On success, WifiLanSocket.IsValid() return true. WifiLanSocket Connect(WifiLanService& wifi_lan_service, - const std::string& service_id) + const std::string& service_id, + CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_); WifiLanService GetRemoteWifiLanService(const std::string& ip_address, diff --git a/cpp/core/internal/mediums/wifi_lan_test.cc b/cpp/core/internal/mediums/wifi_lan_test.cc index fb905b59..0f0e3a83 100644 --- a/cpp/core/internal/mediums/wifi_lan_test.cc +++ b/cpp/core/internal/mediums/wifi_lan_test.cc @@ -145,10 +145,9 @@ TEST_F(WifiLanTest, CanStartAcceptingConnectionsAndConnect) { EXPECT_TRUE(found_latch.Await(kWaitDuration).result()); ASSERT_TRUE(discovered_service.IsValid()); - + CancellationFlag flag; WifiLanSocket socket = - wifi_lan_b.Connect(discovered_service, service_id); - + wifi_lan_b.Connect(discovered_service, service_id, &flag); EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); EXPECT_TRUE(socket.IsValid()); wifi_lan_b.StopDiscovery(service_id); diff --git a/cpp/core/internal/p2p_cluster_pcp_handler.cc b/cpp/core/internal/p2p_cluster_pcp_handler.cc index 96a1ea89..2f7e32bd 100644 --- a/cpp/core/internal/p2p_cluster_pcp_handler.cc +++ b/cpp/core/internal/p2p_cluster_pcp_handler.cc @@ -227,6 +227,83 @@ void P2pClusterPcpHandler::BluetoothDeviceDiscoveredHandler( }); } +void P2pClusterPcpHandler::BluetoothNameChangedHandler( + ClientProxy* client, const std::string& service_id, + BluetoothDevice device) { + RunOnPcpHandlerThread([this, client, service_id, device]() { + // Make sure we are still discovering before proceeding. + if (!client->IsDiscovering()) { + NEARBY_LOG(INFO, + "BT discovery handler (CHANGED) [client=%p, service=%s]: not " + "in discovery mode", + client, service_id.c_str()); + return; + } + + // Parse the Bluetooth device name. + const std::string device_name_string = device.GetName(); + BluetoothDeviceName device_name(device_name_string); + NEARBY_LOG(INFO, + "BT discovery handler (CHANGED) [client=%p, service=%s]: " + "processing new name %s", + client, service_id.c_str(), device_name_string.c_str()); + + // By this point, the BluetoothDevice passed to us has a different name than + // what we may have discovered before. We need to iterate over the found + // BluetoothEndpoints and compare their addresses to see the devices are the + // same. We are not guaranteed to discover a match, since the old name may + // not have been formatted for Nearby Connections. + for (auto endpoint : + GetDiscoveredEndpoints(proto::connections::Medium::BLUETOOTH)) { + BluetoothEndpoint* bluetoothEndpoint = + static_cast(endpoint); + NEARBY_LOG(INFO, + "BT discovery handler (CHANGED) [client=%p, service=%s]: " + "comparing MAC addresses with existing endpoint %s. They have " + "MAC address %s and the new endpoint has MAC address %s.", + client, service_id.c_str(), + bluetoothEndpoint->bluetooth_device.GetName().c_str(), + bluetoothEndpoint->bluetooth_device.GetMacAddress().c_str(), + device.GetMacAddress().c_str()); + if (bluetoothEndpoint->bluetooth_device.GetMacAddress() == + device.GetMacAddress()) { + // Report the BluetoothEndpoint as lost to the client. + NEARBY_LOG( + INFO, + "BT discovery handler (LOST) [client=%p, service=%s]: report " + "to client", + client, service_id.c_str()); + OnEndpointLost(client, *endpoint); + break; + } + } + + // Make sure the Bluetooth device name points to a valid + // endpoint we're discovering. + if (!IsRecognizedBluetoothEndpoint(device_name_string, service_id, + device_name)) { + NEARBY_LOG(INFO, + "BT discovery handler (CHANGED) [client=%p, service=%s]: The " + "new name is not recognized. Ignoring.", + client, service_id.c_str()); + return; + } + + // Report the discovered endpoint to the client. + NEARBY_LOGS(INFO) + << "Invoking BasePcpHandler::OnEndpointFound() for BT service=" + << service_id << "; id=" << device_name.GetEndpointId() << "; name=" + << absl::BytesToHexString(device_name.GetEndpointInfo().data()); + OnEndpointFound( + client, std::make_shared(BluetoothEndpoint{ + {device_name.GetEndpointId(), device_name.GetEndpointInfo(), + service_id, proto::connections::Medium::BLUETOOTH, + device_name.GetWebRtcState()}, + device, + })); + }); +} + void P2pClusterPcpHandler::BluetoothDeviceLostHandler( ClientProxy* client, const std::string& service_id, BluetoothDevice& device) { @@ -250,7 +327,7 @@ void P2pClusterPcpHandler::BluetoothDeviceLostHandler( device_name)) return; - // Report the discovered endpoint to the client. + // Report the BluetoothEndpoint as lost to the client. NEARBY_LOG(INFO, "BT discovery handler (LOST) [client=%p, service=%s]: report " "to client", @@ -576,7 +653,7 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( &P2pClusterPcpHandler::BluetoothDeviceDiscoveredHandler, this, client, service_id), .device_name_changed_cb = absl::bind_front( - &P2pClusterPcpHandler::BluetoothDeviceDiscoveredHandler, this, + &P2pClusterPcpHandler::BluetoothNameChangedHandler, this, client, service_id), .device_lost_cb = absl::bind_front( &P2pClusterPcpHandler::BluetoothDeviceLostHandler, this, client, @@ -814,8 +891,9 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BluetoothConnectImpl( ClientProxy* client, BluetoothEndpoint* endpoint) { BluetoothDevice& device = endpoint->bluetooth_device; - BluetoothSocket bluetooth_socket = - bluetooth_medium_.Connect(device, endpoint->service_id); + BluetoothSocket bluetooth_socket = bluetooth_medium_.Connect( + device, endpoint->service_id, + client->GetCancellationFlag(endpoint->endpoint_id)); if (!bluetooth_socket.IsValid()) { return BasePcpHandler::ConnectImplResult{ .status = {Status::kBluetoothError}, @@ -995,7 +1073,9 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BleConnectImpl( ClientProxy* client, BleEndpoint* endpoint) { BlePeripheral& peripheral = endpoint->ble_peripheral; - BleSocket ble_socket = ble_medium_.Connect(peripheral, endpoint->service_id); + BleSocket ble_socket = + ble_medium_.Connect(peripheral, endpoint->service_id, + client->GetCancellationFlag(endpoint->endpoint_id)); if (!ble_socket.IsValid()) { return BasePcpHandler::ConnectImplResult{ .status = {Status::kBleError}, @@ -1125,8 +1205,9 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::WifiLanConnectImpl( ClientProxy* client, WifiLanEndpoint* endpoint) { WifiLanService& wifi_lan_service = endpoint->wifi_lan_service; - WifiLanSocket wifi_lan_socket = - wifi_lan_medium_.Connect(wifi_lan_service, endpoint->service_id); + WifiLanSocket wifi_lan_socket = wifi_lan_medium_.Connect( + wifi_lan_service, endpoint->service_id, + client->GetCancellationFlag(endpoint->endpoint_id)); if (!wifi_lan_socket.IsValid()) { return BasePcpHandler::ConnectImplResult{ .status = {Status::kWifiLanError}, @@ -1190,7 +1271,8 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::WebRtcConnectImpl( std::string empty_country_code; mediums::WebRtcSocketWrapper socket_wrapper = webrtc_medium_.Connect( webrtc_endpoint->service_id, webrtc_endpoint->peer_id, - Utils::BuildLocationHint(empty_country_code)); + Utils::BuildLocationHint(empty_country_code), + client->GetCancellationFlag(webrtc_endpoint->endpoint_id)); if (!socket_wrapper.IsValid()) { return BasePcpHandler::ConnectImplResult{.status = {Status::kError}}; } diff --git a/cpp/core/internal/p2p_cluster_pcp_handler.h b/cpp/core/internal/p2p_cluster_pcp_handler.h index 016298fc..3d9bdbd4 100644 --- a/cpp/core/internal/p2p_cluster_pcp_handler.h +++ b/cpp/core/internal/p2p_cluster_pcp_handler.h @@ -116,6 +116,9 @@ class P2pClusterPcpHandler : public BasePcpHandler { void BluetoothDeviceDiscoveredHandler(ClientProxy* client, const std::string& service_id, BluetoothDevice device); + void BluetoothNameChangedHandler(ClientProxy* client, + const std::string& service_id, + BluetoothDevice device); void BluetoothDeviceLostHandler(ClientProxy* client, const std::string& service_id, BluetoothDevice& device); diff --git a/cpp/core/internal/service_controller_router.cc b/cpp/core/internal/service_controller_router.cc index fe281993..da189345 100644 --- a/cpp/core/internal/service_controller_router.cc +++ b/cpp/core/internal/service_controller_router.cc @@ -146,6 +146,10 @@ void ServiceControllerRouter::RequestConnection( ClientProxy* client, absl::string_view endpoint_id, const ConnectionRequestInfo& info, const ConnectionOptions& options, const ResultCallback& callback) { + // Cancellations can be fired from clients anytime, need to add the + // CancellationListener as soon as possible. + client->AddCancellationFlag(std::string(endpoint_id)); + RouteToServiceController([this, client, endpoint_id = std::string(endpoint_id), info, options, callback]() { @@ -160,8 +164,12 @@ void ServiceControllerRouter::RequestConnection( return; } - callback.result_cb(service_controller_->RequestConnection( - client, endpoint_id, info, options)); + Status status = service_controller_->RequestConnection(client, endpoint_id, + info, options); + if (!status.Ok()) { + client->CancelEndpoint(endpoint_id); + } + callback.result_cb(status); }); } @@ -199,6 +207,8 @@ void ServiceControllerRouter::AcceptConnection(ClientProxy* client, void ServiceControllerRouter::RejectConnection(ClientProxy* client, absl::string_view endpoint_id, const ResultCallback& callback) { + client->CancelEndpoint(std::string(endpoint_id)); + RouteToServiceController( [this, client, endpoint_id = std::string(endpoint_id), callback]() { if (!ClientHasAcquiredServiceController(client)) { @@ -296,6 +306,10 @@ void ServiceControllerRouter::CancelPayload(ClientProxy* client, void ServiceControllerRouter::DisconnectFromEndpoint( ClientProxy* client, absl::string_view endpoint_id, const ResultCallback& callback) { + // Client can emit the cancellation at anytime, we need to execute the request + // without further posting it. + client->CancelEndpoint(std::string(endpoint_id)); + RouteToServiceController( [this, client, endpoint_id = std::string(endpoint_id), callback]() { if (ClientHasAcquiredServiceController(client)) { @@ -312,6 +326,10 @@ void ServiceControllerRouter::DisconnectFromEndpoint( void ServiceControllerRouter::StopAllEndpoints(ClientProxy* client, const ResultCallback& callback) { + // Client can emit the cancellation at anytime, we need to execute the request + // without further posting it. + client->CancelAllEndpoints(); + RouteToServiceController([this, client, callback]() { if (ClientHasAcquiredServiceController(client)) { DoneWithStrategySessionForClient(client); @@ -322,6 +340,10 @@ void ServiceControllerRouter::StopAllEndpoints(ClientProxy* client, void ServiceControllerRouter::ClientDisconnecting( ClientProxy* client, const ResultCallback& callback) { + // Client can emit the cancellation at anytime, we need to execute the request + // without further posting it. + client->CancelAllEndpoints(); + RouteToServiceController([this, client, callback]() { if (ClientHasAcquiredServiceController(client)) { DoneWithStrategySessionForClient(client); diff --git a/cpp/core/internal/webrtc_bwu_handler.cc b/cpp/core/internal/webrtc_bwu_handler.cc index 85f53d14..93a0a3c7 100644 --- a/cpp/core/internal/webrtc_bwu_handler.cc +++ b/cpp/core/internal/webrtc_bwu_handler.cc @@ -109,7 +109,8 @@ WebrtcBwuHandler::CreateUpgradedEndpointChannel( peer_id.GetId().c_str(), location_hint.DebugString().c_str()); mediums::WebRtcSocketWrapper socket = - webrtc_.Connect(service_id, peer_id, location_hint); + webrtc_.Connect(service_id, peer_id, location_hint, + client->GetCancellationFlag(endpoint_id)); if (!socket.IsValid()) { NEARBY_LOG(ERROR, "WebRtcBwuHandler failed to connect to remote peer (%s) on " diff --git a/cpp/core/internal/wifi_lan_bwu_handler.cc b/cpp/core/internal/wifi_lan_bwu_handler.cc index de50d148..93889842 100644 --- a/cpp/core/internal/wifi_lan_bwu_handler.cc +++ b/cpp/core/internal/wifi_lan_bwu_handler.cc @@ -103,8 +103,8 @@ WifiLanBwuHandler::CreateUpgradedEndpointChannel( if (!wifi_lan_service.IsValid()) { return nullptr; } - WifiLanSocket socket = - wifi_lan_medium_.Connect(wifi_lan_service, service_id); + WifiLanSocket socket = wifi_lan_medium_.Connect( + wifi_lan_service, service_id, client->GetCancellationFlag(endpoint_id)); if (!socket.IsValid()) { return nullptr; } diff --git a/cpp/platform/base/BUILD b/cpp/platform/base/BUILD index c0ba327e..fc148908 100644 --- a/cpp/platform/base/BUILD +++ b/cpp/platform/base/BUILD @@ -80,6 +80,28 @@ cc_library( ], ) +cc_library( + name = "cancellation_flag", + srcs = [ + "cancellation_flag.cc", + ], + hdrs = [ + "cancellation_flag.h", + ], + visibility = [ + "//core/internal:__subpackages__", + "//platform/api:__subpackages__", + "//platform/impl:__subpackages__", + "//platform/public:__pkg__", + ], + deps = [ + ":base", + ":util", + "//absl/container:flat_hash_set", + "//absl/synchronization", + ], +) + cc_library( name = "test_util", testonly = True, @@ -129,6 +151,17 @@ cc_test( ], ) +cc_test( + name = "cancellation_flag_test", + srcs = [ + "cancellation_flag_test.cc", + ], + deps = [ + ":cancellation_flag", + "//testing/base/public:gunit_main", + ], +) + cc_with_non_compile_test( name = "exception_test", srcs = [ diff --git a/cpp/platform/base/cancellation_flag.cc b/cpp/platform/base/cancellation_flag.cc new file mode 100644 index 00000000..1bb6e062 --- /dev/null +++ b/cpp/platform/base/cancellation_flag.cc @@ -0,0 +1,32 @@ +#include "platform/base/cancellation_flag.h" + +namespace location { +namespace nearby { + +CancellationFlag::CancellationFlag() { + mutex_ = std::make_unique(); +} + +CancellationFlag::CancellationFlag(bool cancelled) { + mutex_ = std::make_unique(); + cancelled_ = cancelled; +} + +void CancellationFlag::Cancel() { + absl::MutexLock lock(mutex_.get()); + + if (cancelled_) { + // Someone already cancelled. Return immediately. + return; + } + cancelled_ = true; +} + +bool CancellationFlag::Cancelled() const { + absl::MutexLock lock(mutex_.get()); + + return cancelled_; +} + +} // namespace nearby +} // namespace location diff --git a/cpp/platform/base/cancellation_flag.h b/cpp/platform/base/cancellation_flag.h new file mode 100644 index 00000000..4ef3f1ba --- /dev/null +++ b/cpp/platform/base/cancellation_flag.h @@ -0,0 +1,37 @@ +#ifndef PLATFORM_BASE_CANCELLATION_FLAG_H_ +#define PLATFORM_BASE_CANCELLATION_FLAG_H_ + +#include + +#include "absl/synchronization/mutex.h" + +namespace location { +namespace nearby { + +// A cancellation flag to mark an operation has been cancelled and should be +// cleaned up as soon as possible. +class CancellationFlag { + public: + CancellationFlag(); + explicit CancellationFlag(bool cancelled); + CancellationFlag(const CancellationFlag &) = delete; + CancellationFlag &operator=(const CancellationFlag &) = delete; + CancellationFlag(CancellationFlag &&) = default; + CancellationFlag &operator=(CancellationFlag &&) = default; + virtual ~CancellationFlag() = default; + + // Set the flag as cancelled. + void Cancel() ABSL_LOCKS_EXCLUDED(mutex_); + + // Returns true if the flag has been set to cancelled. + bool Cancelled() const ABSL_LOCKS_EXCLUDED(mutex_); + + private: + std::unique_ptr mutex_; + bool cancelled_ ABSL_GUARDED_BY(mutex_) = false; +}; + +} // namespace nearby +} // namespace location + +#endif // PLATFORM_BASE_CANCELLATION_FLAG_H_ diff --git a/cpp/platform/base/cancellation_flag_test.cc b/cpp/platform/base/cancellation_flag_test.cc new file mode 100644 index 00000000..32d79e0d --- /dev/null +++ b/cpp/platform/base/cancellation_flag_test.cc @@ -0,0 +1,20 @@ +#include "platform/base/cancellation_flag.h" + +#include "gtest/gtest.h" + +namespace location { +namespace nearby { + +TEST(CancellationFlagTest, InitialValueIsFalse) { + CancellationFlag flag; + EXPECT_FALSE(flag.Cancelled()); +} + +TEST(CancellationFlagTest, CanCancel) { + CancellationFlag flag; + flag.Cancel(); + EXPECT_TRUE(flag.Cancelled()); +} + +} // namespace nearby +} // namespace location diff --git a/cpp/platform/impl/g3/webrtc.h b/cpp/platform/impl/g3/webrtc.h index 53196b54..1b3a80df 100644 --- a/cpp/platform/impl/g3/webrtc.h +++ b/cpp/platform/impl/g3/webrtc.h @@ -27,7 +27,7 @@ class WebRtcSignalingMessenger : public api::WebRtcSignalingMessenger { void StopReceivingMessages() override; private: - absl::string_view self_id_; + std::string self_id_; connections::LocationHint location_hint_; }; diff --git a/cpp/platform/public/BUILD b/cpp/platform/public/BUILD index 4562f961..e67f5e18 100644 --- a/cpp/platform/public/BUILD +++ b/cpp/platform/public/BUILD @@ -38,7 +38,6 @@ cc_library( "//platform/base:logging", "//platform/base:util", "//absl/base:core_headers", - "//absl/container:flat_hash_map", "//absl/time", ], )