Move accept timeout into outgoingShareSession.

PiperOrigin-RevId: 652626672
This commit is contained in:
Francis Tsui
2024-07-15 16:10:35 -07:00
committed by Copybara-Service
parent 907ad97e8d
commit b166682810
6 changed files with 591 additions and 342 deletions
+1
View File
@@ -789,6 +789,7 @@ cc_test(
":share_session",
":test_support",
":transfer_metadata",
":transfer_metadata_matchers",
":types",
"//internal/analytics:mock_event_logger",
"//internal/platform/implementation/g3", # fixdeps: keep
+42 -197
View File
@@ -118,6 +118,7 @@ using ::location::nearby::proto::sharing::SessionStatus;
using ::nearby::sharing::api::SharingPlatform;
using ::nearby::sharing::proto::DataUsage;
using ::nearby::sharing::proto::DeviceVisibility;
using ::nearby::sharing::service::proto::ConnectionResponseFrame;
using ::nearby::sharing::service::proto::IntroductionFrame;
constexpr absl::Duration kBackgroundAdvertisementRotationDelayMin =
@@ -344,7 +345,6 @@ void NearbySharingServiceImpl::Cleanup() {
last_outgoing_metadata_.reset();
locally_cancelled_share_target_ids_.clear();
mutual_acceptance_timeout_alarm_.reset();
disconnection_timeout_alarms_.clear();
is_scanning_ = false;
@@ -814,20 +814,9 @@ void NearbySharingServiceImpl::SendAttachments(
bool NearbySharingServiceImpl::OutgoingSessionAccept(
OutgoingShareSession& session) {
if (!session.IsConnected()) {
NL_LOG(WARNING) << __func__
<< ": Accept invoked for unconnected share target";
return false;
}
if (!ReadyToAccept(session.self_share(),
last_outgoing_metadata_.has_value()
? std::get<2>(*last_outgoing_metadata_).status()
: TransferMetadata::Status::kUnknown)) {
NL_LOG(WARNING) << __func__ << ": out of order API call.";
return false;
}
SendPayloads(session);
return true;
return session.AcceptTransfer(
absl::bind_front(&NearbySharingServiceImpl::OnReceiveConnectionResponse,
this, session.share_target().id));
}
void NearbySharingServiceImpl::Accept(
@@ -896,8 +885,7 @@ void NearbySharingServiceImpl::Reject(
// kRejected status already sent below, no need to send on disconnect.
session->set_disconnect_status(TransferMetadata::Status::kUnknown);
session->WriteResponseFrame(
service::proto::ConnectionResponseFrame::REJECT);
session->WriteResponseFrame(ConnectionResponseFrame::REJECT);
NL_VLOG(1) << __func__
<< ": Successfully wrote a rejection response frame";
@@ -2411,31 +2399,6 @@ void NearbySharingServiceImpl::OnTransferStarted(bool is_incoming) {
InvalidateSurfaceState();
}
void NearbySharingServiceImpl::SendPayloads(OutgoingShareSession& session) {
NL_VLOG(1) << __func__ << ": Preparing to send payloads to "
<< session.share_target().id;
// Log analytics event of sending attachment start.
analytics_recorder_->NewSendAttachmentsStart(
session.session_id(), session.attachment_container(),
/*transfer_position=*/GetConnectedShareTargetPos(),
/*concurrent_connections=*/GetConnectedShareTargetCount());
session.UpdateTransferMetadata(
TransferMetadataBuilder()
.set_token(session.token())
.set_status(TransferMetadata::Status::kAwaitingRemoteAcceptance)
.build());
NL_VLOG(1) << __func__ << ": Receiving response frame from "
<< session.share_target().id;
session.frames_reader()->ReadFrame(
nearby::sharing::service::proto::V1Frame::RESPONSE,
[this, share_target_id = session.share_target().id](
std::optional<nearby::sharing::service::proto::V1Frame> frame) {
OnReceiveConnectionResponse(share_target_id, std::move(frame));
},
kReadResponseFrameTimeout);
}
void NearbySharingServiceImpl::OnOutgoingConnection(
absl::Time connect_start_time, NearbyConnection* connection,
OutgoingShareSession& session) {
@@ -2479,58 +2442,6 @@ void NearbySharingServiceImpl::OnOutgoingConnection(
this, share_target_id));
}
void NearbySharingServiceImpl::SendIntroduction(OutgoingShareSession& session) {
// We successfully connected! Now lets build up Payloads for all the files we
// want to send them. We won't send any just yet, but we'll send the Payload
// IDs in our introduction frame so that they know what to expect if they
// accept.
NL_VLOG(1) << __func__ << ": Preparing to send introduction to "
<< session.share_target().id;
// Log analytics event of sending introduction.
analytics_recorder_->NewSendIntroduction(
session.session_id(), session.share_target(),
/*transfer_position=*/GetConnectedShareTargetPos(),
/*concurrent_connections=*/GetConnectedShareTargetCount(),
session.os_type());
if (foreground_send_surface_map_.empty() &&
background_send_surface_map_.empty()) {
NL_LOG(WARNING) << __func__ << ": No transfer callbacks, disconnecting.";
session.connection()->Close();
return;
}
NL_VLOG(1) << __func__ << ": Sending attachments to "
<< session.share_target().id;
if (!session.WriteIntroductionFrame()) {
NL_LOG(WARNING) << __func__
<< ": No payloads tied to transfer, disconnecting.";
session.Abort(TransferMetadata::Status::kMissingPayloads);
return;
}
// We've successfully written the introduction, so we now have to wait for the
// remote side to accept.
NL_VLOG(1) << __func__ << ": Successfully wrote the introduction frame";
mutual_acceptance_timeout_alarm_ = std::make_unique<ThreadTimer>(
*service_thread_, "mutual_acceptance_timeout_alarm",
kReadResponseFrameTimeout,
[this, share_target_id = session.share_target().id]() {
NL_VLOG(1)
<< __func__
<< ": Outgoing mutual acceptance timed out, closing connection for "
<< share_target_id;
OutgoingShareSession* session =
GetOutgoingShareSession(share_target_id);
if (session == nullptr) {
return;
}
session->Abort(TransferMetadata::Status::kTimedOut);
});
}
void NearbySharingServiceImpl::CreatePayloads(
OutgoingShareSession& session,
std::function<void(OutgoingShareSession&, bool)> callback) {
@@ -2907,13 +2818,31 @@ void NearbySharingServiceImpl::OnOutgoingConnectionKeyVerificationDone(
session->Abort(TransferMetadata::Status::kPairedKeyVerificationFailed);
return;
}
SendIntroduction(*session);
// SendPayloads if key verification is successful or skip sender confirmation.
NL_VLOG(1) << __func__ << ": Preparing to send introduction to "
<< share_target_id;
if (!session->SendIntroduction([this, share_target_id]() {
NL_VLOG(1)
<< "Outgoing mutual acceptance timed out, closing connection for "
<< share_target_id;
OutgoingShareSession* session =
GetOutgoingShareSession(share_target_id);
if (session == nullptr) {
return;
}
session->Abort(TransferMetadata::Status::kTimedOut);
})) {
NL_LOG(WARNING) << __func__
<< ": No payloads tied to transfer, disconnecting.";
session->Abort(TransferMetadata::Status::kMissingPayloads);
return;
}
// Auto Accept if key verification is successful or skip sender confirmation.
if (session->token().empty() ||
NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_sharing_feature::
kSenderSkipsConfirmation)) {
SendPayloads(*session);
OutgoingSessionAccept(*session);
} else {
session->UpdateTransferMetadata(
TransferMetadataBuilder()
@@ -2981,8 +2910,7 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
}
void NearbySharingServiceImpl::OnReceiveConnectionResponse(
int64_t share_target_id,
std::optional<nearby::sharing::service::proto::V1Frame> frame) {
int64_t share_target_id, std::optional<ConnectionResponseFrame> frame) {
OutgoingShareSession* session = GetOutgoingShareSession(share_target_id);
if (!session || !session->IsConnected()) {
NL_LOG(WARNING) << __func__
@@ -2991,92 +2919,23 @@ void NearbySharingServiceImpl::OnReceiveConnectionResponse(
return;
}
if (!frame) {
NL_LOG(WARNING)
<< __func__
<< ": Failed to read a response from the remote device. Disconnecting.";
session->Abort(
TransferMetadata::Status::kFailedToReadOutgoingConnectionResponse);
std::optional<TransferMetadata::Status> status =
session->HandleConnectionResponse(std::move(frame));
if (status.has_value()) {
session->Abort(*status);
return;
}
mutual_acceptance_timeout_alarm_.reset();
NL_VLOG(1) << __func__
<< ": Successfully read the connection response frame.";
nearby::sharing::service::proto::ConnectionResponseFrame response =
std::move(frame->connection_response());
switch (response.status()) {
case nearby::sharing::service::proto::ConnectionResponseFrame::ACCEPT: {
// Write progress update frame to remote machine.
session->WriteProgressUpdateFrame(/*start_transfer=*/true,
/*progress=*/std::nullopt);
session->frames_reader()->ReadFrame(
[this, share_target_id](
std::optional<nearby::sharing::service::proto::V1Frame> frame) {
OnFrameRead(share_target_id, std::move(frame));
});
session->UpdateTransferMetadata(
TransferMetadataBuilder()
.set_status(TransferMetadata::Status::kInProgress)
.build());
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_sharing_feature::
kEnableTransferCancellationOptimization)) {
session->InitSendPayload(
context_->GetClock(), *nearby_connections_manager_,
absl::bind_front(&NearbySharingServiceImpl::OnPayloadTransferUpdate,
this));
session->SendNextPayload(*nearby_connections_manager_);
} else {
session->SendAllPayloads(
context_->GetClock(), *nearby_connections_manager_,
absl::bind_front(&NearbySharingServiceImpl::OnPayloadTransferUpdate,
this));
}
NL_VLOG(1)
<< __func__
<< ": The connection was accepted. Payloads are now being sent.";
break;
}
case nearby::sharing::service::proto::ConnectionResponseFrame::REJECT:
session->Abort(TransferMetadata::Status::kRejected);
NL_VLOG(1)
<< __func__
<< ": The connection was rejected. The connection has been closed.";
break;
case nearby::sharing::service::proto::ConnectionResponseFrame::
NOT_ENOUGH_SPACE:
session->Abort(TransferMetadata::Status::kNotEnoughSpace);
NL_VLOG(1) << __func__
<< ": The connection was rejected because the remote device "
"does not have enough space for our attachments. The "
"connection has been closed.";
break;
case nearby::sharing::service::proto::ConnectionResponseFrame::
UNSUPPORTED_ATTACHMENT_TYPE:
session->Abort(TransferMetadata::Status::kUnsupportedAttachmentType);
NL_VLOG(1) << __func__
<< ": The connection was rejected because the remote device "
"does not support the attachments we were sending. The "
"connection has been closed.";
break;
case nearby::sharing::service::proto::ConnectionResponseFrame::TIMED_OUT:
session->Abort(TransferMetadata::Status::kTimedOut);
NL_VLOG(1) << __func__
<< ": The connection was rejected because the remote device "
"timed out. The connection has been closed.";
break;
default:
session->Abort(TransferMetadata::Status::kFailed);
NL_VLOG(1) << __func__
<< ": The connection failed. The connection has been closed.";
break;
}
session->SendPayloads(
NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_sharing_feature::
kEnableTransferCancellationOptimization),
context_->GetClock(), *nearby_connections_manager_,
[this, share_target_id](
std::optional<nearby::sharing::service::proto::V1Frame> frame) {
OnFrameRead(share_target_id, std::move(frame));
},
absl::bind_front(&NearbySharingServiceImpl::OnPayloadTransferUpdate,
this));
}
void NearbySharingServiceImpl::OnStorageCheckCompleted(
@@ -3512,7 +3371,6 @@ void NearbySharingServiceImpl::UnregisterShareTarget(int64_t share_target_id) {
NL_VLOG(1) << __func__ << ": Unregister share target: " << share_target_id;
}
mutual_acceptance_timeout_alarm_.reset();
}
void NearbySharingServiceImpl::OnStartAdvertisingResult(bool used_device_name,
@@ -3661,19 +3519,6 @@ void NearbySharingServiceImpl::ResetAllSettings(bool logout) {
InvalidateSurfaceState();
}
bool NearbySharingServiceImpl::ReadyToAccept(
bool for_self_share, TransferMetadata::Status status) const {
if (status == TransferMetadata::Status::kAwaitingLocalConfirmation) {
return true;
}
if (for_self_share && status == TransferMetadata::Status::kUnknown) {
return true;
}
return false;
}
void NearbySharingServiceImpl::RunOnNearbySharingServiceThread(
absl::string_view task_name, absl::AnyInvocable<void()> task) {
if (IsShuttingDown()) {
+2 -12
View File
@@ -312,12 +312,9 @@ class NearbySharingServiceImpl
void OnTransferComplete();
void OnTransferStarted(bool is_incoming);
void SendPayloads(OutgoingShareSession& session);
void OnOutgoingConnection(absl::Time connect_start_time,
NearbyConnection* connection,
OutgoingShareSession& session);
void SendIntroduction(OutgoingShareSession& session);
void CreatePayloads(
OutgoingShareSession& session,
@@ -351,7 +348,8 @@ class NearbySharingServiceImpl
std::optional<nearby::sharing::service::proto::IntroductionFrame> frame);
void OnReceiveConnectionResponse(
int64_t share_target_id,
std::optional<nearby::sharing::service::proto::V1Frame> frame);
std::optional<nearby::sharing::service::proto::ConnectionResponseFrame>
frame);
void OnStorageCheckCompleted(IncomingShareSession& session);
void OnFrameRead(
int64_t share_target_id,
@@ -416,10 +414,6 @@ class NearbySharingServiceImpl
// `contacts` -> `off`.
void ResetAllSettings(bool logout);
// Checks whether we should accept transfer.
bool ReadyToAccept(bool for_self_share,
TransferMetadata::Status status) const;
// Runs API/task on the service thread to avoid UI block.
void RunOnNearbySharingServiceThread(absl::string_view task_name,
absl::AnyInvocable<void()> task);
@@ -539,10 +533,6 @@ class NearbySharingServiceImpl
// unnecessary backend API call.
absl::flat_hash_set<std::string> discovered_advertisements_retried_set_;
// This alarm is used to disconnect the sharing connection if both sides do
// not press accept within the timeout.
std::unique_ptr<ThreadTimer> mutual_acceptance_timeout_alarm_;
// A map of ShareTarget id to disconnection timeout callback. Used to only
// disconnect after a timeout to keep sending any pending payloads.
absl::flat_hash_map<std::string, std::unique_ptr<ThreadTimer>>
+137 -2
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/constants.h"
#include "sharing/file_attachment.h"
#include "sharing/internal/public/logging.h"
#include "sharing/nearby_connection.h"
@@ -40,11 +41,14 @@
#include "sharing/share_session.h"
#include "sharing/share_target.h"
#include "sharing/text_attachment.h"
#include "sharing/thread_timer.h"
#include "sharing/transfer_metadata.h"
#include "sharing/transfer_metadata_builder.h"
#include "sharing/wifi_credentials_attachment.h"
namespace nearby::sharing {
using ::nearby::sharing::service::proto::ConnectionResponseFrame;
using ::nearby::sharing::service::proto::Frame;
using ::nearby::sharing::service::proto::IntroductionFrame;
using ::nearby::sharing::service::proto::ProgressUpdateFrame;
@@ -227,6 +231,69 @@ bool OutgoingShareSession::FillIntroductionFrame(
return true;
}
bool OutgoingShareSession::AcceptTransfer(
std::function<void(std::optional<ConnectionResponseFrame>)>
response_callback) {
if (!IsConnected()) {
NL_LOG(WARNING) << __func__
<< ": Accept invoked for unconnected share target";
return false;
}
if (!ready_for_accept_) {
NL_LOG(WARNING) << __func__ << ": out of order API call.";
return false;
}
ready_for_accept_ = false;
// Wait for remote accept in response frame.
UpdateTransferMetadata(
TransferMetadataBuilder()
.set_token(token())
.set_status(TransferMetadata::Status::kAwaitingRemoteAcceptance)
.build());
NL_VLOG(1) << __func__ << ": Waiting for response frame from "
<< share_target().id;
frames_reader()->ReadFrame(
nearby::sharing::service::proto::V1Frame::RESPONSE,
[callback = std::move(response_callback)](std::optional<V1Frame> frame) {
if (!frame.has_value()) {
callback(std::nullopt);
return;
}
callback(frame->connection_response());
},
kReadResponseFrameTimeout);
return true;
}
void OutgoingShareSession::SendPayloads(
bool enable_transfer_cancellation_optimization, Clock* clock,
NearbyConnectionsManager& connection_manager,
std::function<
void(std::optional<nearby::sharing::service::proto::V1Frame> frame)>
frame_read_callback,
std::function<void(int64_t, TransferMetadata)> update_callback) {
if (!IsConnected()) {
NL_LOG(WARNING) << __func__
<< ": SendPayloads invoked for unconnected share target";
return;
}
frames_reader()->ReadFrame(std::move(frame_read_callback));
// Log analytics event of sending attachment start.
analytics_recorder().NewSendAttachmentsStart(session_id(),
attachment_container(),
/*transfer_position=*/1,
/*concurrent_connections=*/1);
NL_VLOG(1) << __func__
<< ": The connection was accepted. Payloads are now being sent.";
if (enable_transfer_cancellation_optimization) {
InitSendPayload(clock, connection_manager, std::move(update_callback));
SendNextPayload(connection_manager);
} else {
SendAllPayloads(clock, connection_manager, std::move(update_callback));
}
}
void OutgoingShareSession::SendAllPayloads(
Clock* clock, NearbyConnectionsManager& connection_manager,
std::function<void(int64_t, TransferMetadata)> update_callback) {
@@ -283,7 +350,8 @@ void OutgoingShareSession::WriteProgressUpdateFrame(
WriteFrame(frame);
}
bool OutgoingShareSession::WriteIntroductionFrame() {
bool OutgoingShareSession::SendIntroduction(
std::function<void()> timeout_callback) {
Frame frame;
frame.set_version(Frame::V1);
V1Frame* v1_frame = frame.mutable_v1();
@@ -293,11 +361,78 @@ bool OutgoingShareSession::WriteIntroductionFrame() {
if (!FillIntroductionFrame(introduction_frame)) {
return false;
}
WriteFrame(frame);
// Log analytics event of sending introduction.
analytics_recorder().NewSendIntroduction(session_id(), share_target(),
/*transfer_position=*/1,
/*concurrent_connections=*/1,
os_type());
NL_VLOG(1) << __func__ << ": Successfully wrote the introduction frame";
ready_for_accept_ = true;
mutual_acceptance_timeout_ = std::make_unique<ThreadTimer>(
service_thread(), "outgoing_mutual_acceptance_timeout",
kReadResponseFrameTimeout, std::move(timeout_callback));
return true;
}
std::optional<TransferMetadata::Status>
OutgoingShareSession::HandleConnectionResponse(
std::optional<ConnectionResponseFrame> response) {
// Stop accept timer.
mutual_acceptance_timeout_.reset();
if (!response.has_value()) {
NL_LOG(WARNING)
<< __func__
<< ": Failed to read a response from the remote device. Disconnecting.";
return TransferMetadata::Status::kFailedToReadOutgoingConnectionResponse;
}
NL_VLOG(1) << __func__
<< ": Successfully read the connection response frame.";
switch (response->status()) {
case ConnectionResponseFrame::ACCEPT: {
// Write progress update frame to remote machine.
WriteProgressUpdateFrame(/*start_transfer=*/true,
/*progress=*/std::nullopt);
UpdateTransferMetadata(
TransferMetadataBuilder()
.set_status(TransferMetadata::Status::kInProgress)
.build());
return std::nullopt;
}
case ConnectionResponseFrame::REJECT:
NL_VLOG(1)
<< __func__
<< ": The connection was rejected. The connection has been closed.";
return TransferMetadata::Status::kRejected;
case ConnectionResponseFrame::NOT_ENOUGH_SPACE:
NL_VLOG(1) << __func__
<< ": The connection was rejected because the remote device "
"does not have enough space for our attachments. The "
"connection has been closed.";
return TransferMetadata::Status::kNotEnoughSpace;
case ConnectionResponseFrame::UNSUPPORTED_ATTACHMENT_TYPE:
NL_VLOG(1) << __func__
<< ": The connection was rejected because the remote device "
"does not support the attachments we were sending. The "
"connection has been closed.";
return TransferMetadata::Status::kUnsupportedAttachmentType;
case ConnectionResponseFrame::TIMED_OUT:
NL_VLOG(1) << __func__
<< ": The connection was rejected because the remote device "
"timed out. The connection has been closed.";
return TransferMetadata::Status::kTimedOut;
default:
NL_VLOG(1) << __func__
<< ": The connection failed. The connection has been closed.";
break;
}
return TransferMetadata::Status::kFailed;
}
std::vector<Payload> OutgoingShareSession::ExtractTextPayloads() {
return std::move(text_payloads_);
}
+54 -17
View File
@@ -18,6 +18,7 @@
#include <cstdint>
#include <filesystem> // NOLINT
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <utility>
@@ -33,6 +34,7 @@
#include "sharing/paired_key_verification_runner.h"
#include "sharing/share_session.h"
#include "sharing/share_target.h"
#include "sharing/thread_timer.h"
#include "sharing/transfer_metadata.h"
namespace nearby::sharing {
@@ -89,30 +91,60 @@ class OutgoingShareSession : public ShareSession {
bool CreateFilePayloads(
const std::vector<NearbyFileHandler::FileInfo>& files);
// Create a payload status listener to send status change to
// |update_callback|. Send all payloads to NearbyConnectionManager.
void SendAllPayloads(
Clock* clock, NearbyConnectionsManager& connection_manager,
std::function<void(int64_t, TransferMetadata)> update_callback);
// Create a payload status listener to send status change to
// |update_callback|.
void InitSendPayload(
Clock* clock, NearbyConnectionsManager& connection_manager,
std::function<void(int64_t, TransferMetadata)> update_callback);
// Send the next payload to NearbyConnectionManager.
void SendNextPayload(NearbyConnectionsManager& connection_manager);
void WriteProgressUpdateFrame(std::optional<bool> start_transfer,
std::optional<float> progress);
// Returns true if the introduction frame is written successfully.
bool WriteIntroductionFrame();
// `timeout_callback` is called if accept is not received from both sender and
// receiver within the timeout.
bool SendIntroduction(std::function<void()> timeout_callback);
// Accept the outgoing transfer and wait for remote accept message in a
// ConnectionResponseFrame.
bool AcceptTransfer(
std::function<
void(std::optional<
nearby::sharing::service::proto::ConnectionResponseFrame>)>
response_callback);
// Process the ConnectionResponseFrame.
// On success, returns std::nullopt.
// On failure, returns the status if the connection should be aborted.
std::optional<TransferMetadata::Status> HandleConnectionResponse(
std::optional<nearby::sharing::service::proto::ConnectionResponseFrame>
response);
// Begin sending payloads.
// Listen to the payload status change and send the status to
// `update_callback`.
// Any other frames received will be passed to `frame_read_callback`.
void SendPayloads(
bool enable_transfer_cancellation_optimization, Clock* clock,
NearbyConnectionsManager& connection_manager,
std::function<
void(std::optional<nearby::sharing::service::proto::V1Frame> frame)>
frame_read_callback,
std::function<void(int64_t, TransferMetadata)> update_callback);
// Send the next payload to NearbyConnectionManager.
// Used only if enable_transfer_cancellation_optimization is true.
void SendNextPayload(NearbyConnectionsManager& connection_manager);
protected:
void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override;
bool OnNewConnection(NearbyConnection* connection) override;
private:
void WriteProgressUpdateFrame(std::optional<bool> start_transfer,
std::optional<float> progress);
// Create a payload status listener to send status change to
// `update_callback`. Send all payloads to NearbyConnectionManager.
void SendAllPayloads(
Clock* clock, NearbyConnectionsManager& connection_manager,
std::function<void(int64_t, TransferMetadata)> update_callback);
// Create a payload status listener to send status change to
// `update_callback`.
void InitSendPayload(
Clock* clock, NearbyConnectionsManager& connection_manager,
std::function<void(int64_t, TransferMetadata)> update_callback);
std::vector<Payload> ExtractTextPayloads();
std::vector<Payload> ExtractFilePayloads();
std::vector<Payload> ExtractWifiCredentialsPayloads();
@@ -120,6 +152,7 @@ class OutgoingShareSession : public ShareSession {
bool FillIntroductionFrame(
nearby::sharing::service::proto::IntroductionFrame* introduction) const;
std::optional<std::string> obfuscated_gaia_id_;
// All payloads are in the same order as the attachments in the share target.
std::vector<Payload> text_payloads_;
@@ -128,6 +161,10 @@ class OutgoingShareSession : public ShareSession {
Status connection_layer_status_;
std::function<void(OutgoingShareSession&, const TransferMetadata&)>
transfer_update_callback_;
bool ready_for_accept_ = false;
// This alarm is used to disconnect the sharing connection if both sides do
// not press accept within the timeout.
std::unique_ptr<ThreadTimer> mutual_acceptance_timeout_;
};
} // namespace nearby::sharing
+355 -114
View File
@@ -26,7 +26,9 @@
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "internal/analytics/mock_event_logger.h"
#include "internal/analytics/sharing_log_matchers.h"
#include "internal/test/fake_clock.h"
#include "internal/test/fake_task_runner.h"
#include "sharing/analytics/analytics_recorder.h"
@@ -43,24 +45,36 @@
#include "sharing/share_target.h"
#include "sharing/text_attachment.h"
#include "sharing/transfer_metadata.h"
#include "sharing/transfer_metadata_matchers.h"
#include "sharing/wifi_credentials_attachment.h"
namespace nearby::sharing {
namespace {
using ::location::nearby::proto::sharing::EventCategory;
using ::location::nearby::proto::sharing::EventType;
using ::location::nearby::proto::sharing::OSType;
using ::nearby::analytics::HasCategory;
using ::nearby::analytics::HasEventType;
using ::nearby::analytics::HasSessionId;
using ::nearby::sharing::analytics::proto::SharingLog;
using ::nearby::sharing::service::proto::ConnectionResponseFrame;
using ::nearby::sharing::service::proto::Frame;
using ::nearby::sharing::service::proto::IntroductionFrame;
using ::nearby::sharing::service::proto::ProgressUpdateFrame;
using ::nearby::sharing::service::proto::V1Frame;
using ::nearby::sharing::service::proto::WifiCredentials;
using ::testing::_;
using ::testing::AllOf;
using ::testing::Eq;
using ::testing::Invoke;
using ::testing::IsEmpty;
using ::testing::IsFalse;
using ::testing::IsTrue;
using ::testing::Matcher;
using ::testing::MockFunction;
using ::testing::Property;
using ::testing::SizeIs;
using ::testing::StrictMock;
constexpr absl::string_view kEndpointId = "ABCD";
@@ -69,7 +83,7 @@ class OutgoingShareSessionTest : public ::testing::Test {
OutgoingShareSessionTest()
: session_(fake_task_runner_, analytics_recorder_,
std::string(kEndpointId), share_target_,
[](OutgoingShareSession&, const TransferMetadata&) {}),
transfer_metadata_callback_.AsStdFunction()),
text1_(nearby::sharing::service::proto::TextMetadata::URL,
"A bit of text body", "Some text title", "text/html"),
text2_(nearby::sharing::service::proto::TextMetadata::ADDRESS,
@@ -95,6 +109,8 @@ class OutgoingShareSessionTest : public ::testing::Test {
&mock_event_logger_};
NearbySharingDecoderImpl decoder_;
ShareTarget share_target_;
MockFunction<void(OutgoingShareSession&, const TransferMetadata&)>
transfer_metadata_callback_;
OutgoingShareSession session_;
TextAttachment text1_;
TextAttachment text2_;
@@ -229,11 +245,12 @@ TEST_F(OutgoingShareSessionTest, CreateWifiCredentialsPayloads) {
EXPECT_THAT(attachment_payload_map.at(wifi1_.id()), Eq(payloads[0].id));
}
TEST_F(OutgoingShareSessionTest, WriteIntroductionFrameWithoutPayloads) {
EXPECT_THAT(session_.WriteIntroductionFrame(), IsFalse());
TEST_F(OutgoingShareSessionTest, SendIntroductionWithoutPayloads) {
EXPECT_THAT(session_.SendIntroduction([]() {}), IsFalse());
}
TEST_F(OutgoingShareSessionTest, WriteIntroductionFrameSuccess) {
TEST_F(OutgoingShareSessionTest, SendIntroductionSuccess) {
session_.set_session_id(1234);
FakeNearbyConnection connection;
session_.OnConnected(decoder_, absl::Now(), &connection);
std::vector<NearbyFileHandler::FileInfo> file_infos;
@@ -244,8 +261,14 @@ TEST_F(OutgoingShareSessionTest, WriteIntroductionFrameSuccess) {
session_.CreateFilePayloads(file_infos);
session_.CreateTextPayloads();
session_.CreateWifiCredentialsPayloads();
EXPECT_CALL(
mock_event_logger_,
Log(Matcher<const SharingLog&>(AllOf(
(HasCategory(EventCategory::SENDING_EVENT),
HasEventType(EventType::SEND_INTRODUCTION),
Property(&SharingLog::send_introduction, HasSessionId(1234)))))));
EXPECT_THAT(session_.WriteIntroductionFrame(), IsTrue());
EXPECT_THAT(session_.SendIntroduction([]() {}), IsTrue());
std::vector<uint8_t> frame_data = connection.GetWrittenData();
Frame frame;
@@ -296,130 +319,189 @@ TEST_F(OutgoingShareSessionTest, WriteIntroductionFrameSuccess) {
Eq(wifi_payloads[0].id));
}
TEST_F(OutgoingShareSessionTest, SendAllPayloads) {
std::vector<NearbyFileHandler::FileInfo> file_infos;
file_infos.push_back({
.size = 12355L,
.file_path = file1_.file_path().value(),
});
session_.CreateFilePayloads(file_infos);
TEST_F(OutgoingShareSessionTest, SendIntroductionTimeout) {
AttachmentContainer container(
std::vector<TextAttachment>{text1_}, {}, {});
session_.SetAttachmentContainer(std::move(container));
session_.set_session_id(1234);
FakeNearbyConnection connection;
session_.OnConnected(decoder_, absl::Now(), &connection);
session_.CreateTextPayloads();
session_.CreateWifiCredentialsPayloads();
MockFunction<void(int64_t, TransferMetadata)> transfer_metadata_callback;
MockFunction<void(
std::unique_ptr<Payload>,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>)>
send_payload_callback;
FakeNearbyConnectionsManager connections_manager;
connections_manager.set_send_payload_callback(
send_payload_callback.AsStdFunction());
EXPECT_CALL(send_payload_callback, Call(_, _))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(file1_.id());
}))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(text1_.id());
}))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(text2_.id());
}));
EXPECT_CALL(
mock_event_logger_,
Log(Matcher<const SharingLog&>(AllOf(
(HasCategory(EventCategory::SENDING_EVENT),
HasEventType(EventType::SEND_INTRODUCTION),
Property(&SharingLog::send_introduction, HasSessionId(1234)))))));
session_.SendAllPayloads(&fake_clock_, connections_manager,
transfer_metadata_callback.AsStdFunction());
bool accept_timeout_called = false;
EXPECT_THAT(session_.SendIntroduction(
[&accept_timeout_called]() { accept_timeout_called = true; }),
IsTrue());
auto payload_listener = session_.payload_tracker().lock();
EXPECT_THAT(payload_listener, IsTrue());
fake_clock_.FastForward(absl::Seconds(60));
fake_task_runner_.SyncWithTimeout(absl::Milliseconds(100));
EXPECT_THAT(accept_timeout_called, IsTrue());
}
TEST_F(OutgoingShareSessionTest, InitSendPayload) {
std::vector<NearbyFileHandler::FileInfo> file_infos;
file_infos.push_back({
.size = 12355L,
.file_path = file1_.file_path().value(),
});
session_.CreateFilePayloads(file_infos);
TEST_F(OutgoingShareSessionTest, SendIntroductionTimeoutCancelled) {
AttachmentContainer container(
std::vector<TextAttachment>{text1_}, {}, {});
session_.SetAttachmentContainer(std::move(container));
session_.set_session_id(1234);
FakeNearbyConnection connection;
session_.OnConnected(decoder_, absl::Now(), &connection);
session_.CreateTextPayloads();
session_.CreateWifiCredentialsPayloads();
MockFunction<void(int64_t, TransferMetadata)> transfer_metadata_callback;
MockFunction<void(
std::unique_ptr<Payload>,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>)>
send_payload_callback;
FakeNearbyConnectionsManager connections_manager;
connections_manager.set_send_payload_callback(
send_payload_callback.AsStdFunction());
EXPECT_CALL(
mock_event_logger_,
Log(Matcher<const SharingLog&>(AllOf(
(HasCategory(EventCategory::SENDING_EVENT),
HasEventType(EventType::SEND_INTRODUCTION),
Property(&SharingLog::send_introduction, HasSessionId(1234)))))));
session_.InitSendPayload(&fake_clock_, connections_manager,
transfer_metadata_callback.AsStdFunction());
bool accept_timeout_called = false;
EXPECT_THAT(session_.SendIntroduction(
[&accept_timeout_called]() { accept_timeout_called = true; }),
IsTrue());
ConnectionResponseFrame response;
response.set_status(ConnectionResponseFrame::ACCEPT);
EXPECT_CALL(transfer_metadata_callback_,
Call(_, HasStatus(TransferMetadata::Status::kInProgress)));
auto payload_listener = session_.payload_tracker().lock();
EXPECT_THAT(payload_listener, IsTrue());
std::optional<TransferMetadata::Status> status =
session_.HandleConnectionResponse(response);
EXPECT_THAT(status.has_value(), IsFalse());
fake_clock_.FastForward(absl::Seconds(60));
fake_task_runner_.SyncWithTimeout(absl::Milliseconds(100));
EXPECT_THAT(accept_timeout_called, IsFalse());
}
TEST_F(OutgoingShareSessionTest, SendNextPayload) {
std::vector<NearbyFileHandler::FileInfo> file_infos;
file_infos.push_back({
.size = 12355L,
.file_path = file1_.file_path().value(),
});
session_.CreateFilePayloads(file_infos);
session_.CreateTextPayloads();
session_.CreateWifiCredentialsPayloads();
MockFunction<void(int64_t, TransferMetadata)> transfer_metadata_callback;
MockFunction<void(
std::unique_ptr<Payload>,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>)>
send_payload_callback;
FakeNearbyConnectionsManager connections_manager;
connections_manager.set_send_payload_callback(
send_payload_callback.AsStdFunction());
session_.InitSendPayload(&fake_clock_, connections_manager,
transfer_metadata_callback.AsStdFunction());
EXPECT_CALL(send_payload_callback, Call(_, _))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(file1_.id());
}));
session_.SendNextPayload(connections_manager);
EXPECT_CALL(send_payload_callback, Call(_, _))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(text1_.id());
}));
session_.SendNextPayload(connections_manager);
EXPECT_CALL(send_payload_callback, Call(_, _))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(text2_.id());
}));
session_.SendNextPayload(connections_manager);
TEST_F(OutgoingShareSessionTest, AcceptTransferNotConnected) {
EXPECT_THAT(
session_.AcceptTransfer([](std::optional<ConnectionResponseFrame>) {}),
IsFalse());
}
TEST_F(OutgoingShareSessionTest, WriteInProgressUpdateFrameSuccess) {
TEST_F(OutgoingShareSessionTest, AcceptTransferNotReady) {
session_.set_session_id(1234);
FakeNearbyConnection connection;
session_.OnConnected(decoder_, absl::Now(), &connection);
session_.WriteProgressUpdateFrame(true, 0.5);
EXPECT_THAT(
session_.AcceptTransfer([](std::optional<ConnectionResponseFrame>) {}),
IsFalse());
}
TEST_F(OutgoingShareSessionTest, AcceptTransferSuccess) {
AttachmentContainer container(
std::vector<TextAttachment>{text1_}, {}, {});
session_.SetAttachmentContainer(std::move(container));
session_.set_session_id(1234);
FakeNearbyConnection connection;
session_.OnConnected(decoder_, absl::Now(), &connection);
session_.CreateTextPayloads();
EXPECT_CALL(mock_event_logger_,
Log(Matcher<const SharingLog&>(
AllOf((HasCategory(EventCategory::SENDING_EVENT),
HasEventType(EventType::SEND_INTRODUCTION))))));
EXPECT_THAT(session_.SendIntroduction([]() {}), IsTrue());
EXPECT_CALL(
transfer_metadata_callback_,
Call(_, HasStatus(TransferMetadata::Status::kAwaitingRemoteAcceptance)));
bool connection_response_received = false;
EXPECT_THAT(
session_.AcceptTransfer([&connection_response_received](
std::optional<ConnectionResponseFrame>) {
connection_response_received = true;
}),
IsTrue());
// Send response frame
nearby::sharing::service::proto::Frame frame =
nearby::sharing::service::proto::Frame();
frame.set_version(nearby::sharing::service::proto::Frame::V1);
V1Frame* v1frame = frame.mutable_v1();
v1frame->set_type(service::proto::V1Frame::RESPONSE);
v1frame->mutable_connection_response();
std::vector<uint8_t> data;
data.resize(frame.ByteSizeLong());
EXPECT_THAT(frame.SerializeToArray(data.data(), data.size()), IsTrue());
connection.AppendReadableData(std::move(data));
EXPECT_THAT(connection_response_received, IsTrue());
}
TEST_F(OutgoingShareSessionTest, HandleConnectionResponseEmptyResponse) {
std::optional<TransferMetadata::Status> status =
session_.HandleConnectionResponse(std::nullopt);
ASSERT_THAT(status.has_value(), IsTrue());
EXPECT_THAT(
status.value(),
Eq(TransferMetadata::Status::kFailedToReadOutgoingConnectionResponse));
}
TEST_F(OutgoingShareSessionTest, HandleConnectionResponseRejectResponse) {
ConnectionResponseFrame response;
response.set_status(ConnectionResponseFrame::REJECT);
std::optional<TransferMetadata::Status> status =
session_.HandleConnectionResponse(response);
ASSERT_THAT(status.has_value(), IsTrue());
EXPECT_THAT(status.value(), Eq(TransferMetadata::Status::kRejected));
}
TEST_F(OutgoingShareSessionTest,
HandleConnectionResponseNotEnoughSpaceResponse) {
ConnectionResponseFrame response;
response.set_status(ConnectionResponseFrame::NOT_ENOUGH_SPACE);
std::optional<TransferMetadata::Status> status =
session_.HandleConnectionResponse(response);
ASSERT_THAT(status.has_value(), IsTrue());
EXPECT_THAT(status.value(), Eq(TransferMetadata::Status::kNotEnoughSpace));
}
TEST_F(OutgoingShareSessionTest,
HandleConnectionResponseUnsuportedTypeResponse) {
ConnectionResponseFrame response;
response.set_status(ConnectionResponseFrame::UNSUPPORTED_ATTACHMENT_TYPE);
std::optional<TransferMetadata::Status> status =
session_.HandleConnectionResponse(response);
ASSERT_THAT(status.has_value(), IsTrue());
EXPECT_THAT(status.value(),
Eq(TransferMetadata::Status::kUnsupportedAttachmentType));
}
TEST_F(OutgoingShareSessionTest, HandleConnectionResponseTimeoutResponse) {
ConnectionResponseFrame response;
response.set_status(ConnectionResponseFrame::TIMED_OUT);
std::optional<TransferMetadata::Status> status =
session_.HandleConnectionResponse(response);
ASSERT_THAT(status.has_value(), IsTrue());
EXPECT_THAT(status.value(), Eq(TransferMetadata::Status::kTimedOut));
}
TEST_F(OutgoingShareSessionTest, HandleConnectionResponseAcceptResponse) {
ConnectionResponseFrame response;
response.set_status(ConnectionResponseFrame::ACCEPT);
FakeNearbyConnection connection;
session_.OnConnected(decoder_, absl::Now(), &connection);
EXPECT_CALL(transfer_metadata_callback_,
Call(_, HasStatus(TransferMetadata::Status::kInProgress)));
std::optional<TransferMetadata::Status> status =
session_.HandleConnectionResponse(response);
ASSERT_THAT(status.has_value(), IsFalse());
// Verify progress update frame
std::vector<uint8_t> frame_data = connection.GetWrittenData();
Frame frame;
ASSERT_THAT(frame.ParseFromArray(frame_data.data(), frame_data.size()),
@@ -428,7 +510,166 @@ TEST_F(OutgoingShareSessionTest, WriteInProgressUpdateFrameSuccess) {
ASSERT_THAT(frame.v1().type(), Eq(V1Frame::PROGRESS_UPDATE));
const ProgressUpdateFrame& progress_frame = frame.v1().progress_update();
EXPECT_THAT(progress_frame.start_transfer(), IsTrue());
EXPECT_THAT(progress_frame.progress(), Eq(0.5));
}
TEST_F(OutgoingShareSessionTest, SendPayloadsDisableCancellationOptimization) {
session_.set_session_id(1234);
std::vector<NearbyFileHandler::FileInfo> file_infos;
file_infos.push_back({
.size = 12355L,
.file_path = file1_.file_path().value(),
});
session_.CreateFilePayloads(file_infos);
session_.CreateTextPayloads();
session_.CreateWifiCredentialsPayloads();
MockFunction<void(int64_t, TransferMetadata)> transfer_metadata_callback;
StrictMock<MockFunction<void(
std::unique_ptr<Payload>,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>)>>
send_payload_callback;
FakeNearbyConnectionsManager connections_manager;
connections_manager.set_send_payload_callback(
send_payload_callback.AsStdFunction());
EXPECT_CALL(send_payload_callback, Call(_, _))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(file1_.id());
}))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(text1_.id());
}))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(text2_.id());
}));
EXPECT_CALL(mock_event_logger_,
Log(Matcher<const SharingLog&>(
AllOf((HasCategory(EventCategory::SENDING_EVENT),
HasEventType(EventType::SEND_ATTACHMENTS_START),
Property(&SharingLog::send_attachments_start,
HasSessionId(1234)))))));
FakeNearbyConnection connection;
session_.OnConnected(decoder_, absl::Now(), &connection);
session_.SendPayloads(
/*enable_transfer_cancellation_optimization=*/
false, &fake_clock_, connections_manager,
[](std::optional<V1Frame> frame) {},
transfer_metadata_callback.AsStdFunction());
auto payload_listener = session_.payload_tracker().lock();
EXPECT_THAT(payload_listener, IsTrue());
}
TEST_F(OutgoingShareSessionTest, SendPayloadsEnableCancellationOptimization) {
session_.set_session_id(1234);
std::vector<NearbyFileHandler::FileInfo> file_infos;
file_infos.push_back({
.size = 12355L,
.file_path = file1_.file_path().value(),
});
session_.CreateFilePayloads(file_infos);
session_.CreateTextPayloads();
session_.CreateWifiCredentialsPayloads();
MockFunction<void(int64_t, TransferMetadata)> transfer_metadata_callback;
StrictMock<MockFunction<void(
std::unique_ptr<Payload>,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>)>>
send_payload_callback;
FakeNearbyConnectionsManager connections_manager;
connections_manager.set_send_payload_callback(
send_payload_callback.AsStdFunction());
EXPECT_CALL(send_payload_callback, Call(_, _))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(file1_.id());
}));
EXPECT_CALL(mock_event_logger_,
Log(Matcher<const SharingLog&>(
AllOf((HasCategory(EventCategory::SENDING_EVENT),
HasEventType(EventType::SEND_ATTACHMENTS_START),
Property(&SharingLog::send_attachments_start,
HasSessionId(1234)))))));
FakeNearbyConnection connection;
session_.OnConnected(decoder_, absl::Now(), &connection);
session_.SendPayloads(
/*enable_transfer_cancellation_optimization=*/
true, &fake_clock_, connections_manager,
[](std::optional<V1Frame> frame) {},
transfer_metadata_callback.AsStdFunction());
auto payload_listener = session_.payload_tracker().lock();
EXPECT_THAT(payload_listener, IsTrue());
}
TEST_F(OutgoingShareSessionTest, SendNextPayload) {
session_.set_session_id(1234);
std::vector<NearbyFileHandler::FileInfo> file_infos;
file_infos.push_back({
.size = 12355L,
.file_path = file1_.file_path().value(),
});
session_.CreateFilePayloads(file_infos);
session_.CreateTextPayloads();
session_.CreateWifiCredentialsPayloads();
MockFunction<void(int64_t, TransferMetadata)> transfer_metadata_callback;
StrictMock<MockFunction<void(
std::unique_ptr<Payload>,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>)>>
send_payload_callback;
FakeNearbyConnectionsManager connections_manager;
connections_manager.set_send_payload_callback(
send_payload_callback.AsStdFunction());
EXPECT_CALL(send_payload_callback, Call(_, _))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(file1_.id());
}));
EXPECT_CALL(mock_event_logger_,
Log(Matcher<const SharingLog&>(
AllOf((HasCategory(EventCategory::SENDING_EVENT),
HasEventType(EventType::SEND_ATTACHMENTS_START),
Property(&SharingLog::send_attachments_start,
HasSessionId(1234)))))));
FakeNearbyConnection connection;
session_.OnConnected(decoder_, absl::Now(), &connection);
session_.SendPayloads(
/*enable_transfer_cancellation_optimization=*/
true, &fake_clock_, connections_manager,
[](std::optional<V1Frame> frame) {},
transfer_metadata_callback.AsStdFunction());
EXPECT_CALL(send_payload_callback, Call(_, _))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(text1_.id());
}));
session_.SendNextPayload(connections_manager);
EXPECT_CALL(send_payload_callback, Call(_, _))
.WillOnce(Invoke(
[this](
std::unique_ptr<Payload> payload,
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
payload->id = session_.attachment_payload_map().at(text2_.id());
}));
session_.SendNextPayload(connections_manager);
}
TEST_F(OutgoingShareSessionTest, ProcessKeyVerificationResultFail) {