From 2d845718f290f7e3ba8f33beec5f4018f35d178a Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 6 Jun 2024 18:55:30 -0700 Subject: [PATCH] Cleanup share target info. PiperOrigin-RevId: 641091075 --- sharing/BUILD | 6 + sharing/incoming_share_target_info.cc | 7 + sharing/incoming_share_target_info.h | 2 + sharing/nearby_sharing_service_impl.cc | 216 +++++++++++-------------- sharing/nearby_sharing_service_impl.h | 19 ++- sharing/outgoing_share_target_info.cc | 20 +++ sharing/outgoing_share_target_info.h | 3 + sharing/share_target_info.cc | 64 +++++++- sharing/share_target_info.h | 43 +++-- sharing/share_target_info_test.cc | 113 +++++++++++++ 10 files changed, 334 insertions(+), 159 deletions(-) diff --git a/sharing/BUILD b/sharing/BUILD index db0c40c2..d277e8ca 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -624,11 +624,17 @@ cc_test( srcs = ["share_target_info_test.cc"], deps = [ ":nearby_sharing_service", + ":test_support", ":transfer_metadata", ":types", + "//internal/platform/implementation:types", "//internal/platform/implementation/g3", # fixdeps: keep + "//sharing/certificates:test_support", + "//sharing/internal/test:nearby_test", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", + "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], ) diff --git a/sharing/incoming_share_target_info.cc b/sharing/incoming_share_target_info.cc index eeec98fd..6c8f2067 100644 --- a/sharing/incoming_share_target_info.cc +++ b/sharing/incoming_share_target_info.cc @@ -18,6 +18,7 @@ #include #include +#include "sharing/nearby_connection.h" #include "sharing/share_target.h" #include "sharing/share_target_info.h" #include "sharing/transfer_metadata.h" @@ -45,5 +46,11 @@ void IncomingShareTargetInfo::InvokeTransferUpdateCallback( transfer_update_callback_(*this, metadata); } +bool IncomingShareTargetInfo::OnNewConnection(NearbyConnection* connection) { + set_disconnect_status( + TransferMetadata::Status::kAwaitingRemoteAcceptanceFailed); + return true; +} + } // namespace sharing } // namespace nearby diff --git a/sharing/incoming_share_target_info.h b/sharing/incoming_share_target_info.h index 3f87d4d3..941b1b80 100644 --- a/sharing/incoming_share_target_info.h +++ b/sharing/incoming_share_target_info.h @@ -17,6 +17,7 @@ #include #include +#include "sharing/nearby_connection.h" #include "sharing/share_target.h" #include "sharing/share_target_info.h" #include "sharing/transfer_metadata.h" @@ -39,6 +40,7 @@ class IncomingShareTargetInfo : public ShareTargetInfo { protected: void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override; + bool OnNewConnection(NearbyConnection* connection) override; private: std::function diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index a46553a2..295af72f 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -1054,11 +1054,9 @@ void NearbySharingServiceImpl::OnIncomingConnection( ShareTarget placeholder_share_target; placeholder_share_target.is_incoming = true; int64_t placeholder_share_target_id = placeholder_share_target.id; - ShareTargetInfo& share_target_info = - GetOrCreateShareTargetInfo(placeholder_share_target, endpoint_id); - share_target_info.set_connection(connection); - share_target_info.set_disconnect_status( - TransferMetadata::Status::kAwaitingRemoteAcceptanceFailed); + IncomingShareTargetInfo& share_target_info = CreateIncomingShareTargetInfo( + placeholder_share_target, endpoint_id, /*certificate=*/std::nullopt); + share_target_info.OnConnected(context_->GetClock()->Now(), connection); connection->SetDisconnectionListener([this, placeholder_share_target_id]() { OnConnectionDisconnected(placeholder_share_target_id); }); @@ -1069,7 +1067,7 @@ void NearbySharingServiceImpl::OnIncomingConnection( std::unique_ptr advertisement = decoder_->DecodeAdvertisement(endpoint_info); - OnIncomingAdvertisementDecoded(endpoint_id, placeholder_share_target_id, + OnIncomingAdvertisementDecoded(endpoint_id, share_target_info, std::move(advertisement)); } @@ -1787,7 +1785,7 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate( // The certificate provides the device name, in order to create a ShareTarget // to represent this remote device. std::optional share_target = - CreateShareTarget(endpoint_id, advertisement, std::move(certificate), + CreateShareTarget(endpoint_id, advertisement, certificate, /*is_incoming=*/false); if (!share_target.has_value()) { if (discovered_advertisements_retried_set_.contains(endpoint_id)) { @@ -1809,6 +1807,8 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate( FinishEndpointDiscoveryEvent(); return; } + CreateOutgoingShareTargetInfo(*share_target, endpoint_id, + std::move(certificate)); // Update the endpoint id for the share target. NL_LOG(INFO) << __func__ @@ -2632,27 +2632,15 @@ void NearbySharingServiceImpl::OnPayloadPathsRegistered( void NearbySharingServiceImpl::OnOutgoingConnection( absl::Time connect_start_time, NearbyConnection* connection, OutgoingShareTargetInfo& info) { - if (!connection) { - NL_LOG(WARNING) << __func__ - << ": Failed to initiate connection to share target " - << info.share_target().id; - TransferMetadata::Status transfer_status = - TransferMetadata::Status::kFailedToInitiateOutgoingConnection; - if (info.connection_layer_status() == Status::kTimeout) { - transfer_status = TransferMetadata::Status::kTimedOut; - info.set_connection_layer_status(Status::kUnknown); - } - AbortAndCloseConnectionIfNecessary(transfer_status, info.share_target().id); + int64_t share_target_id = info.share_target().id; + if (!info.OnConnected(connect_start_time, connection)) { + AbortAndCloseConnectionIfNecessary(info.disconnect_status(), + share_target_id); return; } - info.set_connection(connection); - info.set_disconnect_status( - TransferMetadata::Status::kUnexpectedDisconnection); connection->SetDisconnectionListener( - [this, share_target_id = info.share_target().id]() { - OnConnectionDisconnected(share_target_id); - }); + [this, share_target_id]() { OnConnectionDisconnected(share_target_id); }); // Log analytics event of establishing connection. analytics_recorder_->NewEstablishConnection( @@ -2660,21 +2648,24 @@ void NearbySharingServiceImpl::OnOutgoingConnection( info.share_target(), /*transfer_position=*/GetConnectedShareTargetPos(), /*concurrent_connections=*/GetConnectedShareTargetCount(), - info.connection_start_time().has_value() - ? absl::ToInt64Milliseconds((context_->GetClock()->Now() - - *(info.connection_start_time()))) - : 0, - std::nullopt); + absl::ToInt64Milliseconds( + (context_->GetClock()->Now() - connect_start_time)), + /*referrer_package=*/std::nullopt); - - std::optional four_digit_token = TokenToFourDigitString( + std::optional> token = nearby_connections_manager_->GetRawAuthenticationToken( - info.endpoint_id())); + info.endpoint_id()); + std::optional four_digit_token = TokenToFourDigitString(token); - RunPairedKeyVerification( - info.share_target().id, info.endpoint_id(), - [this, share_target_id = info.share_target().id, - four_digit_token = std::move(four_digit_token)]( + info.RunPairedKeyVerification( + context_, decoder_, device_info_.GetOsType(), + { + .visibility = settings_->GetVisibility(), + .last_visibility = settings_->GetLastVisibility(), + .last_visibility_time = settings_->GetLastVisibilityTimestamp(), + }, + GetCertificateManager(), std::move(token), + [this, share_target_id, four_digit_token = std::move(four_digit_token)]( PairedKeyVerificationRunner::PairedKeyVerificationResult result, OSType remote_os_type) { OnOutgoingConnectionKeyVerificationDone( @@ -2879,8 +2870,6 @@ void NearbySharingServiceImpl::OnCreatePayloads( // For metrics. all_cancelled_share_target_ids_.clear(); - info->set_connection_start_time(context_->GetClock()->Now()); - nearby_connections_manager_->Connect( std::move(endpoint_info), info->endpoint_id(), std::move(bluetooth_mac_address), settings_->GetDataUsage(), @@ -3080,9 +3069,11 @@ void NearbySharingServiceImpl::Fail(int64_t share_target_id, } void NearbySharingServiceImpl::OnIncomingAdvertisementDecoded( - absl::string_view endpoint_id, int64_t placeholder_share_target_id, + absl::string_view endpoint_id, + const IncomingShareTargetInfo& share_target_info, std::unique_ptr advertisement) { - NearbyConnection* connection = GetConnection(placeholder_share_target_id); + int64_t placeholder_share_target_id = share_target_info.share_target().id; + NearbyConnection* connection = share_target_info.connection(); if (!connection) { NL_LOG(WARNING) << __func__ << ": Invalid connection for endpoint id - " << endpoint_id; @@ -3295,9 +3286,8 @@ void NearbySharingServiceImpl::OnIncomingDecryptedCertificate( incoming_share_target_info_map_.erase(placeholder_share_target_id); std::optional share_target = - CreateShareTarget(endpoint_id, advertisement, std::move(certificate), + CreateShareTarget(endpoint_id, advertisement, certificate, /*is_incoming=*/true); - if (!share_target) { NL_LOG(WARNING) << __func__ << ": Failed to convert advertisement to share target for " @@ -3307,26 +3297,30 @@ void NearbySharingServiceImpl::OnIncomingDecryptedCertificate( placeholder_share_target_id); return; } - int64_t share_target_id = share_target->id; NL_VLOG(1) << __func__ << ": Received incoming connection from " << share_target_id; - IncomingShareTargetInfo* share_target_info = - GetIncomingShareTargetInfo(share_target_id); - NL_DCHECK(share_target_info); - share_target_info->set_connection(connection); - share_target_info->set_disconnect_status( - TransferMetadata::Status::kAwaitingRemoteAcceptanceFailed); + IncomingShareTargetInfo& share_target_info = CreateIncomingShareTargetInfo( + *share_target, endpoint_id, std::move(certificate)); + share_target_info.OnConnected(context_->GetClock()->Now(), connection); // Need to rebind the disconnect listener to the new share target id. connection->SetDisconnectionListener( [this, share_target_id]() { OnConnectionDisconnected(share_target_id); }); - std::optional four_digit_token = TokenToFourDigitString( - nearby_connections_manager_->GetRawAuthenticationToken(endpoint_id)); + std::optional> token = + nearby_connections_manager_->GetRawAuthenticationToken( + share_target_info.endpoint_id()); + std::optional four_digit_token = TokenToFourDigitString(token); - RunPairedKeyVerification( - share_target_id, endpoint_id, + share_target_info.RunPairedKeyVerification( + context_, decoder_, device_info_.GetOsType(), + { + .visibility = settings_->GetVisibility(), + .last_visibility = settings_->GetLastVisibility(), + .last_visibility_time = settings_->GetLastVisibilityTimestamp(), + }, + GetCertificateManager(), std::move(token), [this, share_target_id, four_digit_token = std::move(four_digit_token)]( PairedKeyVerificationRunner::PairedKeyVerificationResult verification_result, @@ -3337,42 +3331,6 @@ void NearbySharingServiceImpl::OnIncomingDecryptedCertificate( }); } -void NearbySharingServiceImpl::RunPairedKeyVerification( - int64_t share_target_id, absl::string_view endpoint_id, - std::function - callback) { - std::optional> token = - nearby_connections_manager_->GetRawAuthenticationToken(endpoint_id); - if (!token) { - NL_VLOG(1) << __func__ - << ": Failed to read authentication token from endpoint - " - << endpoint_id; - std::move(callback)( - PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail, - OSType::UNKNOWN_OS_TYPE); - return; - } - - ShareTargetInfo* share_target_info = GetShareTargetInfo(share_target_id); - NL_DCHECK(share_target_info); - - share_target_info->set_frames_reader(std::make_shared( - context_, decoder_, share_target_info->connection())); - - share_target_info->set_key_verification_runner( - std::make_shared( - context_->GetClock(), device_info_.GetOsType(), - share_target_info->IsIncoming(), - PairedKeyVerificationRunner::VisibilityHistory{ - settings_->GetVisibility(), settings_->GetLastVisibility(), - settings_->GetLastVisibilityTimestamp()}, - *token, share_target_info->connection(), - share_target_info->certificate(), GetCertificateManager(), - share_target_info->frames_reader(), kReadFramesTimeout)); - share_target_info->key_verification_runner()->Run(std::move(callback)); -} - void NearbySharingServiceImpl::OnIncomingConnectionKeyVerificationDone( int64_t share_target_id, std::optional four_digit_token, PairedKeyVerificationRunner::PairedKeyVerificationResult result, @@ -3968,7 +3926,7 @@ void NearbySharingServiceImpl::OnOutgoingMutualAcceptanceTimeout( std::optional NearbySharingServiceImpl::CreateShareTarget( absl::string_view endpoint_id, const Advertisement& advertisement, - std::optional certificate, + const std::optional& certificate, bool is_incoming) { if (!advertisement.device_name() && !certificate.has_value()) { NL_VLOG(1) << __func__ @@ -4013,10 +3971,6 @@ std::optional NearbySharingServiceImpl::CreateShareTarget( } target.is_known = true; } - ShareTargetInfo& info = GetOrCreateShareTargetInfo(target, endpoint_id); - if (certificate.has_value()) { - info.set_certificate(std::move(*certificate)); - } return target; } @@ -4316,36 +4270,52 @@ void NearbySharingServiceImpl::OnDisconnectingConnectionTimeout( nearby_connections_manager_->Disconnect(endpoint_id); } -ShareTargetInfo& NearbySharingServiceImpl::GetOrCreateShareTargetInfo( - const ShareTarget& share_target, absl::string_view endpoint_id) { - if (share_target.is_incoming) { - auto [it, inserted] = incoming_share_target_info_map_.try_emplace( - share_target.id, std::string(endpoint_id), share_target, - absl::bind_front(&NearbySharingServiceImpl::OnIncomingTransferUpdate, - this)); - return it->second; - } else { - // We need to explicitly remove any previous share target for - // |endpoint_id| if one exists, notifying observers that a share target is - // lost. - const auto it = outgoing_share_target_map_.find(endpoint_id); - if (it != outgoing_share_target_map_.end() && - it->second.id != share_target.id) { - RemoveOutgoingShareTargetWithEndpointId(endpoint_id); - } - - NL_VLOG(1) << __func__ << ": Adding (endpoint_id=" << endpoint_id - << ", share_target_id=" << share_target.id - << ") to outgoing share target map"; - outgoing_share_target_map_.insert_or_assign(endpoint_id, share_target); - auto [it_out, inserted] = outgoing_share_target_info_map_.try_emplace( - share_target.id, std::string(endpoint_id), share_target, - absl::bind_front(&NearbySharingServiceImpl::OnOutgoingTransferUpdate, - this)); - auto& info = it_out->second; - info.set_connection_layer_status(Status::kUnknown); - return info; +IncomingShareTargetInfo& +NearbySharingServiceImpl::CreateIncomingShareTargetInfo( + const ShareTarget& share_target, absl::string_view endpoint_id, + std::optional certificate) { + NL_DCHECK(share_target.is_incoming); + auto [it, inserted] = incoming_share_target_info_map_.try_emplace( + share_target.id, std::string(endpoint_id), share_target, + absl::bind_front(&NearbySharingServiceImpl::OnIncomingTransferUpdate, + this)); + if (!inserted) { + NL_LOG(ERROR) << __func__ << ": Incoming share target id already exists " + << share_target.id; } + if (certificate.has_value()) { + it->second.set_certificate(std::move(*certificate)); + } + return it->second; +} + +OutgoingShareTargetInfo& +NearbySharingServiceImpl::CreateOutgoingShareTargetInfo( + const ShareTarget& share_target, absl::string_view endpoint_id, + std::optional certificate) { + // We need to explicitly remove any previous share target for + // |endpoint_id| if one exists, notifying observers that a share target is + // lost. + const auto it = outgoing_share_target_map_.find(endpoint_id); + if (it != outgoing_share_target_map_.end() && + it->second.id != share_target.id) { + RemoveOutgoingShareTargetWithEndpointId(endpoint_id); + } + + NL_VLOG(1) << __func__ << ": Adding (endpoint_id=" << endpoint_id + << ", share_target_id=" << share_target.id + << ") to outgoing share target map"; + outgoing_share_target_map_.insert_or_assign(endpoint_id, share_target); + auto [it_out, inserted] = outgoing_share_target_info_map_.try_emplace( + share_target.id, std::string(endpoint_id), share_target, + absl::bind_front(&NearbySharingServiceImpl::OnOutgoingTransferUpdate, + this)); + auto& info = it_out->second; + info.set_connection_layer_status(Status::kUnknown); + if (certificate.has_value()) { + info.set_certificate(std::move(*certificate)); + } + return info; } ShareTargetInfo* NearbySharingServiceImpl::GetShareTargetInfo( diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index 1684d17b..6fb49c44 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -358,7 +358,8 @@ class NearbySharingServiceImpl std::optional progress); void Fail(int64_t share_target_id, TransferMetadata::Status status); void OnIncomingAdvertisementDecoded( - absl::string_view endpoint_id, int64_t placeholder_share_target_id, + absl::string_view endpoint_id, + const IncomingShareTargetInfo& share_target_info, std::unique_ptr advertisement); void OnIncomingTransferUpdate( const IncomingShareTargetInfo& share_target_info, @@ -371,12 +372,6 @@ class NearbySharingServiceImpl absl::string_view endpoint_id, const Advertisement& advertisement, int64_t placeholder_share_target_id, std::optional certificate); - void RunPairedKeyVerification( - int64_t share_target_id, absl::string_view endpoint_id, - std::function< - void(PairedKeyVerificationRunner::PairedKeyVerificationResult, - ::location::nearby::proto::sharing::OSType)> - callback); void OnIncomingConnectionKeyVerificationDone( int64_t share_target_id, std::optional four_digit_token, PairedKeyVerificationRunner::PairedKeyVerificationResult result, @@ -416,7 +411,7 @@ class NearbySharingServiceImpl std::optional CreateShareTarget( absl::string_view endpoint_id, const Advertisement& advertisement, - std::optional certificate, + const std::optional& certificate, bool is_incoming); void OnPayloadTransferUpdate(int64_t share_target_id, @@ -426,8 +421,12 @@ class NearbySharingServiceImpl void Disconnect(int64_t share_target_id, TransferMetadata metadata); void OnDisconnectingConnectionTimeout(absl::string_view endpoint_id); - ShareTargetInfo& GetOrCreateShareTargetInfo(const ShareTarget& share_target, - absl::string_view endpoint_id); + IncomingShareTargetInfo& CreateIncomingShareTargetInfo( + const ShareTarget& share_target, absl::string_view endpoint_id, + std::optional certificate); + OutgoingShareTargetInfo& CreateOutgoingShareTargetInfo( + const ShareTarget& share_target, absl::string_view endpoint_id, + std::optional certificate); ShareTargetInfo* GetShareTargetInfo(int64_t share_target_id); IncomingShareTargetInfo* GetIncomingShareTargetInfo(int64_t share_target_id); diff --git a/sharing/outgoing_share_target_info.cc b/sharing/outgoing_share_target_info.cc index 3463d65f..14ccc910 100644 --- a/sharing/outgoing_share_target_info.cc +++ b/sharing/outgoing_share_target_info.cc @@ -20,6 +20,8 @@ #include #include +#include "sharing/internal/public/logging.h" +#include "sharing/nearby_connection.h" #include "sharing/nearby_connections_types.h" #include "sharing/share_target.h" #include "sharing/share_target_info.h" @@ -48,6 +50,24 @@ void OutgoingShareTargetInfo::InvokeTransferUpdateCallback( transfer_update_callback_(*this, metadata); } +bool OutgoingShareTargetInfo::OnNewConnection(NearbyConnection* connection) { + if (!connection) { + NL_LOG(WARNING) << __func__ + << ": Failed to initiate connection to share target " + << share_target().id; + if (connection_layer_status_ == Status::kTimeout) { + set_disconnect_status(TransferMetadata::Status::kTimedOut); + connection_layer_status_ = Status::kUnknown; + } else { + set_disconnect_status( + TransferMetadata::Status::kFailedToInitiateOutgoingConnection); + } + return false; + } + set_disconnect_status(TransferMetadata::Status::kUnexpectedDisconnection); + return true; +} + std::vector OutgoingShareTargetInfo::ExtractTextPayloads() { return std::move(text_payloads_); } diff --git a/sharing/outgoing_share_target_info.h b/sharing/outgoing_share_target_info.h index 2357faa3..69200642 100644 --- a/sharing/outgoing_share_target_info.h +++ b/sharing/outgoing_share_target_info.h @@ -21,6 +21,7 @@ #include #include +#include "sharing/nearby_connection.h" #include "sharing/nearby_connections_types.h" #include "sharing/share_target.h" #include "sharing/share_target_info.h" @@ -84,6 +85,8 @@ class OutgoingShareTargetInfo : public ShareTargetInfo { protected: void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override; + bool OnNewConnection(NearbyConnection* connection) override; + private: std::optional obfuscated_gaia_id_; diff --git a/sharing/share_target_info.cc b/sharing/share_target_info.cc index 6d9eeee9..981ed469 100644 --- a/sharing/share_target_info.cc +++ b/sharing/share_target_info.cc @@ -14,16 +14,34 @@ #include "sharing/share_target_info.h" +#include +#include +#include +#include #include #include +#include +#include "absl/time/time.h" +#include "internal/platform/implementation/device_info.h" +#include "sharing/certificates/nearby_share_certificate_manager.h" +#include "sharing/constants.h" +#include "sharing/incoming_frames_reader.h" +#include "sharing/internal/public/context.h" #include "sharing/internal/public/logging.h" +#include "sharing/nearby_connection.h" +#include "sharing/nearby_sharing_decoder.h" +#include "sharing/paired_key_verification_runner.h" #include "sharing/share_target.h" #include "sharing/transfer_metadata.h" #include "sharing/transfer_metadata_builder.h" -namespace nearby { -namespace sharing { +namespace nearby::sharing { +namespace { + +using ::location::nearby::proto::sharing::OSType; + +} // namespace ShareTargetInfo::ShareTargetInfo( std::string endpoint_id, const ShareTarget& share_target) @@ -63,6 +81,45 @@ void ShareTargetInfo::set_disconnect_status( } } +bool ShareTargetInfo::OnConnected(absl::Time connect_start_time, + NearbyConnection* connection) { + if (!OnNewConnection(connection)) { + return false; + } + connection_start_time_ = connect_start_time; + connection_ = connection; + return true; +} + +void ShareTargetInfo::RunPairedKeyVerification( + Context* context, NearbySharingDecoder* decoder, + nearby::api::DeviceInfo::OsType os_type, + const PairedKeyVerificationRunner::VisibilityHistory& visibility_history, + NearbyShareCertificateManager* certificate_manager, + std::optional> token, + std::function + callback) { + if (!token) { + NL_VLOG(1) << __func__ + << ": Failed to read authentication token from endpoint - " + << endpoint_id_; + std::move(callback)( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail, + OSType::UNKNOWN_OS_TYPE); + return; + } + + frames_reader_ = + std::make_shared(context, decoder, connection_); + + key_verification_runner_ = std::make_shared( + context->GetClock(), os_type, IsIncoming(), visibility_history, *token, + connection_, certificate_, certificate_manager, frames_reader_.get(), + kReadFramesTimeout); + key_verification_runner_->Run(std::move(callback)); +} + void ShareTargetInfo::OnDisconnect() { if (disconnect_status_ != TransferMetadata::Status::kUnknown) { UpdateTransferMetadata( @@ -71,5 +128,4 @@ void ShareTargetInfo::OnDisconnect() { connection_ = nullptr; } -} // namespace sharing -} // namespace nearby +} // namespace nearby::sharing diff --git a/sharing/share_target_info.h b/sharing/share_target_info.h index 84ce4529..059fe6e3 100644 --- a/sharing/share_target_info.h +++ b/sharing/share_target_info.h @@ -16,18 +16,24 @@ #define THIRD_PARTY_NEARBY_SHARING_SHARE_TARGET_INFO_H_ #include +#include #include #include #include #include +#include #include "absl/time/time.h" +#include "internal/platform/implementation/device_info.h" #include "proto/sharing_enums.pb.h" #include "sharing/attachment_container.h" +#include "sharing/certificates/nearby_share_certificate_manager.h" #include "sharing/certificates/nearby_share_decrypted_public_certificate.h" #include "sharing/incoming_frames_reader.h" +#include "sharing/internal/public/context.h" #include "sharing/nearby_connection.h" #include "sharing/nearby_connections_manager.h" +#include "sharing/nearby_sharing_decoder.h" #include "sharing/paired_key_verification_runner.h" #include "sharing/payload_tracker.h" #include "sharing/share_target.h" @@ -59,10 +65,6 @@ class ShareTargetInfo { NearbyConnection* connection() const { return connection_; } - void set_connection(NearbyConnection* connection) { - connection_ = connection; - } - void UpdateTransferMetadata(const TransferMetadata& transfer_metadata); const std::optional& token() const { return token_; } @@ -71,19 +73,6 @@ class ShareTargetInfo { IncomingFramesReader* frames_reader() const { return frames_reader_.get(); } - void set_frames_reader(std::shared_ptr frames_reader) { - frames_reader_ = std::move(frames_reader); - } - - PairedKeyVerificationRunner* key_verification_runner() { - return key_verification_runner_.get(); - } - - void set_key_verification_runner( - std::shared_ptr key_verification_runner) { - key_verification_runner_ = std::move(key_verification_runner); - } - std::weak_ptr payload_tracker() const { return payload_tracker_->GetWeakPtr(); @@ -101,11 +90,6 @@ class ShareTargetInfo { return connection_start_time_; } - void set_connection_start_time( - std::optional connection_start_time) { - connection_start_time_ = connection_start_time; - } - ::location::nearby::proto::sharing::OSType os_type() const { return os_type_; } @@ -126,6 +110,20 @@ class ShareTargetInfo { TransferMetadata::Status disconnect_status() const { return disconnect_status_; } + // Notifies the ShareTargetInfo that the connection has been established. + // Returns true if the connection was successfully established. + bool OnConnected(absl::Time connect_start_time, NearbyConnection* connection); + + void RunPairedKeyVerification( + Context* context, NearbySharingDecoder* decoder, + nearby::api::DeviceInfo::OsType os_type, + const PairedKeyVerificationRunner::VisibilityHistory& visibility_history, + NearbyShareCertificateManager* certificate_manager, + std::optional> token, + std::function< + void(PairedKeyVerificationRunner::PairedKeyVerificationResult, + location::nearby::proto::sharing::OSType)> + callback); void OnDisconnect(); void SetAttachmentContainer(AttachmentContainer container) { @@ -142,6 +140,7 @@ class ShareTargetInfo { protected: virtual void InvokeTransferUpdateCallback( const TransferMetadata& metadata) = 0; + virtual bool OnNewConnection(NearbyConnection* connection) = 0; private: std::string endpoint_id_; diff --git a/sharing/share_target_info_test.cc b/sharing/share_target_info_test.cc index 920f6a74..44d1bee3 100644 --- a/sharing/share_target_info_test.cc +++ b/sharing/share_target_info_test.cc @@ -14,12 +14,24 @@ #include "sharing/share_target_info.h" +#include #include #include #include +#include #include "gtest/gtest.h" #include "absl/strings/string_view.h" +#include "absl/synchronization/notification.h" +#include "absl/time/clock.h" +#include "absl/time/time.h" +#include "internal/platform/implementation/device_info.h" +#include "sharing/certificates/fake_nearby_share_certificate_manager.h" +#include "sharing/fake_nearby_connection.h" +#include "sharing/internal/test/fake_context.h" +#include "sharing/nearby_connection.h" +#include "sharing/nearby_sharing_decoder_impl.h" +#include "sharing/paired_key_verification_runner.h" #include "sharing/share_target.h" #include "sharing/transfer_metadata.h" #include "sharing/transfer_metadata_builder.h" @@ -46,6 +58,10 @@ class TestShareTargetInfo : public ShareTargetInfo { return last_transfer_metadata_; } + void SetOnNewConnectionResult(bool result) { + on_new_connection_result_ = result; + } + protected: void InvokeTransferUpdateCallback( const TransferMetadata& metadata) override { @@ -53,10 +69,17 @@ class TestShareTargetInfo : public ShareTargetInfo { last_transfer_metadata_ = metadata; } + bool OnNewConnection(NearbyConnection* connection) override { + connection_ = connection; + return on_new_connection_result_; + } + private: const bool is_incoming_; int transfer_update_count_ = 0; std::optional last_transfer_metadata_; + NearbyConnection* connection_ = nullptr; + bool on_new_connection_result_ = true; }; TEST(ShareTargetInfoTest, UpdateTransferMetadata) { @@ -99,6 +122,96 @@ TEST(ShareTargetInfoTest, SetDisconnectStatus) { EXPECT_EQ(info.disconnect_status(), TransferMetadata::Status::kCancelled); } +TEST(ShareTargetInfoTest, OnConnectedFails) { + ShareTarget share_target; + TestShareTargetInfo info(std::string(kEndpointId), share_target); + info.SetOnNewConnectionResult(false); + + EXPECT_FALSE(info.OnConnected(absl::Now(), nullptr)); +} + +TEST(ShareTargetInfoTest, OnConnectedSucceeds) { + ShareTarget share_target; + TestShareTargetInfo info(std::string(kEndpointId), share_target); + FakeNearbyConnection connection; + info.SetOnNewConnectionResult(true); + absl::Time connect_start_time = absl::Now(); + FakeContext context; + + EXPECT_TRUE(info.OnConnected(connect_start_time, &connection)); + EXPECT_EQ(info.connection_start_time(), connect_start_time); + EXPECT_EQ(info.connection(), &connection); +} + +TEST(ShareTargetInfoTest, IncomingRunPairedKeyVerificationSuccess) { + FakeContext context; + NearbySharingDecoderImpl nearby_sharing_decoder; + FakeNearbyShareCertificateManager certificate_manager; + FakeNearbyConnection connection; + std::optional> token = + std::vector{0, 1, 2, 3, 4, 5}; + ShareTarget share_target; + share_target.is_incoming = true; + TestShareTargetInfo info(std::string(kEndpointId), share_target); + info.SetOnNewConnectionResult(true); + absl::Time connect_start_time = absl::Now(); + EXPECT_TRUE(info.OnConnected(connect_start_time, &connection)); + absl::Notification notification; + PairedKeyVerificationRunner::PairedKeyVerificationResult verification_result; + + info.RunPairedKeyVerification( + &context, &nearby_sharing_decoder, + nearby::api::DeviceInfo::OsType::kWindows, + { + .visibility = proto::DeviceVisibility::DEVICE_VISIBILITY_EVERYONE, + .last_visibility = + proto::DeviceVisibility::DEVICE_VISIBILITY_EVERYONE, + .last_visibility_time = absl::Now(), + }, + &certificate_manager, token, + [¬ification, &verification_result]( + PairedKeyVerificationRunner::PairedKeyVerificationResult result, + location::nearby::proto::sharing::OSType) { + verification_result = result; + notification.Notify(); + }); + // Receive PairedKeyEncryptionFrame from remote device. + // This will fail verification. + nearby::sharing::service::proto::Frame in_encryption_frame; + in_encryption_frame.set_version(nearby::sharing::service::proto::Frame::V1); + in_encryption_frame.mutable_v1()->set_type( + nearby::sharing::service::proto::V1Frame::PAIRED_KEY_ENCRYPTION); + in_encryption_frame.mutable_v1() + ->mutable_paired_key_encryption() + ->set_signed_data("signed_data"); + std::string in_encryption_buffer = in_encryption_frame.SerializeAsString(); + connection.AppendReadableData( + std::vector(in_encryption_buffer.begin(), + in_encryption_buffer.end())); + // Receive PairedKeyResultFrame from remote device. + nearby::sharing::service::proto::Frame in_result_frame; + in_result_frame.set_version(nearby::sharing::service::proto::Frame::V1); + in_result_frame.mutable_v1()->set_type( + nearby::sharing::service::proto::V1Frame::PAIRED_KEY_RESULT); + in_result_frame.mutable_v1()->mutable_paired_key_result()->set_status( + nearby::sharing::service::proto::PairedKeyResultFrame::SUCCESS); + std::string in_result_buffer = in_result_frame.SerializeAsString(); + connection.AppendReadableData( + std::vector(in_result_buffer.begin(), in_result_buffer.end())); + + // Check that PairedKeyEncryptionFrame is sent. + std::vector data = connection.GetWrittenData(); + nearby::sharing::service::proto::Frame out_encryption_frame; + ASSERT_TRUE(out_encryption_frame.ParseFromArray(data.data(), data.size())); + ASSERT_TRUE(out_encryption_frame.has_v1()); + ASSERT_TRUE(out_encryption_frame.v1().has_paired_key_encryption()); + + EXPECT_TRUE(notification.WaitForNotificationWithTimeout(absl::Seconds(1))); + // Remote PairedKeyEncryptionFrame failed verification. + EXPECT_EQ(verification_result, + PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable); +} + TEST(ShareTargetInfoTest, OnDisconnect) { ShareTarget share_target; TestShareTargetInfo info(std::string(kEndpointId), share_target);