Update save path for file sync transfers.

PiperOrigin-RevId: 927012760
This commit is contained in:
Francis Tsui
2026-06-04 19:19:16 -07:00
committed by Copybara-Service
parent d6933211d9
commit 33a6a48320
5 changed files with 304 additions and 23 deletions
+1
View File
@@ -649,6 +649,7 @@ cc_test(
":nearby_connection_impl",
":nearby_sharing_service",
":share_session",
":share_session_usage",
":test_support",
":transfer_metadata",
":transfer_metadata_matchers",
@@ -32,6 +32,7 @@
#include "internal/base/file_path.h"
#include "sharing/common/nearby_share_enums.h"
#include "sharing/internal/public/logging.h"
#include "sharing/nearby_connection.h"
#include "sharing/nearby_connections_manager.h"
#include "sharing/nearby_connections_types.h"
#include "sharing/proto/enums.pb.h"
@@ -204,6 +205,12 @@ void FakeNearbyConnectionsManager::UpgradeBandwidth(
upgrade_bandwidth_endpoint_ids_.insert(std::string(endpoint_id));
}
void FakeNearbyConnectionsManager::OverrideSavePath(
absl::string_view endpoint_id, const FilePath& custom_save_path) {
absl::MutexLock lock(endpoints_mutex_);
custom_save_paths_[endpoint_id] = custom_save_path;
}
void FakeNearbyConnectionsManager::OnEndpointFound(
absl::string_view endpoint_id,
std::unique_ptr<DiscoveredEndpointInfo> info) {
+13 -1
View File
@@ -27,6 +27,7 @@
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
@@ -76,7 +77,7 @@ class FakeNearbyConnectionsManager : public NearbyConnectionsManager {
void UpgradeBandwidth(absl::string_view endpoint_id) override;
void SetCustomSavePath(absl::string_view custom_save_path) override {}
void OverrideSavePath(absl::string_view endpoint_id,
const FilePath& custom_save_path) override {}
const FilePath& custom_save_path) override;
absl::flat_hash_set<FilePath> GetAndClearUnknownFilePathsToDelete() override;
// Testing methods
@@ -131,6 +132,14 @@ class FakeNearbyConnectionsManager : public NearbyConnectionsManager {
return it->second;
}
std::optional<FilePath> custom_save_path(absl::string_view endpoint_id) {
absl::MutexLock lock(endpoints_mutex_);
auto it = custom_save_paths_.find(endpoint_id);
if (it == custom_save_paths_.end()) return std::nullopt;
return it->second;
}
bool has_incoming_payloads() {
absl::MutexLock lock(incoming_payloads_mutex_);
return !incoming_payloads_.empty();
@@ -177,6 +186,9 @@ class FakeNearbyConnectionsManager : public NearbyConnectionsManager {
// Maps endpoint_id to endpoint_info.
std::map<std::string, std::vector<uint8_t>> connection_endpoint_infos_
ABSL_GUARDED_BY(endpoints_mutex_);
// Maps endpoint_id to custom_save_path.
absl::flat_hash_map<std::string, FilePath> custom_save_paths_
ABSL_GUARDED_BY(endpoints_mutex_);
std::map<int64_t, std::weak_ptr<PayloadStatusListener>>
payload_status_listeners_;
+22
View File
@@ -2703,6 +2703,28 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
return;
}
FilePath save_path{settings_->GetCustomSavePath()};
// If transfer is for file sync, override the save path to the custom save
// path.
if (frame.use_case() == IntroductionFrame::FILE_SYNC) {
if (!session.certificate().has_value() ||
session.certificate()->binding_id().empty()) {
LOG(ERROR) << __func__
<< ": Binding id is empty for file sync session.";
Fail(session, TransferMetadata::Status::kRejected);
return;
}
std::optional<sync::SyncBinding> binding =
sync_manager_.GetSyncBinding(session.certificate()->binding_id());
if (!binding.has_value()) {
LOG(ERROR) << __func__
<< ": Sync binding not found for binding id: "
<< session.certificate()->binding_id();
Fail(session, TransferMetadata::Status::kRejected);
return;
}
save_path = FilePath(binding->destination_directory());
session.set_session_usage(ShareSessionUsage::kFileSync);
}
// Override save path for this connection.
// This must be called before the transfer is accepted and payloads are being
// received.
+261 -22
View File
@@ -88,6 +88,7 @@
#include "sharing/proto/enums.pb.h"
#include "sharing/proto/rpc_resources.pb.h"
#include "sharing/proto/wire_format.pb.h"
#include "sharing/share_session_usage.h"
#include "sharing/share_target.h"
#include "sharing/share_target_discovered_callback.h"
#include "sharing/text_attachment.h"
@@ -273,11 +274,13 @@ std::unique_ptr<Payload> GetTextPayload(int64_t payload_id,
std::vector<uint8_t>(text.begin(), text.end()));
}
std::unique_ptr<Frame> GetValidIntroductionFrame() {
std::unique_ptr<Frame> GetValidIntroductionFrame(
IntroductionFrame::SharingUseCase use_case) {
IntroductionFrame* introduction_frame =
IntroductionFrame::default_instance().New();
auto text_metadatas = introduction_frame->mutable_text_metadata();
introduction_frame->set_start_transfer(true);
introduction_frame->set_use_case(use_case);
for (int i = 1; i <= 3; ++i) {
nearby::sharing::service::proto::TextMetadata* text_metadata =
@@ -665,10 +668,9 @@ class NearbySharingServiceImplTest : public testing::Test {
EXPECT_TRUE(fake_nearby_connections_manager_->IsAdvertising());
}
void ProcessLatestPublicCertificateDecryption(size_t expected_num_calls,
bool success,
bool for_self_share = false,
uint8_t vendor_id = 0) {
void ProcessLatestPublicCertificateDecryption(
size_t expected_num_calls, bool success, bool for_self_share = false,
uint8_t vendor_id = 0, absl::string_view binding_id = "") {
// Ensure that all pending mojo messages are processed and the certificate
// manager state is as expected up to this point.
std::vector<
@@ -688,6 +690,9 @@ class NearbySharingServiceImplTest : public testing::Test {
DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS,
GetNearbyShareTestNotBefore(), vendor_id);
cert.set_for_self_share(for_self_share);
if (!binding_id.empty()) {
cert.set_binding_id(binding_id);
}
std::move(calls.back().callback)(
NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
cert, GetNearbyShareTestEncryptedMetadataKey()));
@@ -744,13 +749,17 @@ class NearbySharingServiceImplTest : public testing::Test {
return advertisement->ToEndpointInfo();
}
void SetUpIntroductionFrameDecoder(bool return_empty_introduction_frame) {
std::unique_ptr<Frame> frame;
if (return_empty_introduction_frame) {
frame = GetEmptyIntroductionFrame();
} else {
frame = GetValidIntroductionFrame();
}
void SetUpEmptyIntroductionFrameDecoder() {
std::unique_ptr<Frame> frame = GetEmptyIntroductionFrame();
std::vector<uint8_t> bytes(frame->ByteSizeLong());
frame->SerializeToArray(bytes.data(), bytes.size());
ReceiveMessageFromConnection(std::move(bytes));
}
void SetUpIntroductionFrameDecoder(
IntroductionFrame::SharingUseCase use_case =
IntroductionFrame::NEARBY_SHARE) {
std::unique_ptr<Frame> frame = GetValidIntroductionFrame(use_case);
std::vector<uint8_t> bytes(frame->ByteSizeLong());
frame->SerializeToArray(bytes.data(), bytes.size());
ReceiveMessageFromConnection(std::move(bytes));
@@ -775,7 +784,7 @@ class NearbySharingServiceImplTest : public testing::Test {
bool for_self_share = false) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
GetToken());
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
SetUpIntroductionFrameDecoder();
int64_t share_target_id;
SetLanConnected(true);
@@ -2375,7 +2384,7 @@ TEST_F(NearbySharingServiceImplTest,
TEST_F(NearbySharingServiceImplTest, IncomingConnectionEmptyIntroductionFrame) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
GetToken());
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/true);
SetUpEmptyIntroductionFrameDecoder();
SetLanConnected(true);
NiceMock<MockTransferUpdateCallback> callback;
@@ -2414,7 +2423,7 @@ TEST_F(NearbySharingServiceImplTest,
IncomingConnectionValidIntroductionFrameInvalidCertificate) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
GetToken());
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
SetUpIntroductionFrameDecoder();
SetLanConnected(true);
NiceMock<MockTransferUpdateCallback> callback;
@@ -2464,6 +2473,7 @@ TEST_F(NearbySharingServiceImplTest, IncomingConnectionTimedOut) {
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_TRUE(metadata.is_final_status());
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing);
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kTimedOut);
});
@@ -2487,6 +2497,7 @@ TEST_F(NearbySharingServiceImplTest,
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_TRUE(metadata.is_final_status());
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing);
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kFailed);
});
@@ -2614,7 +2625,7 @@ TEST_F(NearbySharingServiceImplTest,
IncomingConnectionValidIntroductionFrameValidCertificate) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
GetToken());
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
SetUpIntroductionFrameDecoder();
SetLanConnected(true);
NiceMock<MockTransferUpdateCallback> callback;
@@ -2655,6 +2666,128 @@ TEST_F(NearbySharingServiceImplTest,
.has_value());
}
TEST_F(NearbySharingServiceImplTest,
IncomingConnectionValidIntroductionFrameValidCertificateFileSync) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
GetToken());
SetUpIntroductionFrameDecoder(IntroductionFrame::FILE_SYNC);
constexpr absl::string_view kBindingId = "binding_id";
sync::SyncBinding binding;
binding.set_binding_id(kBindingId);
binding.set_source_name(kDeviceName);
binding.set_destination_directory(
FilePath("Downloads").append(FilePath(kDeviceName)).ToString());
binding.set_source_device_type(sync::SyncBinding::SOURCE_DEVICE_TYPE_PHONE);
service_->sync_manager().AddSyncBinding(binding);
SetLanConnected(true);
NiceMock<MockTransferUpdateCallback> callback;
absl::Notification notification;
EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_, testing::_))
.WillOnce([&notification](const ShareTarget& share_target,
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_FALSE(metadata.is_final_status());
EXPECT_EQ(TransferMetadata::Status::kAwaitingLocalConfirmation,
metadata.status());
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kFileSync);
EXPECT_TRUE(share_target.is_incoming);
EXPECT_TRUE(share_target.is_known);
EXPECT_TRUE(container.HasAttachments());
EXPECT_EQ(container.GetTextAttachments().size(), 3u);
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
EXPECT_EQ(share_target.device_name, kDeviceName);
EXPECT_EQ(share_target.type, kDeviceType);
EXPECT_NE(share_target.device_id, kEndpointId);
EXPECT_EQ(share_target.full_name, kTestMetadataFullName);
EXPECT_FALSE(share_target.for_self_share);
EXPECT_FALSE(metadata.is_self_share());
EXPECT_TRUE(metadata.token().has_value());
notification.Notify();
});
SetUpKeyVerification(/*is_incoming=*/true, PairedKeyResultFrame::SUCCESS);
SetUpForegroundReceiveSurface(callback);
ScopedReceiveSurface r(service_.get(), &callback);
EXPECT_CALL(*mock_app_info_, SetActiveFlag());
StartIncomingConnection();
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true,
/*for_self_share=*/false,
/*vendor_id=*/0, kBindingId);
EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
EXPECT_TRUE(
fake_nearby_connections_manager_->connection_endpoint_info(kEndpointId)
.has_value());
ASSERT_TRUE(fake_nearby_connections_manager_->custom_save_path(kEndpointId)
.has_value());
EXPECT_EQ(fake_nearby_connections_manager_->custom_save_path(kEndpointId)
->ToString(),
binding.destination_directory());
}
TEST_F(NearbySharingServiceImplTest,
IncomingIntroductionFrameCertificateEmptyBindingId) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
GetToken());
SetUpIntroductionFrameDecoder(IntroductionFrame::FILE_SYNC);
SetLanConnected(true);
NiceMock<MockTransferUpdateCallback> callback;
absl::Notification notification;
EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_, testing::_))
.WillOnce([&notification](const ShareTarget& share_target,
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_EQ(TransferMetadata::Status::kRejected, metadata.status());
notification.Notify();
});
SetUpKeyVerification(/*is_incoming=*/true, PairedKeyResultFrame::SUCCESS);
SetUpForegroundReceiveSurface(callback);
ScopedReceiveSurface r(service_.get(), &callback);
EXPECT_CALL(*mock_app_info_, SetActiveFlag());
StartIncomingConnection();
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true,
/*for_self_share=*/false,
/*vendor_id=*/0, /*binding_id=*/"");
EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
}
TEST_F(NearbySharingServiceImplTest,
IncomingIntroductionFrameFileSyncBindingNotFound) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
GetToken());
SetUpIntroductionFrameDecoder(IntroductionFrame::FILE_SYNC);
constexpr absl::string_view kBindingId = "binding_id";
SetLanConnected(true);
NiceMock<MockTransferUpdateCallback> callback;
absl::Notification notification;
EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_, testing::_))
.WillOnce([&notification](const ShareTarget& share_target,
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_EQ(TransferMetadata::Status::kRejected, metadata.status());
notification.Notify();
});
SetUpKeyVerification(/*is_incoming=*/true, PairedKeyResultFrame::SUCCESS);
SetUpForegroundReceiveSurface(callback);
ScopedReceiveSurface r(service_.get(), &callback);
EXPECT_CALL(*mock_app_info_, SetActiveFlag());
StartIncomingConnection();
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true,
/*for_self_share=*/false,
/*vendor_id=*/0, kBindingId);
EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
}
TEST_F(NearbySharingServiceImplTest, AcceptInvalidShareTarget) {
absl::Notification notification;
service_->Accept(
@@ -2711,6 +2844,7 @@ TEST_F(NearbySharingServiceImplTest,
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_FALSE(metadata.is_final_status());
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing);
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kInProgress);
progress_notification.Notify();
});
@@ -2785,6 +2919,7 @@ TEST_F(NearbySharingServiceImplTest, AcceptValidShareTargetPayloadFailed) {
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_TRUE(metadata.is_final_status());
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing);
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kFailed);
ASSERT_TRUE(container.HasAttachments());
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
@@ -2831,6 +2966,7 @@ TEST_F(NearbySharingServiceImplTest, AcceptValidShareTargetPayloadCancelled) {
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_TRUE(metadata.is_final_status());
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing);
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kCancelled);
ASSERT_TRUE(container.HasAttachments());
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
@@ -2883,6 +3019,7 @@ TEST_F(NearbySharingServiceImplTest, RejectValidShareTarget) {
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_TRUE(metadata.is_final_status());
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing);
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kRejected);
});
@@ -2909,7 +3046,7 @@ TEST_F(NearbySharingServiceImplTest,
IncomingConnectionKeyVerificationRunnerStatusUnable) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
GetToken());
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
SetUpIntroductionFrameDecoder();
SetLanConnected(true);
NiceMock<MockTransferUpdateCallback> callback;
@@ -2952,7 +3089,7 @@ TEST_F(NearbySharingServiceImplTest,
IncomingConnectionKeyVerificationRunnerStatusUnableLowPower) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
GetToken());
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
SetUpIntroductionFrameDecoder();
SetLanConnected(true);
NiceMock<MockTransferUpdateCallback> callback;
@@ -3654,6 +3791,7 @@ TEST_F(NearbySharingServiceImplTest, CancelReceiverInitiator) {
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_EQ(share_target.id, target_id);
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing);
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kCancelled);
});
EXPECT_FALSE(
@@ -3702,6 +3840,7 @@ TEST_F(NearbySharingServiceImplTest, CancelReceiverNoninitiator) {
const AttachmentContainer& container,
TransferMetadata metadata) {
EXPECT_EQ(target_id, share_target.id);
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kSharing);
EXPECT_EQ(TransferMetadata::Status::kCancelled, metadata.status());
notification.Notify();
});
@@ -4661,8 +4800,7 @@ TEST_F(NearbySharingServiceImplTest, LoginAndLogoutShouldResetSettings) {
ASSERT_TRUE(service_->GetAccountManager()->GetCurrentAccount().has_value());
EXPECT_EQ(service_->GetAccountManager()->GetCurrentAccount()->id,
kTestAccountId);
device_id =
preference_manager_.GetString(PrefNames::kDeviceId, "");
device_id = preference_manager_.GetString(PrefNames::kDeviceId, "");
EXPECT_FALSE(device_id.empty());
EXPECT_EQ(device_id.size(), 10u);
for (const char c : device_id) EXPECT_TRUE(std::isalnum(c));
@@ -4679,8 +4817,7 @@ TEST_F(NearbySharingServiceImplTest, LoginAndLogoutShouldResetSettings) {
EXPECT_TRUE(service_->GetSettings()->GetIsAnalyticsEnabled());
EXPECT_FALSE(service_->GetAccountManager()->GetCurrentAccount().has_value());
EXPECT_TRUE(sharing_service_task_runner_->SyncWithTimeout(kTaskWaitTimeout));
device_id =
preference_manager_.GetString(PrefNames::kDeviceId, "");
device_id = preference_manager_.GetString(PrefNames::kDeviceId, "");
EXPECT_TRUE(device_id.empty());
}
@@ -5097,5 +5234,107 @@ TEST_F(NearbySharingServiceImplTest, InitiatePairingSuccess) {
EXPECT_THAT(binding->sync_bindings(0), EqualsProto(expected_binding));
}
TEST_F(NearbySharingServiceImplTest,
InitiatePairingSuccessCheckUsageAndBindingId) {
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
int64_t target_id = SetUpOutgoingShareTarget(
transfer_callback, discovery_callback, /*for_self_share=*/true);
ScopedSendSurface s(service_.get(), &transfer_callback);
absl::Notification notification;
constexpr absl::string_view kBindingId = "binding_id";
EXPECT_CALL(transfer_callback,
OnTransferUpdate(testing::_, testing::_, testing::_))
.WillOnce([&](const ShareTarget& share_target,
const AttachmentContainer& container,
const TransferMetadata& metadata) {
EXPECT_EQ(share_target.id, target_id);
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kConnecting);
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kUnknown);
EXPECT_TRUE(metadata.binding_id().empty());
})
.WillOnce([&](const ShareTarget& share_target,
const AttachmentContainer& container,
const TransferMetadata& metadata) {
EXPECT_EQ(share_target.id, target_id);
EXPECT_EQ(metadata.status(),
TransferMetadata::Status::kAwaitingRemoteAcceptance);
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kPairing);
EXPECT_TRUE(metadata.binding_id().empty());
})
.WillOnce([&](const ShareTarget& share_target,
const AttachmentContainer& container,
const TransferMetadata& metadata) {
EXPECT_EQ(share_target.id, target_id);
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kComplete);
EXPECT_EQ(metadata.usage(), ShareSessionUsage::kPairing);
EXPECT_EQ(metadata.binding_id(), kBindingId);
notification.Notify();
});
absl::Notification pairing_notification;
NearbySharingServiceImpl::StatusCodes pairing_result;
EXPECT_CALL(*mock_app_info_, SetActiveFlag());
google::nearby::identity::v1::InitiateBindingResponse response;
response.set_binding_id(kBindingId);
nearby_identity_client_.SetInitiateBindingResponses({response});
service_->InitiatePairing(
target_id, service::proto::BindingRequest::FILESYNC,
[&](NearbySharingServiceImpl::StatusCodes status_code) {
pairing_result = status_code;
pairing_notification.Notify();
});
EXPECT_TRUE(
pairing_notification.WaitForNotificationWithTimeout(kTaskWaitTimeout));
EXPECT_EQ(pairing_result, NearbySharingServiceImpl::StatusCodes::kOk);
FlushTesting();
// Verify data sent to the remote device so far.
EXPECT_TRUE(ExpectPairedKeyEncryptionFrame());
EXPECT_TRUE(ExpectPairedKeyResultFrame());
// Check BindingRequest frame sent to the remote device.
std::unique_ptr<Frame> frame = GetWrittenFrame();
ASSERT_TRUE(frame->has_v1());
EXPECT_EQ(frame->v1().type(), service::proto::V1Frame::BINDINGS);
EXPECT_EQ(frame->v1().bindings().binding_request().binding_id(), kBindingId);
EXPECT_EQ(frame->v1().bindings().binding_request().type(),
service::proto::BindingRequest::FILESYNC);
preference_manager_.SetString(PrefNames::kCustomSavePath, "Downloads");
Frame binding_response_frame;
binding_response_frame.set_version(Frame::V1);
binding_response_frame.mutable_v1()->set_type(
service::proto::V1Frame::BINDINGS);
binding_response_frame.mutable_v1()
->mutable_bindings()
->mutable_binding_response()
->set_status(service::proto::BindingResponse::SUCCESS);
std::vector<uint8_t> result_bytes(binding_response_frame.ByteSizeLong());
binding_response_frame.SerializeToArray(result_bytes.data(),
result_bytes.size());
ReceiveMessageFromConnection(std::move(result_bytes));
// Verify that connection is closed.
EXPECT_FALSE(
fake_nearby_connections_manager_->connection_endpoint_info(kEndpointId)
.has_value());
std::optional<nearby::sharing::sync::SyncBindingPrefs> binding =
preference_manager_.GetSyncBindingValue();
ASSERT_TRUE(binding.has_value());
EXPECT_EQ(binding->sync_bindings().size(), 1);
sync::SyncBinding expected_binding;
expected_binding.set_binding_id(kBindingId);
expected_binding.set_source_name(kDeviceName);
expected_binding.set_destination_directory(
FilePath("Downloads").append(FilePath(kDeviceName)).ToString());
expected_binding.set_source_device_type(
sync::SyncBinding::SOURCE_DEVICE_TYPE_PHONE);
EXPECT_THAT(binding->sync_bindings(0), EqualsProto(expected_binding));
}
} // namespace NearbySharingServiceUnitTests
} // namespace nearby::sharing