mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Move accept timeout into outgoingShareSession.
PiperOrigin-RevId: 652626672
This commit is contained in:
committed by
Copybara-Service
parent
907ad97e8d
commit
b166682810
@@ -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
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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>>
|
||||
|
||||
@@ -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_);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user