Add de-duplicate in NearbySharing based on device_id matching.

PiperOrigin-RevId: 677910987
This commit is contained in:
Suet-Fei Li
2024-09-23 13:10:56 -07:00
committed by Copybara-Service
parent 42c1ad3173
commit bdca4aa707
9 changed files with 396 additions and 51 deletions
+4 -2
View File
@@ -19,7 +19,7 @@ cc_library(
hdrs = ["nearby_connections_types.h"],
deps = [
"//internal/base:files",
"//internal/crypto_cros",
"//internal/crypto_cros", # buildcleaner: keep
"//internal/interop:authentication_status",
"//sharing/common:compatible_u8_string",
"@com_google_absl//absl/random",
@@ -336,7 +336,6 @@ cc_library(
"@com_google_absl//absl/hash",
"@com_google_absl//absl/meta:type_traits",
"@com_google_absl//absl/random",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
@@ -806,9 +805,12 @@ cc_test(
":transfer_metadata_matchers",
":types",
"//internal/analytics:mock_event_logger",
"//internal/network:url",
"//internal/platform/implementation/g3", # fixdeps: keep
"//internal/test",
"//sharing/analytics",
"//sharing/certificates:test_support",
"//sharing/common:enum",
"//sharing/proto:wire_format_cc_proto",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/strings:string_view",
@@ -94,6 +94,9 @@ constexpr auto kShowAdminModeWarning =
// Update track
constexpr auto kUpdateTrack =
flags::Flag<absl::string_view>(kConfigPackage, "45409861", "");
// Apply endpoints de-duplication algorithms.
constexpr auto kApplyEndpointsDedup =
flags::Flag<bool>(kConfigPackage, "45656298", false);
inline absl::btree_map<int, const flags::Flag<bool>&> GetBoolFlags() {
return {
@@ -115,6 +118,7 @@ inline absl::btree_map<int, const flags::Flag<bool>&> GetBoolFlags() {
{45630055, kUseGrpcClient},
{45417647, kEnableQrCodeUi},
{45410558, kShowAdminModeWarning},
{45656298, kApplyEndpointsDedup},
};
}
+132 -46
View File
@@ -1351,12 +1351,11 @@ void NearbySharingServiceImpl::OnPrivateCertificatesChanged() {
}
void NearbySharingServiceImpl::OnLoginSucceeded(absl::string_view account_id) {
RunOnNearbySharingServiceThread(
"on_login_succeeded", [this]() {
NL_LOG(INFO) << __func__ << ": Account login.";
RunOnNearbySharingServiceThread("on_login_succeeded", [this]() {
NL_LOG(INFO) << __func__ << ": Account login.";
ResetAllSettings(/*logout=*/false);
});
ResetAllSettings(/*logout=*/false);
});
}
void NearbySharingServiceImpl::OnLogoutSucceeded(absl::string_view account_id,
@@ -1683,12 +1682,18 @@ void NearbySharingServiceImpl::HandleEndpointDiscovered(
// found one.
// Looking for the ShareTarget based on endpoint id.
if (outgoing_share_target_map_.find(endpoint_id) !=
outgoing_share_target_map_.end()) {
FinishEndpointDiscoveryEvent();
return;
if (!NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_sharing_feature::
kApplyEndpointsDedup)) {
if (outgoing_share_target_map_.find(endpoint_id) !=
outgoing_share_target_map_.end()) {
LOG(INFO) << __func__ << ": Ignoring endpoint_id: " << endpoint_id
<< " because it is already in the "
<< "outgoingShareTargetMap.";
FinishEndpointDiscoveryEvent();
return;
}
}
// Once we get the advertisement, the first thing to do is decrypt the
// certificate.
NearbyShareEncryptedMetadataKey encrypted_metadata_key(
@@ -1707,7 +1712,7 @@ void NearbySharingServiceImpl::HandleEndpointDiscovered(
"outgoing_decrypted_certificate",
[this, endpoint_id_copy, endpoint_info_copy, advertisement_copy,
decrypted_public_certificate]() {
NL_LOG(INFO) << __func__ << ": Decrypted public certificate";
LOG(INFO) << __func__ << ": Decrypted public certificate";
OnOutgoingDecryptedCertificate(
endpoint_id_copy, endpoint_info_copy, advertisement_copy,
decrypted_public_certificate);
@@ -1749,11 +1754,18 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate(
absl::string_view endpoint_id, absl::Span<const uint8_t> endpoint_info,
const Advertisement& advertisement,
std::optional<NearbyShareDecryptedPublicCertificate> certificate) {
// Check again for this endpoint id, to avoid race conditions.
if (outgoing_share_target_map_.find(endpoint_id) !=
outgoing_share_target_map_.end()) {
FinishEndpointDiscoveryEvent();
return;
bool apply_endpoints_dedup = NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_sharing_feature::kApplyEndpointsDedup);
if (!apply_endpoints_dedup) {
// Check again for this endpoint id, to avoid race conditions.
if (outgoing_share_target_map_.find(endpoint_id) !=
outgoing_share_target_map_.end()) {
LOG(INFO) << __func__ << ": Ignoring endpoint_id: " << endpoint_id
<< " because it is already in the "
<< "outgoingShareTargetMap.";
FinishEndpointDiscoveryEvent();
return;
}
}
// The certificate provides the device name, in order to create a ShareTarget
@@ -1763,7 +1775,7 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate(
/*is_incoming=*/false);
if (!share_target.has_value()) {
if (discovered_advertisements_retried_set_.contains(endpoint_id)) {
NL_LOG(INFO)
LOG(INFO)
<< __func__
<< ": Don't try to download public certificates again for endpoint="
<< endpoint_id;
@@ -1771,9 +1783,10 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate(
return;
}
NL_LOG(INFO)
<< __func__ << ": Failed to convert discovered advertisement to share "
<< "target. Ignoring endpoint until next certificate download.";
LOG(INFO) << __func__
<< ": Failed to convert discovered advertisement to share "
<< "target. Ignoring endpoint: " << endpoint_id
<< " until next certificate download.";
std::vector<uint8_t> endpoint_info_data(endpoint_info.begin(),
endpoint_info.end());
@@ -1781,13 +1794,23 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate(
FinishEndpointDiscoveryEvent();
return;
}
if (apply_endpoints_dedup) {
if (FindDuplicateInOutgoingShareTargets(endpoint_id, *share_target)) {
DeduplicateInOutgoingShareTarget(*share_target, endpoint_id,
std::move(certificate));
FinishEndpointDiscoveryEvent();
return;
}
}
CreateOutgoingShareSession(*share_target, endpoint_id,
std::move(certificate));
// Update the endpoint id for the share target.
NL_LOG(INFO) << __func__
<< ": An endpoint has been discovered, with an advertisement "
"containing a valid share target.";
LOG(INFO) << __func__ << ": An endpoint: " << endpoint_id
<< " has been discovered, with an advertisement "
"containing a valid share target with id: "
<< share_target->id;
// Log analytics event of discovering share target.
analytics_recorder_->NewDiscoverShareTarget(
@@ -1802,10 +1825,10 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate(
share_foreground_send_surface_start_timestamp_));
// Notifies the user that we discovered a device.
NL_VLOG(1) << __func__ << ": There are "
<< (foreground_send_surface_map_.size() +
background_send_surface_map_.size())
<< " discovery callbacks be called.";
VLOG(1) << __func__ << ": There are "
<< (foreground_send_surface_map_.size() +
background_send_surface_map_.size())
<< " discovery callbacks be called.";
for (auto& entry : foreground_send_surface_map_) {
entry.second.OnShareTargetDiscovered(*share_target);
@@ -1814,8 +1837,8 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate(
entry.second.OnShareTargetDiscovered(*share_target);
}
NL_VLOG(1) << __func__ << ": Reported OnShareTargetDiscovered "
<< (context_->GetClock()->Now() - scanning_start_timestamp_);
VLOG(1) << __func__ << ": Reported OnShareTargetDiscovered at timestamp: "
<< (context_->GetClock()->Now() - scanning_start_timestamp_);
FinishEndpointDiscoveryEvent();
}
@@ -2356,9 +2379,9 @@ void NearbySharingServiceImpl::RemoveOutgoingShareTargetWithEndpointId(
return;
}
NL_VLOG(1) << __func__ << ": Removing (endpoint_id=" << it->first
<< ", share_target.id=" << it->second.id
<< ") from outgoing share target map";
LOG(INFO) << __func__ << ": Removing (endpoint_id=" << it->first
<< ", share_target.id=" << it->second.id
<< ") from outgoing share target map";
ShareTarget share_target = std::move(it->second);
outgoing_share_target_map_.erase(it);
@@ -2597,10 +2620,9 @@ void NearbySharingServiceImpl::OnIncomingAdvertisementDecoded(
placeholder_share_target_id,
decrypted_public_certificate =
std::move(decrypted_public_certificate)]() {
OnIncomingDecryptedCertificate(
endpoint_id, advertisement_copy,
placeholder_share_target_id,
decrypted_public_certificate);
OnIncomingDecryptedCertificate(endpoint_id, advertisement_copy,
placeholder_share_target_id,
decrypted_public_certificate);
});
});
}
@@ -2698,7 +2720,7 @@ void NearbySharingServiceImpl::OnOutgoingTransferUpdate(
is_connecting_ = false;
OnTransferComplete();
} else if (metadata.status() ==
TransferMetadata::Status::kAwaitingLocalConfirmation) {
TransferMetadata::Status::kAwaitingLocalConfirmation) {
is_connecting_ = false;
OnTransferStarted(/*is_incoming=*/false);
}
@@ -3264,18 +3286,82 @@ IncomingShareSession& NearbySharingServiceImpl::CreateIncomingShareSession(
return it->second;
}
void NearbySharingServiceImpl::DeduplicateInOutgoingShareTarget(
const ShareTarget& share_target, absl::string_view endpoint_id,
std::optional<NearbyShareDecryptedPublicCertificate> certificate) {
// TODO(b/343764269): may need to update last_outgoing_metadata_ if the
// deduped target id matches the one in last_outgoing_metadata_.
// But since we do not modify the share target of a connected session, it may
// not happen.
auto session_it = outgoing_share_session_map_.find(share_target.id);
if (session_it == outgoing_share_session_map_.end()) {
LOG(WARNING) << __func__ << ": share_target.id=" << share_target.id
<< " not found in outgoing share session map.";
return;
}
if (session_it->second.IsConnected()) {
LOG(INFO) << __func__ << ": share_target.id=" << share_target.id
<< " is connected, not updating outgoing_share_session_map_.";
return;
}
session_it->second.UpdateSessionForDedup(share_target, std::move(certificate),
endpoint_id);
for (auto& entry : foreground_send_surface_map_) {
entry.second.OnShareTargetUpdated(share_target);
}
for (auto& entry : background_send_surface_map_) {
entry.second.OnShareTargetUpdated(share_target);
}
LOG(INFO) << __func__
<< ": [Dedupped] Reported OnShareTargetUpdated to all surfaces "
"for share_target: "
<< share_target.ToString();
}
bool NearbySharingServiceImpl::FindDuplicateInOutgoingShareTargets(
absl::string_view endpoint_id, ShareTarget& share_target) {
// If the duplicate is found, share_target.id needs to be updated to the old
// "discovered" share_target_id so OnShareTargetUpdated matches a target that
// was discovered before.
auto it = outgoing_share_target_map_.find(endpoint_id);
if (it != outgoing_share_target_map_.end()) {
// If endpoint info changes for an endpoint ID, NC will send a rediscovery
// event for the same endpoint id.
LOG(INFO) << __func__
<< ": [Dedupped] Found duplicate endpoint_id: " << endpoint_id
<< " in outgoing_share_target_map, share_target.id changed from: "
<< share_target.id << " to " << it->second.id;
share_target.id = it->second.id;
it->second = share_target;
return true;
}
for (auto it = outgoing_share_target_map_.begin();
it != outgoing_share_target_map_.end(); ++it) {
if (it->second.device_id == share_target.device_id) {
LOG(INFO)
<< __func__
<< ": [Dedupped] Found duplicate device_id. endpoint ID "
"changed from: "
<< it->first << " to " << endpoint_id
<< " in outgoing_share_target_map, share_target.id changed from: "
<< share_target.id << " to " << it->second.id;
share_target.id = it->second.id;
outgoing_share_target_map_.erase(it);
outgoing_share_target_map_.insert_or_assign(endpoint_id, share_target);
return true;
}
}
return false;
}
OutgoingShareSession& NearbySharingServiceImpl::CreateOutgoingShareSession(
const ShareTarget& share_target, absl::string_view endpoint_id,
std::optional<NearbyShareDecryptedPublicCertificate> 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";
+12
View File
@@ -369,6 +369,18 @@ class NearbySharingServiceImpl
const ShareTarget& share_target, absl::string_view endpoint_id,
std::optional<NearbyShareDecryptedPublicCertificate> certificate);
// The share_target's id is updated to match the old one
// and OnShareTargetUpdated is called.
void DeduplicateInOutgoingShareTarget(
const ShareTarget& share_target, absl::string_view endpoint_id,
std::optional<NearbyShareDecryptedPublicCertificate> certificate);
// Looks for a duplicate of the given share target in the outgoing share
// target map. The share target's id is changed to match an existing target if
// available. Returns true if the duplicate is found.
bool FindDuplicateInOutgoingShareTargets(absl::string_view endpoint_id,
ShareTarget& share_target);
ShareSession* GetShareSession(int64_t share_target_id);
IncomingShareSession* GetIncomingShareSession(int64_t share_target_id);
OutgoingShareSession* GetOutgoingShareSession(int64_t share_target_id);
+168
View File
@@ -112,10 +112,12 @@ using ::nearby::sharing::service::proto::IntroductionFrame;
using ::nearby::sharing::service::proto::PairedKeyResultFrame;
using ::nearby::sharing::service::proto::TextMetadata;
using ::nearby::sharing::service::proto::V1Frame;
using ::testing::_;
using ::testing::InSequence;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SaveArg;
using ::testing::StrictMock;
using ::testing::UnorderedElementsAre;
@@ -391,6 +393,7 @@ class NearbySharingServiceImplTest : public testing::Test {
nullptr);
NearbyShareContactManagerImpl::Factory::SetFactoryForTesting(nullptr);
NearbyShareCertificateManagerImpl::Factory::SetFactoryForTesting(nullptr);
NearbyFlags::GetInstance().ResetOverridedValues();
nearby_fast_initiation_factory_.reset();
}
@@ -4063,8 +4066,59 @@ TEST_F(NearbySharingServiceImplTest,
service_.reset();
}
TEST_F(NearbySharingServiceImplTest, DedupSameEndpointId) {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_sharing_feature::kApplyEndpointsDedup,
true);
// Start discovery.
SetConnectionType(ConnectionType::kWifi);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground);
EXPECT_EQ(certificate_manager()->num_download_public_certificates_calls(),
1u);
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
{
absl::Notification notification;
// vendor_id is default to 0.
FindEndpoint(/*endpoint_id=*/"1");
FindEndpointWithVendorId(
/*endpoint_id=*/"1",
static_cast<uint8_t>(Advertisement::BlockedVendorId::kSamsung));
::testing::InSequence s;
ShareTarget share_target_1;
ShareTarget share_target_2;
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered(_))
.WillOnce(SaveArg<0>(&share_target_1));
EXPECT_CALL(discovery_callback, OnShareTargetUpdated(_))
.WillOnce([&](ShareTarget share_target) {
share_target_2 = share_target;
notification.Notify();
});
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/2,
/*success=*/true);
EXPECT_EQ(share_target_1.id, share_target_2.id);
// Vendor_id updated.
EXPECT_EQ(share_target_1.vendor_id, 0);
EXPECT_EQ(share_target_2.vendor_id,
static_cast<uint8_t>(Advertisement::BlockedVendorId::kSamsung));
EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
}
Shutdown();
service_.reset();
}
TEST_F(NearbySharingServiceImplTest,
RetryDiscoveredEndpointsDownloadCertsAndRetryDecryption) {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_sharing_feature::kApplyEndpointsDedup,
false);
// Start discovery.
SetConnectionType(ConnectionType::kWifi);
MockTransferUpdateCallback transfer_callback;
@@ -4125,6 +4179,120 @@ TEST_F(NearbySharingServiceImplTest,
service_.reset();
}
// This test verifies the de-dup logic. Since certificates are the same, all the
// share targets are duplicates.
TEST_F(NearbySharingServiceImplTest, EndpointDedupBAsedOnDeviceId) {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_sharing_feature::kApplyEndpointsDedup,
true);
// Start discovery.
SetConnectionType(ConnectionType::kWifi);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground);
EXPECT_EQ(certificate_manager()->num_download_public_certificates_calls(),
1u);
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
// Order of events:
// - Discover endpoint 1 --> decrypts public certificate
// - Discover endpoint 2 --> cannot decrypt public certificate
// - Discover endpoint 3 --> decrypts public certificate
// --> De-dup endpoint 1 with endpoint 3
// - Discover endpoint 4 --> cannot decrypt public certificate
// - Lose endpoint 3 --> endpoint 3 is purged from map
// ----------------------------------------------------------------
// - Fire certificate download timer --> certificates downloaded
// - (Re)discover endpoints 2 --> endpoint 2 is insert into map
// - (Re)discover endpoints 4 --> De-dup endpoint 2 with endpoint 4
{
absl::Notification notification;
// vendor_id is default to 0.
FindEndpoint(/*endpoint_id=*/"1");
FindInvalidEndpoint(/*endpoint_id=*/"2");
FindEndpointWithVendorId(
/*endpoint_id=*/"3",
static_cast<uint8_t>(Advertisement::BlockedVendorId::kSamsung));
FindInvalidEndpoint(/*endpoint_id=*/"4");
LoseEndpoint(/*endpoint_id=*/"3");
::testing::InSequence s;
ShareTarget share_target_ep_1;
ShareTarget share_target_ep_3;
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered(_))
.WillOnce(SaveArg<0>(&share_target_ep_1));
// Update endpoint 1 to endpoint 3
EXPECT_CALL(discovery_callback, OnShareTargetUpdated(_))
.WillOnce(SaveArg<0>(&share_target_ep_3));
// Lost endpoint 3
EXPECT_CALL(discovery_callback, OnShareTargetLost)
.WillOnce([&](ShareTarget share_target) { notification.Notify(); });
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/2,
/*success=*/false);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/3,
/*success=*/true);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/4,
/*success=*/false);
EXPECT_EQ(share_target_ep_1.id, share_target_ep_3.id);
// Vendor_id updated.
EXPECT_EQ(share_target_ep_3.vendor_id,
static_cast<uint8_t>(Advertisement::BlockedVendorId::kSamsung));
EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
}
FastForward(kCertificateDownloadDuringDiscoveryPeriod);
EXPECT_EQ(certificate_manager()->num_download_public_certificates_calls(),
2u);
certificate_manager()->NotifyPublicCertificatesDownloaded();
FlushTesting();
ShareTarget share_target_ep_4;
{
absl::Notification notification;
::testing::InSequence s;
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered);
// Update endpoint 2 to endpoint 4
EXPECT_CALL(discovery_callback, OnShareTargetUpdated)
.WillOnce([&](ShareTarget share_target) {
share_target_ep_4 = share_target;
notification.Notify();
});
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/5,
/*success=*/true);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/6,
/*success=*/true);
EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
}
EXPECT_CALL(discovery_callback, OnShareTargetLost).Times(1);
// Introduce a small delay for things to settle.
FastForward(absl::Seconds(1));
// Send Text to updated endpoint 4.
SetUpKeyVerification(
/*is_incoming=*/false, PairedKeyResultFrame::SUCCESS);
fake_nearby_connections_manager_->SetRawAuthenticationToken(
/*endpoint_id=*/"4", GetToken());
fake_nearby_connections_manager_->set_nearby_connection(connection_.get());
SetUpOutgoingConnectionUntilAccept(transfer_callback, share_target_ep_4.id);
PayloadInfo info =
AcceptAndSendPayload(transfer_callback, share_target_ep_4.id);
FinishOutgoingTransfer(transfer_callback, share_target_ep_4.id,
/*complete=*/true, info);
EXPECT_TRUE(fake_nearby_connections_manager_
->connection_endpoint_info(/*endpoint_id=*/"4")
.has_value());
Shutdown();
service_.reset();
}
TEST_F(NearbySharingServiceImplTest,
RetryDiscoveredEndpointsDiscoveryRestartClearsCache) {
// Start discovery.
+14
View File
@@ -29,6 +29,7 @@
#include "internal/platform/task_runner.h"
#include "sharing/analytics/analytics_recorder.h"
#include "sharing/attachment_container.h"
#include "sharing/certificates/nearby_share_decrypted_public_certificate.h"
#include "sharing/constants.h"
#include "sharing/file_attachment.h"
#include "sharing/internal/public/logging.h"
@@ -462,4 +463,17 @@ void OutgoingShareSession::DisconnectionTimeout() {
Disconnect();
}
void OutgoingShareSession::UpdateSessionForDedup(
const ShareTarget& share_target,
std::optional<NearbyShareDecryptedPublicCertificate> certificate,
absl::string_view endpoint_id) {
if (IsConnected()) return;
set_share_target(share_target);
set_endpoint_id(endpoint_id);
if (certificate.has_value()) {
set_certificate(std::move(certificate.value()));
} else {
clear_certificate();
}
}
} // namespace nearby::sharing
+7
View File
@@ -24,9 +24,11 @@
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "internal/platform/clock.h"
#include "internal/platform/task_runner.h"
#include "sharing/analytics/analytics_recorder.h"
#include "sharing/certificates/nearby_share_decrypted_public_certificate.h"
#include "sharing/nearby_connection.h"
#include "sharing/nearby_connections_types.h"
#include "sharing/nearby_file_handler.h"
@@ -129,6 +131,11 @@ class OutgoingShareSession : public ShareSession {
void DelayCompleteMetadata(const TransferMetadata& complete_metadata);
// Disconnect timeout expired without receiving client disconnect.
void DisconnectionTimeout();
// Used only for OutgoingShareSession De-duplication.
void UpdateSessionForDedup(
const ShareTarget& share_target,
std::optional<NearbyShareDecryptedPublicCertificate> certificate,
absl::string_view endpoint_id);
protected:
void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override;
+46 -2
View File
@@ -29,10 +29,13 @@
#include "absl/time/time.h"
#include "internal/analytics/mock_event_logger.h"
#include "internal/analytics/sharing_log_matchers.h"
#include "internal/network/url.h"
#include "internal/test/fake_clock.h"
#include "internal/test/fake_task_runner.h"
#include "sharing/analytics/analytics_recorder.h"
#include "sharing/attachment_container.h"
#include "sharing/certificates/test_util.h"
#include "sharing/common/nearby_share_enums.h"
#include "sharing/fake_nearby_connection.h"
#include "sharing/fake_nearby_connections_manager.h"
#include "sharing/file_attachment.h"
@@ -461,7 +464,7 @@ TEST_F(OutgoingShareSessionTest,
}
TEST_F(OutgoingShareSessionTest,
HandleConnectionResponseUnsuportedTypeResponse) {
HandleConnectionResponseUnsupportedTypeResponse) {
ConnectionResponseFrame response;
response.set_status(ConnectionResponseFrame::UNSUPPORTED_ATTACHMENT_TYPE);
std::optional<TransferMetadata::Status> status =
@@ -680,7 +683,7 @@ TEST_F(OutgoingShareSessionTest, ProcessKeyVerificationResultSuccess) {
EXPECT_THAT(session_.os_type(), Eq(OSType::WINDOWS));
}
TEST_F(OutgoingShareSessionTest, DelayCompleteMetadataRecevierDisconnect) {
TEST_F(OutgoingShareSessionTest, DelayCompleteMetadataReceiverDisconnect) {
FakeNearbyConnection connection;
session_.OnConnected(absl::Now(), &connections_manager_, &connection);
TransferMetadata complete_metadata =
@@ -713,5 +716,46 @@ TEST_F(OutgoingShareSessionTest, DelayCompleteMetadataDisconnectTimeout) {
EXPECT_THAT(connection.IsClosed(), IsTrue());
}
TEST_F(OutgoingShareSessionTest, UpdateSessionForDedupWithCertificate) {
EXPECT_FALSE(session_.certificate().has_value());
EXPECT_FALSE(session_.self_share());
ShareTarget share_target2{
"test_update_name", ::nearby::network::Url(), ShareTargetType::kPhone,
/* is_incoming */ true, "test_update_full_name",
/* is_known */ true, "test_update_device_id", true};
session_.UpdateSessionForDedup(share_target2,
GetNearbyShareTestDecryptedPublicCertificate(),
"test_update_endpoint_id");
EXPECT_THAT(session_.share_target().ToString(), Eq(share_target2.ToString()));
EXPECT_TRUE(session_.certificate().has_value());
EXPECT_THAT(session_.endpoint_id(), Eq("test_update_endpoint_id"));
EXPECT_TRUE(session_.self_share());
}
TEST_F(OutgoingShareSessionTest, UpdateSessionForDedupWithoutCertificate) {
session_.set_certificate(GetNearbyShareTestDecryptedPublicCertificate());
ShareTarget share_target2{
"test_update_name", ::nearby::network::Url(), ShareTargetType::kPhone,
/* is_incoming */ true, "test_update_full_name",
/* is_known */ true, "test_update_device_id", true};
session_.UpdateSessionForDedup(share_target2, std::nullopt,
"test_update_endpoint_id");
// Certificate is cleared.
EXPECT_FALSE(session_.certificate().has_value());
}
TEST_F(OutgoingShareSessionTest, UpdateSessionForDedupConnectedIsNoOp) {
auto share_target_org = session_.share_target();
FakeNearbyConnection connection;
session_.OnConnected(absl::Now(), &connections_manager_, &connection);
ShareTarget share_target2{
"test_update_name", ::nearby::network::Url(), ShareTargetType::kPhone,
/* is_incoming */ true, "test_update_full_name",
/* is_known */ true, "test_update_device_id", true};
session_.UpdateSessionForDedup(share_target2, std::nullopt,
"test_update_endpoint_id");
EXPECT_THAT(session_.share_target().ToString(),
Eq(share_target_org.ToString()));
}
} // namespace
} // namespace nearby::sharing
+9 -1
View File
@@ -24,6 +24,7 @@
#include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "internal/platform/clock.h"
#include "internal/platform/task_runner.h"
@@ -57,7 +58,6 @@ class ShareSession {
virtual bool IsIncoming() const = 0;
std::string endpoint_id() const { return endpoint_id_; }
const std::optional<NearbyShareDecryptedPublicCertificate>& certificate()
const {
return certificate_;
@@ -66,6 +66,7 @@ class ShareSession {
void set_certificate(NearbyShareDecryptedPublicCertificate certificate) {
certificate_ = std::move(certificate);
}
void clear_certificate() { certificate_ = std::nullopt; }
NearbyConnection* connection() const { return connection_; }
bool IsConnected() const { return connection_ != nullptr; }
@@ -174,6 +175,13 @@ class ShareSession {
NearbyConnectionsManager* connections_manager() {
return connections_manager_;
}
void set_endpoint_id(absl::string_view endpoint_id) {
endpoint_id_ = std::string(endpoint_id);
}
void set_share_target(const ShareTarget& share_target) {
share_target_ = share_target;
self_share_ = share_target.for_self_share;
}
private:
TaskRunner& service_thread_;