mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Move remaining payload processing into ShareTargetInfo.
PiperOrigin-RevId: 646185948
This commit is contained in:
committed by
Copybara-Service
parent
cdd6870af2
commit
822e1af2a5
+6
-1
@@ -199,7 +199,6 @@ cc_library(
|
||||
"//sharing/internal/public:types",
|
||||
"//sharing/proto:wire_format_cc_proto",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:string_view",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:span",
|
||||
@@ -758,12 +757,15 @@ cc_test(
|
||||
":attachments",
|
||||
":connection_types",
|
||||
":share_target_info",
|
||||
":test_support",
|
||||
":transfer_metadata",
|
||||
":types",
|
||||
"//internal/platform/implementation/g3", # fixdeps: keep
|
||||
"//sharing/internal/test:nearby_test",
|
||||
"//sharing/proto:wire_format_cc_proto",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/strings:string_view",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
@@ -774,11 +776,14 @@ cc_test(
|
||||
deps = [
|
||||
":attachment_compare",
|
||||
":attachments",
|
||||
":connection_types",
|
||||
":share_target_info",
|
||||
":test_support",
|
||||
":transfer_metadata",
|
||||
":types",
|
||||
"//internal/platform/implementation/g3", # fixdeps: keep
|
||||
"//sharing/internal/public:logging",
|
||||
"//sharing/internal/test:nearby_test",
|
||||
"//sharing/proto:wire_format_cc_proto",
|
||||
"//third_party/protobuf",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
|
||||
@@ -83,20 +83,4 @@ void AttachmentContainer::Clear() {
|
||||
wifi_credentials_attachments_.clear();
|
||||
}
|
||||
|
||||
std::vector<int64_t> AttachmentContainer::GetAttachmentIds() const {
|
||||
std::vector<int64_t> attachment_ids;
|
||||
|
||||
attachment_ids.reserve(GetAttachmentCount());
|
||||
for (const auto& file : file_attachments_)
|
||||
attachment_ids.push_back(file.id());
|
||||
|
||||
for (const auto& text : text_attachments_)
|
||||
attachment_ids.push_back(text.id());
|
||||
|
||||
for (const auto& wifi_credentials : wifi_credentials_attachments_)
|
||||
attachment_ids.push_back(wifi_credentials.id());
|
||||
|
||||
return attachment_ids;
|
||||
}
|
||||
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -99,9 +99,6 @@ class AttachmentContainer {
|
||||
// Delete all attachments.
|
||||
void Clear();
|
||||
|
||||
// Returns the list of attachment IDs of attachments in this container.
|
||||
std::vector<int64_t> GetAttachmentIds() const;
|
||||
|
||||
private:
|
||||
std::vector<TextAttachment> text_attachments_;
|
||||
std::vector<FileAttachment> file_attachments_;
|
||||
|
||||
@@ -192,19 +192,6 @@ TEST_F(AttachmentContainerTest, Clear) {
|
||||
EXPECT_THAT(container.HasAttachments(), IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, GetAttachmentIds) {
|
||||
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
std::vector<WifiCredentialsAttachment>{wifi1_});
|
||||
|
||||
std::vector<int64_t> attachment_ids = container.GetAttachmentIds();
|
||||
|
||||
EXPECT_THAT(attachment_ids, SizeIs(4));
|
||||
EXPECT_THAT(attachment_ids,
|
||||
UnorderedElementsAre(text1_.id(), text2_.id(), file1_.id(),
|
||||
wifi1_.id()));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, GetStorageSize) {
|
||||
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
|
||||
@@ -15,17 +15,26 @@
|
||||
#include "sharing/incoming_share_target_info.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem> // NOLINT
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/common/compatible_u8_string.h"
|
||||
#include "sharing/constants.h"
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/internal/public/context.h"
|
||||
#include "sharing/internal/public/logging.h"
|
||||
#include "sharing/nearby_connection.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
#include "sharing/payload_tracker.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/share_target_info.h"
|
||||
@@ -37,6 +46,7 @@ namespace nearby::sharing {
|
||||
namespace {
|
||||
|
||||
using ::nearby::sharing::service::proto::IntroductionFrame;
|
||||
using ::nearby::sharing::service::proto::WifiCredentials;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -139,4 +149,174 @@ IncomingShareTargetInfo::ProcessIntroduction(
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void IncomingShareTargetInfo::RegisterPayloadListener(
|
||||
Context* context,
|
||||
NearbyConnectionsManager& connections_manager,
|
||||
std::function<void(int64_t, TransferMetadata)> update_callback) {
|
||||
const absl::flat_hash_map<int64_t, int64_t>& payload_map =
|
||||
attachment_payload_map();
|
||||
set_payload_tracker(std::make_shared<PayloadTracker>(
|
||||
context, share_target().id, attachment_container(),
|
||||
payload_map, std::move(update_callback)));
|
||||
|
||||
// Register status listener for all payloads.
|
||||
for (auto it = payload_map.begin(); it != payload_map.end(); ++it) {
|
||||
NL_VLOG(1) << __func__ << ": Started listening for progress on payload: "
|
||||
<< it->second << " for attachment: " << it->first;
|
||||
|
||||
connections_manager.RegisterPayloadStatusListener(it->second,
|
||||
payload_tracker());
|
||||
|
||||
NL_VLOG(1) << __func__ << ": Accepted incoming files from share target - "
|
||||
<< share_target().id;
|
||||
}
|
||||
}
|
||||
|
||||
bool IncomingShareTargetInfo::UpdateFilePayloadPaths(
|
||||
const NearbyConnectionsManager& connections_manager) {
|
||||
AttachmentContainer& container = mutable_attachment_container();
|
||||
bool result = true;
|
||||
for (int i = 0; i < container.GetFileAttachments().size(); ++i) {
|
||||
FileAttachment& file = container.GetMutableFileAttachment(i);
|
||||
// Skip file if it already has file_path set.
|
||||
if (file.file_path().has_value()) {
|
||||
continue;
|
||||
}
|
||||
const auto it = attachment_payload_map().find(file.id());
|
||||
if (it == attachment_payload_map().end()) {
|
||||
NL_LOG(WARNING) << __func__ << ": No payload id found for file - "
|
||||
<< file.id();
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
const Payload* incoming_payload =
|
||||
connections_manager.GetIncomingPayload(it->second);
|
||||
if (!incoming_payload || !incoming_payload->content.is_file()) {
|
||||
NL_LOG(WARNING) << __func__ << ": No payload found for file - "
|
||||
<< file.id();
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto file_path = incoming_payload->content.file_payload.file.path;
|
||||
NL_VLOG(1) << __func__ << ": Updated file_path="
|
||||
<< GetCompatibleU8String(file_path.u8string());
|
||||
file.set_file_path(file_path);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IncomingShareTargetInfo::UpdatePayloadContents(
|
||||
const NearbyConnectionsManager& connections_manager) {
|
||||
if (!UpdateFilePayloadPaths(connections_manager)) {
|
||||
return false;
|
||||
}
|
||||
AttachmentContainer& container = mutable_attachment_container();
|
||||
for (int i = 0; i < container.GetTextAttachments().size(); ++i) {
|
||||
TextAttachment& text = container.GetMutableTextAttachment(i);
|
||||
const auto it = attachment_payload_map().find(text.id());
|
||||
if (it == attachment_payload_map().end()) {
|
||||
// This should never happen unless IntroductionFrame has not been
|
||||
// processed.
|
||||
NL_LOG(WARNING) << __func__ << ": No payload id found for text - "
|
||||
<< text.id();
|
||||
return false;
|
||||
}
|
||||
const Payload* incoming_payload =
|
||||
connections_manager.GetIncomingPayload(it->second);
|
||||
if (!incoming_payload || !incoming_payload->content.is_bytes()) {
|
||||
NL_LOG(WARNING) << __func__ << ": No payload found for text - "
|
||||
<< text.id();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> bytes = incoming_payload->content.bytes_payload.bytes;
|
||||
if (bytes.empty()) {
|
||||
NL_LOG(WARNING)
|
||||
<< __func__
|
||||
<< ": Incoming bytes is empty for text payload with payload_id - "
|
||||
<< it->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string text_body(bytes.begin(), bytes.end());
|
||||
text.set_text_body(text_body);
|
||||
}
|
||||
|
||||
for (int i = 0; i < container.GetWifiCredentialsAttachments().size(); ++i) {
|
||||
WifiCredentialsAttachment& wifi_credentials_attachment =
|
||||
container.GetMutableWifiCredentialsAttachment(i);
|
||||
const auto it =
|
||||
attachment_payload_map().find(wifi_credentials_attachment.id());
|
||||
if (it == attachment_payload_map().end()) {
|
||||
// This should never happen unless IntroductionFrame has not been
|
||||
// processed.
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": No payload id found for WiFi credentials - "
|
||||
<< wifi_credentials_attachment.id();
|
||||
return false;
|
||||
}
|
||||
|
||||
const Payload* incoming_payload =
|
||||
connections_manager.GetIncomingPayload(it->second);
|
||||
if (!incoming_payload || !incoming_payload->content.is_bytes()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": No payload found for WiFi credentials - "
|
||||
<< wifi_credentials_attachment.id();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> bytes = incoming_payload->content.bytes_payload.bytes;
|
||||
if (bytes.empty()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": Incoming bytes is empty for WiFi credentials "
|
||||
"payload with payload_id - "
|
||||
<< it->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
WifiCredentials wifi_credentials;
|
||||
if (!wifi_credentials.ParseFromArray(bytes.data(), bytes.size())) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": Incoming bytes is invalid for WiFi credentials "
|
||||
"payload with payload_id - "
|
||||
<< it->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
wifi_credentials_attachment.set_password(wifi_credentials.password());
|
||||
wifi_credentials_attachment.set_is_hidden(wifi_credentials.hidden_ssid());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncomingShareTargetInfo::FinalizePayloads(
|
||||
const NearbyConnectionsManager& connections_manager) {
|
||||
if (!UpdatePayloadContents(connections_manager)) {
|
||||
mutable_attachment_container().ClearAttachments();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path>
|
||||
IncomingShareTargetInfo::GetPayloadFilePaths() const {
|
||||
std::vector<std::filesystem::path> file_paths;
|
||||
const AttachmentContainer& container = attachment_container();
|
||||
const absl::flat_hash_map<int64_t, int64_t>& attachment_paylod_map =
|
||||
attachment_payload_map();
|
||||
for (const auto& file : container.GetFileAttachments()) {
|
||||
if (!file.file_path().has_value()) continue;
|
||||
auto file_path = *file.file_path();
|
||||
NL_VLOG(1) << __func__
|
||||
<< ": file_path=" << GetCompatibleU8String(file_path.u8string());
|
||||
if (attachment_paylod_map.find(file.id()) == attachment_paylod_map.end()) {
|
||||
continue;
|
||||
}
|
||||
file_paths.push_back(file_path);
|
||||
}
|
||||
return file_paths;
|
||||
}
|
||||
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -15,10 +15,16 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_SHARING_INCOMING_SHARE_TARGET_INFO_H_
|
||||
#define THIRD_PARTY_NEARBY_SHARING_INCOMING_SHARE_TARGET_INFO_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem> // NOLINT
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "sharing/internal/public/context.h"
|
||||
#include "sharing/nearby_connection.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/share_target_info.h"
|
||||
@@ -46,11 +52,32 @@ class IncomingShareTargetInfo : public ShareTargetInfo {
|
||||
const nearby::sharing::service::proto::IntroductionFrame&
|
||||
introduction_frame);
|
||||
|
||||
// Update file attachment paths with payload paths.
|
||||
bool UpdateFilePayloadPaths(
|
||||
const NearbyConnectionsManager& connections_manager);
|
||||
|
||||
void RegisterPayloadListener(
|
||||
Context* context,
|
||||
NearbyConnectionsManager& connections_manager,
|
||||
std::function<void(int64_t, TransferMetadata)> update_callback);
|
||||
|
||||
// Once transfer has completed, make payload content available in the
|
||||
// corresponding Attachment.
|
||||
// Returns true if all payloads were successfully finalized.
|
||||
bool FinalizePayloads(const NearbyConnectionsManager& connections_manager);
|
||||
|
||||
// Returns the file paths of all file payloads.
|
||||
std::vector<std::filesystem::path> GetPayloadFilePaths() const;
|
||||
|
||||
protected:
|
||||
void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override;
|
||||
bool OnNewConnection(NearbyConnection* connection) override;
|
||||
|
||||
private:
|
||||
// Copy payload contents from the NearbyConnection to the Attachment.
|
||||
bool UpdatePayloadContents(
|
||||
const NearbyConnectionsManager& connections_manager);
|
||||
|
||||
std::function<void(const IncomingShareTargetInfo&, const TransferMetadata&)>
|
||||
transfer_update_callback_;
|
||||
};
|
||||
|
||||
@@ -15,18 +15,24 @@
|
||||
#include "sharing/incoming_share_target_info.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem> // NOLINT
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "sharing/attachment_compare.h" // IWYU pragma: keep
|
||||
#include "sharing/fake_nearby_connections_manager.h"
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/internal/public/logging.h"
|
||||
#include "sharing/internal/test/fake_context.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
@@ -40,14 +46,43 @@ namespace {
|
||||
using ::nearby::sharing::service::proto::FileMetadata;
|
||||
using ::nearby::sharing::service::proto::IntroductionFrame;
|
||||
using ::nearby::sharing::service::proto::TextMetadata;
|
||||
using ::nearby::sharing::service::proto::WifiCredentials;
|
||||
using ::nearby::sharing::service::proto::WifiCredentialsMetadata;
|
||||
using ::testing::Eq;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::IsFalse;
|
||||
using ::testing::IsTrue;
|
||||
using ::testing::UnorderedElementsAre;
|
||||
|
||||
constexpr absl::string_view kEndpointId = "ABCD";
|
||||
|
||||
std::unique_ptr<Payload> CreateFilePayload(int64_t payload_id,
|
||||
std::filesystem::path file_path) {
|
||||
auto file_payload =
|
||||
std::make_unique<Payload>(InputFile(std::move(file_path)));
|
||||
file_payload->id = payload_id;
|
||||
return file_payload;
|
||||
}
|
||||
|
||||
std::unique_ptr<Payload> CreateTextPayload(int64_t payload_id,
|
||||
std::string text_body) {
|
||||
auto text_payload =
|
||||
std::make_unique<Payload>(text_body.data(), text_body.size());
|
||||
text_payload->id = payload_id;
|
||||
return text_payload;
|
||||
}
|
||||
|
||||
std::unique_ptr<Payload> CreateWifiCredentialsPayload(
|
||||
int64_t payload_id, const std::string& password, bool is_hidden) {
|
||||
WifiCredentials wifi_credentials;
|
||||
wifi_credentials.set_password(password);
|
||||
wifi_credentials.set_hidden_ssid(is_hidden);
|
||||
std::string wifi_content = wifi_credentials.SerializeAsString();
|
||||
auto wifi_payload =
|
||||
std::make_unique<Payload>(wifi_content.data(), wifi_content.size());
|
||||
wifi_payload->id = payload_id;
|
||||
return wifi_payload;
|
||||
}
|
||||
class IncomingShareTargetInfoTest : public ::testing::Test {
|
||||
protected:
|
||||
IncomingShareTargetInfoTest()
|
||||
@@ -193,5 +228,316 @@ TEST_F(IncomingShareTargetInfoTest, ProcessIntroductionSuccess) {
|
||||
EXPECT_THAT(info_.attachment_payload_map().at(wifimeta2.id()),
|
||||
Eq(wifimeta2.payload_id()));
|
||||
}
|
||||
|
||||
TEST_F(IncomingShareTargetInfoTest, UpdateFilePayloadPathsSuccess) {
|
||||
EXPECT_THAT(info_.ProcessIntroduction(introduction_frame_), Eq(std::nullopt));
|
||||
FakeNearbyConnectionsManager connections_manager;
|
||||
std::filesystem::path file1_path = "/usr/tmp/file1";
|
||||
int64_t payload_id1 = introduction_frame_.file_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id1, CreateFilePayload(payload_id1, file1_path));
|
||||
|
||||
std::filesystem::path file2_path = "/usr/tmp/file2";
|
||||
int64_t payload_id2 = introduction_frame_.file_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id2, CreateFilePayload(payload_id2, file2_path));
|
||||
|
||||
EXPECT_THAT(info_.UpdateFilePayloadPaths(connections_manager), IsTrue());
|
||||
EXPECT_THAT(info_.attachment_container().GetFileAttachments()[0].file_path(),
|
||||
Eq(file1_path));
|
||||
EXPECT_THAT(info_.attachment_container().GetFileAttachments()[1].file_path(),
|
||||
Eq(file2_path));
|
||||
}
|
||||
|
||||
TEST_F(IncomingShareTargetInfoTest, UpdateFilePayloadPathsWrongType) {
|
||||
EXPECT_THAT(info_.ProcessIntroduction(introduction_frame_), Eq(std::nullopt));
|
||||
FakeNearbyConnectionsManager connections_manager;
|
||||
int64_t payload_id1 = introduction_frame_.file_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id1, CreateTextPayload(payload_id1, "text1"));
|
||||
|
||||
std::filesystem::path file2_path = "/usr/tmp/file2";
|
||||
int64_t payload_id2 = introduction_frame_.file_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id2, CreateFilePayload(payload_id2, file2_path));
|
||||
|
||||
EXPECT_THAT(info_.UpdateFilePayloadPaths(connections_manager), IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(IncomingShareTargetInfoTest, GetPayloadFilePaths) {
|
||||
EXPECT_THAT(info_.ProcessIntroduction(introduction_frame_), Eq(std::nullopt));
|
||||
FakeNearbyConnectionsManager connections_manager;
|
||||
std::filesystem::path file1_path = "/usr/tmp/file1";
|
||||
int64_t payload_id1 = introduction_frame_.file_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id1, CreateFilePayload(payload_id1, file1_path));
|
||||
|
||||
std::filesystem::path file2_path = "/usr/tmp/file2";
|
||||
int64_t payload_id2 = introduction_frame_.file_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id2, CreateFilePayload(payload_id2, file2_path));
|
||||
EXPECT_THAT(info_.UpdateFilePayloadPaths(connections_manager), IsTrue());
|
||||
|
||||
std::vector<std::filesystem::path> file_paths = info_.GetPayloadFilePaths();
|
||||
|
||||
EXPECT_THAT(file_paths, UnorderedElementsAre(file1_path, file2_path));
|
||||
}
|
||||
|
||||
TEST_F(IncomingShareTargetInfoTest, FinalizePayloadsSuccess) {
|
||||
EXPECT_THAT(info_.ProcessIntroduction(introduction_frame_), Eq(std::nullopt));
|
||||
FakeNearbyConnectionsManager connections_manager;
|
||||
std::filesystem::path file1_path = "/usr/tmp/file1";
|
||||
int64_t payload_id1 = introduction_frame_.file_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id1, CreateFilePayload(payload_id1, file1_path));
|
||||
|
||||
std::filesystem::path file2_path = "/usr/tmp/file2";
|
||||
int64_t payload_id2 = introduction_frame_.file_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id2, CreateFilePayload(payload_id2, file2_path));
|
||||
EXPECT_THAT(info_.UpdateFilePayloadPaths(connections_manager), IsTrue());
|
||||
|
||||
std::string text_content1 = "text1";
|
||||
int64_t text_payload_id1 = introduction_frame_.text_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
text_payload_id1, CreateTextPayload(text_payload_id1, text_content1));
|
||||
|
||||
std::string text_content2 = "text2";
|
||||
int64_t text_payload_id2 = introduction_frame_.text_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
text_payload_id2, CreateTextPayload(text_payload_id2, text_content2));
|
||||
|
||||
int64_t wifi_payload_id1 =
|
||||
introduction_frame_.wifi_credentials_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
wifi_payload_id1,
|
||||
CreateWifiCredentialsPayload(wifi_payload_id1, "password1", false));
|
||||
|
||||
int64_t wifi_payload_id2 =
|
||||
introduction_frame_.wifi_credentials_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
wifi_payload_id2,
|
||||
CreateWifiCredentialsPayload(wifi_payload_id2, "password2", true));
|
||||
|
||||
EXPECT_THAT(info_.FinalizePayloads(connections_manager), IsTrue());
|
||||
EXPECT_THAT(info_.attachment_container().GetFileAttachments()[0].file_path(),
|
||||
Eq(file1_path));
|
||||
EXPECT_THAT(info_.attachment_container().GetFileAttachments()[1].file_path(),
|
||||
Eq(file2_path));
|
||||
EXPECT_THAT(info_.attachment_container().GetTextAttachments()[0].text_body(),
|
||||
Eq(text_content1));
|
||||
EXPECT_THAT(info_.attachment_container().GetTextAttachments()[1].text_body(),
|
||||
Eq(text_content2));
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[0].password(),
|
||||
Eq("password1"));
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[0]
|
||||
.is_hidden(),
|
||||
IsFalse());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[1]
|
||||
.password(),
|
||||
Eq("password2"));
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[1]
|
||||
.is_hidden(),
|
||||
IsTrue());
|
||||
}
|
||||
|
||||
TEST_F(IncomingShareTargetInfoTest, FinalizePayloadsMissingFilePayloads) {
|
||||
EXPECT_THAT(info_.ProcessIntroduction(introduction_frame_), Eq(std::nullopt));
|
||||
FakeNearbyConnectionsManager connections_manager;
|
||||
std::filesystem::path file1_path = "/usr/tmp/file1";
|
||||
int64_t payload_id1 = introduction_frame_.file_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id1, CreateFilePayload(payload_id1, file1_path));
|
||||
EXPECT_THAT(info_.UpdateFilePayloadPaths(connections_manager), IsFalse());
|
||||
|
||||
std::string text_content1 = "text1";
|
||||
int64_t text_payload_id1 = introduction_frame_.text_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
text_payload_id1, CreateTextPayload(text_payload_id1, text_content1));
|
||||
|
||||
std::string text_content2 = "text2";
|
||||
int64_t text_payload_id2 = introduction_frame_.text_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
text_payload_id2, CreateTextPayload(text_payload_id2, text_content2));
|
||||
|
||||
int64_t wifi_payload_id1 =
|
||||
introduction_frame_.wifi_credentials_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
wifi_payload_id1,
|
||||
CreateWifiCredentialsPayload(wifi_payload_id1, "password1", false));
|
||||
|
||||
int64_t wifi_payload_id2 =
|
||||
introduction_frame_.wifi_credentials_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
wifi_payload_id2,
|
||||
CreateWifiCredentialsPayload(wifi_payload_id2, "password2", true));
|
||||
|
||||
EXPECT_THAT(info_.FinalizePayloads(connections_manager), IsFalse());
|
||||
|
||||
// Verify that attachments are cleared out
|
||||
EXPECT_THAT(info_.attachment_container().GetFileAttachments()[0].file_path(),
|
||||
Eq(std::nullopt));
|
||||
EXPECT_THAT(info_.attachment_container().GetFileAttachments()[1].file_path(),
|
||||
Eq(std::nullopt));
|
||||
EXPECT_THAT(info_.attachment_container().GetTextAttachments()[0].text_body(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container().GetTextAttachments()[1].text_body(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[0].password(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[0]
|
||||
.is_hidden(),
|
||||
IsFalse());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[1]
|
||||
.password(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[1]
|
||||
.is_hidden(),
|
||||
IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(IncomingShareTargetInfoTest, FinalizePayloadsMissingTextPayloads) {
|
||||
EXPECT_THAT(info_.ProcessIntroduction(introduction_frame_), Eq(std::nullopt));
|
||||
FakeNearbyConnectionsManager connections_manager;
|
||||
std::filesystem::path file1_path = "/usr/tmp/file1";
|
||||
int64_t payload_id1 = introduction_frame_.file_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id1, CreateFilePayload(payload_id1, file1_path));
|
||||
EXPECT_THAT(info_.UpdateFilePayloadPaths(connections_manager), IsFalse());
|
||||
|
||||
std::filesystem::path file2_path = "/usr/tmp/file2";
|
||||
int64_t payload_id2 = introduction_frame_.file_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id2, CreateFilePayload(payload_id2, file2_path));
|
||||
EXPECT_THAT(info_.UpdateFilePayloadPaths(connections_manager), IsTrue());
|
||||
|
||||
std::string text_content1 = "text1";
|
||||
int64_t text_payload_id1 = introduction_frame_.text_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
text_payload_id1, CreateTextPayload(text_payload_id1, text_content1));
|
||||
|
||||
int64_t wifi_payload_id1 =
|
||||
introduction_frame_.wifi_credentials_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
wifi_payload_id1,
|
||||
CreateWifiCredentialsPayload(wifi_payload_id1, "password1", false));
|
||||
|
||||
int64_t wifi_payload_id2 =
|
||||
introduction_frame_.wifi_credentials_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
wifi_payload_id2,
|
||||
CreateWifiCredentialsPayload(wifi_payload_id2, "password2", true));
|
||||
|
||||
EXPECT_THAT(info_.FinalizePayloads(connections_manager), IsFalse());
|
||||
|
||||
// Verify that attachments are cleared out
|
||||
EXPECT_THAT(info_.attachment_container().GetFileAttachments()[0].file_path(),
|
||||
Eq(std::nullopt));
|
||||
EXPECT_THAT(info_.attachment_container().GetFileAttachments()[1].file_path(),
|
||||
Eq(std::nullopt));
|
||||
EXPECT_THAT(info_.attachment_container().GetTextAttachments()[0].text_body(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container().GetTextAttachments()[1].text_body(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[0].password(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[0]
|
||||
.is_hidden(),
|
||||
IsFalse());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[1]
|
||||
.password(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[1]
|
||||
.is_hidden(),
|
||||
IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(IncomingShareTargetInfoTest, FinalizePayloadsMissingWifiPayloads) {
|
||||
EXPECT_THAT(info_.ProcessIntroduction(introduction_frame_), Eq(std::nullopt));
|
||||
FakeNearbyConnectionsManager connections_manager;
|
||||
std::filesystem::path file1_path = "/usr/tmp/file1";
|
||||
int64_t payload_id1 = introduction_frame_.file_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id1, CreateFilePayload(payload_id1, file1_path));
|
||||
EXPECT_THAT(info_.UpdateFilePayloadPaths(connections_manager), IsFalse());
|
||||
|
||||
std::filesystem::path file2_path = "/usr/tmp/file2";
|
||||
int64_t payload_id2 = introduction_frame_.file_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
payload_id2, CreateFilePayload(payload_id2, file2_path));
|
||||
EXPECT_THAT(info_.UpdateFilePayloadPaths(connections_manager), IsTrue());
|
||||
|
||||
std::string text_content1 = "text1";
|
||||
int64_t text_payload_id1 = introduction_frame_.text_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
text_payload_id1, CreateTextPayload(text_payload_id1, text_content1));
|
||||
|
||||
std::string text_content2 = "text2";
|
||||
int64_t text_payload_id2 = introduction_frame_.text_metadata(1).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
text_payload_id2, CreateTextPayload(text_payload_id2, text_content2));
|
||||
|
||||
int64_t wifi_payload_id1 =
|
||||
introduction_frame_.wifi_credentials_metadata(0).payload_id();
|
||||
connections_manager.SetIncomingPayload(
|
||||
wifi_payload_id1,
|
||||
CreateWifiCredentialsPayload(wifi_payload_id1, "password1", false));
|
||||
|
||||
EXPECT_THAT(info_.FinalizePayloads(connections_manager), IsFalse());
|
||||
|
||||
// Verify that attachments are cleared out
|
||||
EXPECT_THAT(info_.attachment_container().GetFileAttachments()[0].file_path(),
|
||||
Eq(std::nullopt));
|
||||
EXPECT_THAT(info_.attachment_container().GetFileAttachments()[1].file_path(),
|
||||
Eq(std::nullopt));
|
||||
EXPECT_THAT(info_.attachment_container().GetTextAttachments()[0].text_body(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container().GetTextAttachments()[1].text_body(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[0].password(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[0]
|
||||
.is_hidden(),
|
||||
IsFalse());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[1]
|
||||
.password(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(info_.attachment_container()
|
||||
.GetWifiCredentialsAttachments()[1]
|
||||
.is_hidden(),
|
||||
IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(IncomingShareTargetInfoTest, RegisterPayloadListenerSuccess) {
|
||||
EXPECT_THAT(info_.ProcessIntroduction(introduction_frame_), Eq(std::nullopt));
|
||||
FakeNearbyConnectionsManager connections_manager;
|
||||
FakeContext context;
|
||||
|
||||
info_.RegisterPayloadListener(&context, connections_manager,
|
||||
[](int64_t, TransferMetadata) {});
|
||||
|
||||
for (auto it : info_.attachment_payload_map()) {
|
||||
EXPECT_THAT(
|
||||
connections_manager.GetRegisteredPayloadStatusListener(it.second)
|
||||
.lock(),
|
||||
Eq(info_.payload_tracker().lock()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
#include "sharing/certificates/nearby_share_certificate_manager_impl.h"
|
||||
#include "sharing/certificates/nearby_share_decrypted_public_certificate.h"
|
||||
#include "sharing/certificates/nearby_share_encrypted_metadata_key.h"
|
||||
#include "sharing/common/compatible_u8_string.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/common/nearby_share_prefs.h"
|
||||
#include "sharing/constants.h"
|
||||
@@ -93,7 +92,6 @@
|
||||
#include "sharing/nearby_sharing_util.h"
|
||||
#include "sharing/outgoing_share_target_info.h"
|
||||
#include "sharing/paired_key_verification_runner.h"
|
||||
#include "sharing/payload_tracker.h"
|
||||
#include "sharing/proto/encrypted_metadata.pb.h"
|
||||
#include "sharing/proto/enums.pb.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
@@ -101,11 +99,9 @@
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/share_target_discovered_callback.h"
|
||||
#include "sharing/share_target_info.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
#include "sharing/transfer_metadata.h"
|
||||
#include "sharing/transfer_metadata_builder.h"
|
||||
#include "sharing/transfer_update_callback.h"
|
||||
#include "sharing/wifi_credentials_attachment.h"
|
||||
#include "sharing/wrapped_share_target_discovered_callback.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
@@ -115,7 +111,6 @@ using BlockedVendorId = ::nearby::sharing::Advertisement::BlockedVendorId;
|
||||
using ::nearby::sharing::api::SharingPlatform;
|
||||
using ::nearby::sharing::proto::DataUsage;
|
||||
using ::nearby::sharing::proto::DeviceVisibility;
|
||||
using Type = ::nearby::sharing::service::proto::TextMetadata;
|
||||
using ::location::nearby::proto::sharing::AttachmentTransmissionStatus;
|
||||
using ::location::nearby::proto::sharing::EstablishConnectionStatus;
|
||||
using ::location::nearby::proto::sharing::OSType;
|
||||
@@ -350,7 +345,6 @@ void NearbySharingServiceImpl::Cleanup() {
|
||||
|
||||
last_incoming_metadata_.reset();
|
||||
last_outgoing_metadata_.reset();
|
||||
attachment_payload_map_.clear();
|
||||
locally_cancelled_share_target_ids_.clear();
|
||||
|
||||
mutual_acceptance_timeout_alarm_->Stop();
|
||||
@@ -824,7 +818,7 @@ void NearbySharingServiceImpl::Accept(
|
||||
std::move(status_codes_callback)(StatusCodes::kInvalidArgument);
|
||||
return;
|
||||
}
|
||||
if (!info->connection()) {
|
||||
if (!info->IsConnected()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": Accept invoked for unconnected share target";
|
||||
std::move(status_codes_callback)(StatusCodes::kOutOfOrderApiCall);
|
||||
@@ -847,8 +841,10 @@ void NearbySharingServiceImpl::Accept(
|
||||
|
||||
is_waiting_to_record_accept_to_transfer_start_metric_ = is_incoming;
|
||||
if (is_incoming) {
|
||||
IncomingShareTargetInfo* incoming_info =
|
||||
GetIncomingShareTargetInfo(share_target_id);
|
||||
incoming_share_accepted_timestamp_ = context_->GetClock()->Now();
|
||||
ReceivePayloads(*info, std::move(status_codes_callback));
|
||||
ReceivePayloads(*incoming_info, std::move(status_codes_callback));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -874,7 +870,7 @@ void NearbySharingServiceImpl::Reject(
|
||||
std::move(status_codes_callback)(StatusCodes::kInvalidArgument);
|
||||
return;
|
||||
}
|
||||
if (!info->connection()) {
|
||||
if (!info->IsConnected()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": Reject invoked for unconnected share target";
|
||||
std::move(status_codes_callback)(StatusCodes::kOutOfOrderApiCall);
|
||||
@@ -887,10 +883,8 @@ void NearbySharingServiceImpl::Reject(
|
||||
// kRejected status already sent below, no need to send on disconnect.
|
||||
info->set_disconnect_status(TransferMetadata::Status::kUnknown);
|
||||
|
||||
NearbyConnection* connection = info->connection();
|
||||
WriteResponseFrame(
|
||||
*connection,
|
||||
nearby::sharing::service::proto::ConnectionResponseFrame::REJECT);
|
||||
info->WriteResponseFrame(
|
||||
service::proto::ConnectionResponseFrame::REJECT);
|
||||
NL_VLOG(1) << __func__
|
||||
<< ": Successfully wrote a rejection response frame";
|
||||
|
||||
@@ -945,13 +939,7 @@ void NearbySharingServiceImpl::DoCancel(
|
||||
// cancellation signals. Also, note that there might not be any ongoing
|
||||
// payload transfer, for example, if a connection has not been established
|
||||
// yet.
|
||||
for (int64_t attachment_id :
|
||||
info->attachment_container().GetAttachmentIds()) {
|
||||
std::optional<int64_t> payload_id = GetAttachmentPayloadId(attachment_id);
|
||||
if (payload_id) {
|
||||
nearby_connections_manager_->Cancel(*payload_id);
|
||||
}
|
||||
}
|
||||
info->CancelPayloads(*nearby_connections_manager_);
|
||||
|
||||
// Inform the user that the transfer has been cancelled before disconnecting
|
||||
// because subsequent disconnections might be interpreted as failure.
|
||||
@@ -971,7 +959,7 @@ void NearbySharingServiceImpl::DoCancel(
|
||||
// from endpoint id directly. Note: A share attempt can be cancelled by the
|
||||
// user before a connection is fully established, in which case,
|
||||
// info->connection() will be null.
|
||||
if (info->connection()) {
|
||||
if (info->IsConnected()) {
|
||||
NL_LOG(INFO) << "Disconnect fully established endpoint id:"
|
||||
<< info->endpoint_id();
|
||||
if (is_initiator_of_cancellation) {
|
||||
@@ -985,7 +973,7 @@ void NearbySharingServiceImpl::DoCancel(
|
||||
CloseConnection(share_target_id);
|
||||
});
|
||||
|
||||
WriteCancelFrame(*info->connection());
|
||||
info->WriteCancelFrame();
|
||||
} else {
|
||||
info->connection()->Close();
|
||||
}
|
||||
@@ -2499,34 +2487,46 @@ void NearbySharingServiceImpl::OnTransferStarted(bool is_incoming) {
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::ReceivePayloads(
|
||||
ShareTargetInfo& share_target_info,
|
||||
IncomingShareTargetInfo& share_target_info,
|
||||
std::function<void(StatusCodes status_codes)> status_codes_callback) {
|
||||
mutual_acceptance_timeout_alarm_->Stop();
|
||||
|
||||
std::filesystem::path download_path =
|
||||
std::filesystem::u8path(settings_->GetCustomSavePath());
|
||||
// Log analytics event of starting to receive payloads.
|
||||
analytics_recorder_->NewReceiveAttachmentsStart(
|
||||
receiving_session_id_, share_target_info.attachment_container());
|
||||
share_target_info.RegisterPayloadListener(
|
||||
context_, *nearby_connections_manager_,
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnPayloadTransferUpdate,
|
||||
this));
|
||||
share_target_info.WriteResponseFrame(
|
||||
nearby::sharing::service::proto::ConnectionResponseFrame::ACCEPT);
|
||||
NL_VLOG(1) << __func__ << ": Successfully wrote response frame";
|
||||
|
||||
const AttachmentContainer& container =
|
||||
share_target_info.attachment_container();
|
||||
// Register payload path for all valid file payloads.
|
||||
for (const auto& file : container.GetFileAttachments()) {
|
||||
std::optional<int64_t> payload_id = GetAttachmentPayloadId(file.id());
|
||||
if (!payload_id) {
|
||||
NL_LOG(WARNING)
|
||||
<< __func__
|
||||
<< ": Failed to register payload path for attachment id - "
|
||||
<< file.id();
|
||||
continue;
|
||||
}
|
||||
share_target_info.UpdateTransferMetadata(
|
||||
TransferMetadataBuilder()
|
||||
.set_status(TransferMetadata::Status::kAwaitingRemoteAcceptance)
|
||||
.set_token(share_target_info.token())
|
||||
.build());
|
||||
|
||||
if (share_target_info.attachment_container().GetTotalAttachmentsSize() >=
|
||||
kAttachmentsSizeThresholdOverHighQualityMedium) {
|
||||
// Upgrade bandwidth regardless of advertising visibility because either
|
||||
// the system or the user has verified the sender's identity; the
|
||||
// stable identifiers potentially exposed by performing a bandwidth
|
||||
// upgrade are no longer a concern.
|
||||
NL_LOG(INFO) << __func__ << ": Upgrade bandwidth when receiving accept.";
|
||||
nearby_connections_manager_->UpgradeBandwidth(
|
||||
share_target_info.endpoint_id());
|
||||
}
|
||||
OnPayloadPathsRegistered(share_target_info, std::move(status_codes_callback));
|
||||
|
||||
std::move(status_codes_callback)(StatusCodes::kOk);
|
||||
}
|
||||
|
||||
NearbySharingService::StatusCodes NearbySharingServiceImpl::SendPayloads(
|
||||
ShareTargetInfo& info) {
|
||||
NL_VLOG(1) << __func__ << ": Preparing to send payloads to "
|
||||
<< info.share_target().id;
|
||||
if (!info.connection()) {
|
||||
if (!info.IsConnected()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": Failed to send payload due to missing connection.";
|
||||
return StatusCodes::kOutOfOrderApiCall;
|
||||
@@ -2548,72 +2548,6 @@ NearbySharingService::StatusCodes NearbySharingServiceImpl::SendPayloads(
|
||||
return StatusCodes::kOk;
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnPayloadPathsRegistered(
|
||||
ShareTargetInfo& info,
|
||||
std::function<void(StatusCodes status_codes)> status_codes_callback) {
|
||||
if (!info.connection()) {
|
||||
NL_LOG(WARNING) << __func__ << ": Accept invoked for unknown share target";
|
||||
std::move(status_codes_callback)(StatusCodes::kOutOfOrderApiCall);
|
||||
return;
|
||||
}
|
||||
NearbyConnection* connection = info.connection();
|
||||
|
||||
// Log analytics event of starting to receive payloads.
|
||||
analytics_recorder_->NewReceiveAttachmentsStart(receiving_session_id_,
|
||||
info.attachment_container());
|
||||
|
||||
int64_t share_target_id = info.share_target().id;
|
||||
info.set_payload_tracker(std::make_shared<PayloadTracker>(
|
||||
context_, share_target_id, info.attachment_container(),
|
||||
attachment_payload_map_,
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnPayloadTransferUpdate,
|
||||
this)));
|
||||
|
||||
// Register status listener for all payloads.
|
||||
for (int64_t attachment_id : info.attachment_container().GetAttachmentIds()) {
|
||||
std::optional<int64_t> payload_id = GetAttachmentPayloadId(attachment_id);
|
||||
if (!payload_id) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": Failed to retrieve payload for attachment id - "
|
||||
<< attachment_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
NL_VLOG(1) << __func__ << ": Started listening for progress on payload - "
|
||||
<< *payload_id;
|
||||
|
||||
nearby_connections_manager_->RegisterPayloadStatusListener(
|
||||
*payload_id, info.payload_tracker());
|
||||
|
||||
NL_VLOG(1) << __func__ << ": Accepted incoming files from share target - "
|
||||
<< share_target_id;
|
||||
}
|
||||
|
||||
WriteResponseFrame(
|
||||
*connection,
|
||||
nearby::sharing::service::proto::ConnectionResponseFrame::ACCEPT);
|
||||
NL_VLOG(1) << __func__ << ": Successfully wrote response frame";
|
||||
|
||||
info.UpdateTransferMetadata(
|
||||
TransferMetadataBuilder()
|
||||
.set_status(TransferMetadata::Status::kAwaitingRemoteAcceptance)
|
||||
.set_token(info.token())
|
||||
.build());
|
||||
|
||||
std::string endpoint_id = info.endpoint_id();
|
||||
if (info.attachment_container().GetTotalAttachmentsSize() >=
|
||||
kAttachmentsSizeThresholdOverHighQualityMedium) {
|
||||
// Upgrade bandwidth regardless of advertising visibility because either
|
||||
// the system or the user has verified the sender's identity; the
|
||||
// stable identifiers potentially exposed by performing a bandwidth
|
||||
// upgrade are no longer a concern.
|
||||
NL_LOG(INFO) << __func__ << ": Upgrade bandwidth when receiving accept.";
|
||||
nearby_connections_manager_->UpgradeBandwidth(endpoint_id);
|
||||
}
|
||||
|
||||
std::move(status_codes_callback)(StatusCodes::kOk);
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnOutgoingConnection(
|
||||
absl::Time connect_start_time, NearbyConnection* connection,
|
||||
OutgoingShareTargetInfo& info) {
|
||||
@@ -2668,7 +2602,7 @@ void NearbySharingServiceImpl::SendIntroduction(
|
||||
NL_VLOG(1) << __func__ << ": Preparing to send introduction to "
|
||||
<< info.share_target().id;
|
||||
|
||||
if (!info.connection()) {
|
||||
if (!info.IsConnected()) {
|
||||
NL_LOG(WARNING) << __func__ << ": No NearbyConnection tied to "
|
||||
<< info.share_target().id;
|
||||
return;
|
||||
@@ -2690,30 +2624,15 @@ void NearbySharingServiceImpl::SendIntroduction(
|
||||
return;
|
||||
}
|
||||
|
||||
// Build the introduction.
|
||||
std::unique_ptr<nearby::sharing::service::proto::IntroductionFrame>
|
||||
introduction = info.CreateIntroductionFrame();
|
||||
if (!introduction) {
|
||||
NL_VLOG(1) << __func__ << ": Sending attachments to "
|
||||
<< info.share_target().id;
|
||||
if (!info.WriteIntroductionFrame()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": No payloads tied to transfer, disconnecting.";
|
||||
AbortAndCloseConnectionIfNecessary(
|
||||
TransferMetadata::Status::kMissingPayloads, info.share_target().id);
|
||||
return;
|
||||
}
|
||||
introduction->set_start_transfer(true);
|
||||
NL_VLOG(1) << __func__ << ": Sending attachments to "
|
||||
<< info.share_target().id;
|
||||
|
||||
// Write the introduction to the remote device.
|
||||
nearby::sharing::service::proto::Frame frame;
|
||||
frame.set_version(nearby::sharing::service::proto::Frame::V1);
|
||||
nearby::sharing::service::proto::V1Frame* v1_frame = frame.mutable_v1();
|
||||
v1_frame->set_type(nearby::sharing::service::proto::V1Frame::INTRODUCTION);
|
||||
v1_frame->set_allocated_introduction(introduction.release());
|
||||
|
||||
std::vector<uint8_t> data(frame.ByteSizeLong());
|
||||
frame.SerializeToArray(data.data(), frame.ByteSizeLong());
|
||||
connection->Write(std::move(data));
|
||||
|
||||
// We've successfully written the introduction, so we now have to wait for the
|
||||
// remote side to accept.
|
||||
@@ -2760,7 +2679,6 @@ void NearbySharingServiceImpl::CreatePayloads(
|
||||
return;
|
||||
}
|
||||
bool result = info->CreateFilePayloads(file_infos);
|
||||
attachment_payload_map_ = info->attachment_payload_map();
|
||||
std::move(callback)(*info, result);
|
||||
});
|
||||
});
|
||||
@@ -2826,70 +2744,13 @@ void NearbySharingServiceImpl::OnCreatePayloads(
|
||||
});
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::WriteResponseFrame(
|
||||
NearbyConnection& connection,
|
||||
nearby::sharing::service::proto::ConnectionResponseFrame::Status
|
||||
response_status) {
|
||||
nearby::sharing::service::proto::Frame frame;
|
||||
frame.set_version(nearby::sharing::service::proto::Frame::V1);
|
||||
nearby::sharing::service::proto::V1Frame* v1_frame = frame.mutable_v1();
|
||||
v1_frame->set_type(nearby::sharing::service::proto::V1Frame::RESPONSE);
|
||||
v1_frame->mutable_connection_response()->set_status(response_status);
|
||||
|
||||
std::vector<uint8_t> data(frame.ByteSizeLong());
|
||||
frame.SerializeToArray(data.data(), frame.ByteSizeLong());
|
||||
|
||||
connection.Write(std::move(data));
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::WriteCancelFrame(NearbyConnection& connection) {
|
||||
NL_LOG(INFO) << __func__ << ": Writing cancel frame.";
|
||||
|
||||
nearby::sharing::service::proto::Frame frame;
|
||||
frame.set_version(nearby::sharing::service::proto::Frame::V1);
|
||||
nearby::sharing::service::proto::V1Frame* v1_frame = frame.mutable_v1();
|
||||
v1_frame->set_type(nearby::sharing::service::proto::V1Frame::CANCEL);
|
||||
|
||||
std::vector<uint8_t> data(frame.ByteSizeLong());
|
||||
frame.SerializeToArray(data.data(), frame.ByteSizeLong());
|
||||
|
||||
connection.Write(std::move(data));
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::WriteProgressUpdateFrame(
|
||||
NearbyConnection& connection, std::optional<bool> start_transfer,
|
||||
std::optional<float> progress) {
|
||||
NL_LOG(INFO) << __func__ << ": Writing progress update frame. start_transfer="
|
||||
<< (start_transfer.has_value() ? *start_transfer : false)
|
||||
<< ", progress=" << (progress.has_value() ? *progress : 0.0);
|
||||
nearby::sharing::service::proto::Frame frame;
|
||||
frame.set_version(nearby::sharing::service::proto::Frame::V1);
|
||||
nearby::sharing::service::proto::V1Frame* v1_frame = frame.mutable_v1();
|
||||
v1_frame->set_type(nearby::sharing::service::proto::V1Frame::PROGRESS_UPDATE);
|
||||
nearby::sharing::service::proto::ProgressUpdateFrame* progress_frame =
|
||||
v1_frame->mutable_progress_update();
|
||||
if (start_transfer.has_value()) {
|
||||
progress_frame->set_start_transfer(*start_transfer);
|
||||
}
|
||||
if (progress.has_value()) {
|
||||
progress_frame->set_progress(*progress);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> data(frame.ByteSizeLong());
|
||||
frame.SerializeToArray(data.data(), frame.ByteSizeLong());
|
||||
|
||||
connection.Write(std::move(data));
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::Fail(int64_t share_target_id,
|
||||
TransferMetadata::Status status) {
|
||||
ShareTargetInfo* info = GetShareTargetInfo(share_target_id);
|
||||
if (!info || !info->connection()) {
|
||||
if (!info || !info->IsConnected()) {
|
||||
NL_LOG(WARNING) << __func__ << ": Fail invoked for unknown share target.";
|
||||
return;
|
||||
}
|
||||
NearbyConnection* connection = info->connection();
|
||||
|
||||
RunOnNearbySharingServiceThreadDelayed(
|
||||
"incoming_rejection_delay", kIncomingRejectionDelay,
|
||||
[this, share_target_id]() { CloseConnection(share_target_id); });
|
||||
@@ -2921,8 +2782,7 @@ void NearbySharingServiceImpl::Fail(int64_t share_target_id,
|
||||
break;
|
||||
}
|
||||
|
||||
WriteResponseFrame(*connection, response_status);
|
||||
|
||||
info->WriteResponseFrame(response_status);
|
||||
info->UpdateTransferMetadata(
|
||||
TransferMetadataBuilder().set_status(status).build());
|
||||
}
|
||||
@@ -2932,8 +2792,7 @@ void NearbySharingServiceImpl::OnIncomingAdvertisementDecoded(
|
||||
const IncomingShareTargetInfo& share_target_info,
|
||||
std::unique_ptr<Advertisement> advertisement) {
|
||||
int64_t placeholder_share_target_id = share_target_info.share_target().id;
|
||||
NearbyConnection* connection = share_target_info.connection();
|
||||
if (!connection) {
|
||||
if (!share_target_info.IsConnected()) {
|
||||
NL_LOG(WARNING) << __func__ << ": Invalid connection for endpoint id - "
|
||||
<< endpoint_id;
|
||||
return;
|
||||
@@ -3095,15 +2954,7 @@ void NearbySharingServiceImpl::OnOutgoingTransferUpdate(
|
||||
metadata.in_progress_attachment_total_bytes().has_value() &&
|
||||
*metadata.in_progress_attachment_transferred_bytes() ==
|
||||
*metadata.in_progress_attachment_total_bytes()) {
|
||||
std::optional<Payload> payload = share_target_info.ExtractNextPayload();
|
||||
if (payload.has_value()) {
|
||||
NL_LOG(INFO) << __func__ << ": Send payload " << payload->id;
|
||||
nearby_connections_manager_->Send(share_target_info.endpoint_id(),
|
||||
std::make_unique<Payload>(*payload),
|
||||
share_target_info.payload_tracker());
|
||||
} else {
|
||||
NL_LOG(WARNING) << __func__ << ": There is no paylaods to send.";
|
||||
}
|
||||
share_target_info.SendNextPayload(*nearby_connections_manager_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3120,29 +2971,36 @@ void NearbySharingServiceImpl::OnOutgoingTransferUpdate(
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::CloseConnection(int64_t share_target_id) {
|
||||
NearbyConnection* connection = GetConnection(share_target_id);
|
||||
if (!connection) {
|
||||
NL_LOG(WARNING) << __func__ << ": Invalid connection for target - "
|
||||
<< share_target_id;
|
||||
ShareTargetInfo* share_target_info = GetShareTargetInfo(share_target_id);
|
||||
if (share_target_info != nullptr && share_target_info->IsConnected()) {
|
||||
share_target_info->connection()->Close();
|
||||
return;
|
||||
}
|
||||
connection->Close();
|
||||
NL_LOG(WARNING) << __func__ << ": Invalid connection for target - "
|
||||
<< share_target_id;
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnIncomingDecryptedCertificate(
|
||||
absl::string_view endpoint_id, const Advertisement& advertisement,
|
||||
int64_t placeholder_share_target_id,
|
||||
std::optional<NearbyShareDecryptedPublicCertificate> certificate) {
|
||||
NearbyConnection* connection = GetConnection(placeholder_share_target_id);
|
||||
if (!connection) {
|
||||
auto it = incoming_share_target_info_map_.find(placeholder_share_target_id);
|
||||
if (it == incoming_share_target_info_map_.end()) {
|
||||
NL_VLOG(1) << __func__ << ": Invalid connection for endpoint id - "
|
||||
<< endpoint_id;
|
||||
return;
|
||||
}
|
||||
if (!it->second.IsConnected()) {
|
||||
NL_VLOG(1) << __func__ << ": Connection has been closedfor endpoint id - "
|
||||
<< endpoint_id;
|
||||
incoming_share_target_info_map_.erase(it);
|
||||
return;
|
||||
}
|
||||
NearbyConnection* connection = it->second.connection();
|
||||
|
||||
// Remove placeholder share target since we are creating the actual share
|
||||
// target below.
|
||||
incoming_share_target_info_map_.erase(placeholder_share_target_id);
|
||||
incoming_share_target_info_map_.erase(it);
|
||||
|
||||
std::optional<ShareTarget> share_target =
|
||||
CreateShareTarget(endpoint_id, advertisement, certificate,
|
||||
@@ -3195,7 +3053,7 @@ void NearbySharingServiceImpl::OnIncomingConnectionKeyVerificationDone(
|
||||
PairedKeyVerificationRunner::PairedKeyVerificationResult result,
|
||||
OSType share_target_os_type) {
|
||||
IncomingShareTargetInfo* info = GetIncomingShareTargetInfo(share_target_id);
|
||||
if (!info || !info->connection()) {
|
||||
if (!info || !info->IsConnected()) {
|
||||
NL_VLOG(1) << __func__ << ": Invalid connection or endpoint id";
|
||||
return;
|
||||
}
|
||||
@@ -3243,7 +3101,7 @@ void NearbySharingServiceImpl::OnOutgoingConnectionKeyVerificationDone(
|
||||
PairedKeyVerificationRunner::PairedKeyVerificationResult result,
|
||||
OSType share_target_os_type) {
|
||||
OutgoingShareTargetInfo* info = GetOutgoingShareTargetInfo(share_target_id);
|
||||
if (!info || !info->connection()) {
|
||||
if (!info || !info->IsConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3305,7 +3163,7 @@ void NearbySharingServiceImpl::ReceiveIntroduction(
|
||||
std::optional<std::string> four_digit_token) {
|
||||
NL_LOG(INFO) << __func__ << ": Receiving introduction from "
|
||||
<< info.share_target().id;
|
||||
NL_DCHECK(info.connection());
|
||||
NL_DCHECK(info.IsConnected());
|
||||
|
||||
info.frames_reader()->ReadFrame(
|
||||
nearby::sharing::service::proto::V1Frame::INTRODUCTION,
|
||||
@@ -3322,7 +3180,7 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
|
||||
int64_t share_target_id, std::optional<std::string> four_digit_token,
|
||||
std::optional<nearby::sharing::service::proto::V1Frame> frame) {
|
||||
IncomingShareTargetInfo* info = GetIncomingShareTargetInfo(share_target_id);
|
||||
if (!info || !info->connection()) {
|
||||
if (!info || !info->IsConnected()) {
|
||||
NL_LOG(WARNING)
|
||||
<< __func__
|
||||
<< ": Ignore received introduction, due to no connection established.";
|
||||
@@ -3344,7 +3202,6 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
|
||||
Fail(share_target_id, *status);
|
||||
return;
|
||||
}
|
||||
attachment_payload_map_ = info->attachment_payload_map();
|
||||
|
||||
// Log analytics event of receiving introduction.
|
||||
analytics_recorder_->NewReceiveIntroduction(
|
||||
@@ -3383,7 +3240,7 @@ void NearbySharingServiceImpl::ReceiveConnectionResponse(
|
||||
ShareTargetInfo& info) {
|
||||
NL_VLOG(1) << __func__ << ": Receiving response frame from "
|
||||
<< info.share_target().id;
|
||||
NL_DCHECK(info.connection());
|
||||
NL_DCHECK(info.IsConnected());
|
||||
|
||||
info.frames_reader()->ReadFrame(
|
||||
nearby::sharing::service::proto::V1Frame::RESPONSE,
|
||||
@@ -3398,7 +3255,7 @@ void NearbySharingServiceImpl::OnReceiveConnectionResponse(
|
||||
int64_t share_target_id,
|
||||
std::optional<nearby::sharing::service::proto::V1Frame> frame) {
|
||||
OutgoingShareTargetInfo* info = GetOutgoingShareTargetInfo(share_target_id);
|
||||
if (!info || !info->connection()) {
|
||||
if (!info || !info->IsConnected()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": Ignore received connection response, due to no "
|
||||
"connection established.";
|
||||
@@ -3425,7 +3282,8 @@ void NearbySharingServiceImpl::OnReceiveConnectionResponse(
|
||||
switch (response.status()) {
|
||||
case nearby::sharing::service::proto::ConnectionResponseFrame::ACCEPT: {
|
||||
// Write progress update frame to remote machine.
|
||||
WriteProgressUpdateFrame(*info->connection(), true, std::nullopt);
|
||||
info->WriteProgressUpdateFrame(/*start_transfer=*/true,
|
||||
/*progress=*/std::nullopt);
|
||||
|
||||
info->frames_reader()->ReadFrame(
|
||||
[this, share_target_id](
|
||||
@@ -3438,36 +3296,19 @@ void NearbySharingServiceImpl::OnReceiveConnectionResponse(
|
||||
.set_status(TransferMetadata::Status::kInProgress)
|
||||
.build());
|
||||
|
||||
info->set_payload_tracker(std::make_unique<PayloadTracker>(
|
||||
context_, share_target_id, info->attachment_container(),
|
||||
attachment_payload_map_,
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnPayloadTransferUpdate,
|
||||
this)));
|
||||
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
kEnableTransferCancellationOptimization)) {
|
||||
std::optional<Payload> payload = info->ExtractNextPayload();
|
||||
if (payload.has_value()) {
|
||||
NL_LOG(INFO) << __func__ << ": Send payload " << payload->id;
|
||||
|
||||
nearby_connections_manager_->Send(info->endpoint_id(),
|
||||
std::make_unique<Payload>(*payload),
|
||||
info->payload_tracker());
|
||||
} else {
|
||||
NL_LOG(WARNING) << __func__ << ": There is no payloads to send.";
|
||||
}
|
||||
info->InitSendPayload(
|
||||
context_, *nearby_connections_manager_,
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnPayloadTransferUpdate,
|
||||
this));
|
||||
info->SendNextPayload(*nearby_connections_manager_);
|
||||
} else {
|
||||
for (auto& payload : info->ExtractTextPayloads()) {
|
||||
nearby_connections_manager_->Send(info->endpoint_id(),
|
||||
std::make_unique<Payload>(payload),
|
||||
info->payload_tracker());
|
||||
}
|
||||
for (auto& payload : info->ExtractFilePayloads()) {
|
||||
nearby_connections_manager_->Send(info->endpoint_id(),
|
||||
std::make_unique<Payload>(payload),
|
||||
info->payload_tracker());
|
||||
}
|
||||
info->SendAllPayloads(
|
||||
context_, *nearby_connections_manager_,
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnPayloadTransferUpdate,
|
||||
this));
|
||||
}
|
||||
NL_VLOG(1)
|
||||
<< __func__
|
||||
@@ -3527,7 +3368,7 @@ void NearbySharingServiceImpl::OnStorageCheckCompleted(
|
||||
return;
|
||||
}
|
||||
ShareTargetInfo* info = GetShareTargetInfo(share_target_id);
|
||||
if (!info || !info->connection()) {
|
||||
if (!info || !info->IsConnected()) {
|
||||
NL_LOG(WARNING) << __func__ << ": Invalid connection for share target - "
|
||||
<< share_target_id;
|
||||
return;
|
||||
@@ -3776,19 +3617,19 @@ void NearbySharingServiceImpl::OnPayloadTransferUpdate(
|
||||
is_waiting_to_record_accept_to_transfer_start_metric_) {
|
||||
is_waiting_to_record_accept_to_transfer_start_metric_ = false;
|
||||
}
|
||||
IncomingShareTargetInfo* incoming_info =
|
||||
GetIncomingShareTargetInfo(share_target_id);
|
||||
|
||||
// Update file paths during progress. It may impact transfer speed.
|
||||
// TODO: b/289290115 - Revisit UpdateFilePath to enhance transfer speed for
|
||||
// MacOS.
|
||||
if (update_file_paths_in_progress_) {
|
||||
UpdateFilePath(info->mutable_attachment_container());
|
||||
incoming_info->UpdateFilePayloadPaths(*nearby_connections_manager_);
|
||||
}
|
||||
|
||||
if (metadata.status() == TransferMetadata::Status::kComplete) {
|
||||
if (!OnIncomingPayloadsComplete(share_target_id)) {
|
||||
if (!incoming_info->FinalizePayloads(*nearby_connections_manager_)) {
|
||||
payload_incomplete = true;
|
||||
|
||||
info->mutable_attachment_container().ClearAttachments();
|
||||
}
|
||||
|
||||
fast_initiation_scanner_cooldown_timer_->Stop();
|
||||
@@ -3801,7 +3642,7 @@ void NearbySharingServiceImpl::OnPayloadTransferUpdate(
|
||||
} else if (metadata.status() == TransferMetadata::Status::kCancelled) {
|
||||
NL_VLOG(1) << __func__ << ": Update file paths for cancelled transfer";
|
||||
if (!update_file_paths_in_progress_) {
|
||||
UpdateFilePath(info->mutable_attachment_container());
|
||||
incoming_info->UpdateFilePayloadPaths(*nearby_connections_manager_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3830,127 +3671,6 @@ void NearbySharingServiceImpl::OnPayloadTransferUpdate(
|
||||
}
|
||||
}
|
||||
|
||||
bool NearbySharingServiceImpl::OnIncomingPayloadsComplete(
|
||||
int64_t share_target_id) {
|
||||
ShareTargetInfo* info = GetShareTargetInfo(share_target_id);
|
||||
if (!info || !info->connection()) {
|
||||
NL_VLOG(1) << __func__ << ": Connection not found for target - "
|
||||
<< share_target_id;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!update_file_paths_in_progress_) {
|
||||
UpdateFilePath(info->mutable_attachment_container());
|
||||
}
|
||||
|
||||
AttachmentContainer& container = info->mutable_attachment_container();
|
||||
for (int i = 0; i < container.GetTextAttachments().size(); ++i) {
|
||||
TextAttachment& text = container.GetMutableTextAttachment(i);
|
||||
const auto it = attachment_payload_map_.find(text.id());
|
||||
if (it == attachment_payload_map_.end()) {
|
||||
NL_LOG(WARNING) << __func__ << ": No payload id found for text - "
|
||||
<< text.id();
|
||||
return false;
|
||||
}
|
||||
const Payload* incoming_payload =
|
||||
nearby_connections_manager_->GetIncomingPayload(it->second);
|
||||
if (!incoming_payload || !incoming_payload->content.is_bytes()) {
|
||||
NL_LOG(WARNING) << __func__ << ": No payload found for text - "
|
||||
<< text.id();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> bytes = incoming_payload->content.bytes_payload.bytes;
|
||||
if (bytes.empty()) {
|
||||
NL_LOG(WARNING)
|
||||
<< __func__
|
||||
<< ": Incoming bytes is empty for text payload with payload_id - "
|
||||
<< it->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string text_body(bytes.begin(), bytes.end());
|
||||
text.set_text_body(text_body);
|
||||
}
|
||||
|
||||
for (int i = 0; i < container.GetWifiCredentialsAttachments().size(); ++i) {
|
||||
WifiCredentialsAttachment& wifi_credentials_attachment =
|
||||
container.GetMutableWifiCredentialsAttachment(i);
|
||||
const auto it =
|
||||
attachment_payload_map_.find(wifi_credentials_attachment.id());
|
||||
if (it == attachment_payload_map_.end()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": No payload id found for WiFi credentials - "
|
||||
<< wifi_credentials_attachment.id();
|
||||
return false;
|
||||
}
|
||||
|
||||
const Payload* incoming_payload =
|
||||
nearby_connections_manager_->GetIncomingPayload(it->second);
|
||||
if (!incoming_payload || !incoming_payload->content.is_bytes()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": No payload found for WiFi credentials - "
|
||||
<< wifi_credentials_attachment.id();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> bytes = incoming_payload->content.bytes_payload.bytes;
|
||||
if (bytes.empty()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": Incoming bytes is empty for WiFi credentials "
|
||||
"payload with payload_id - "
|
||||
<< it->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto wifi_credentials =
|
||||
std::make_unique<nearby::sharing::service::proto::WifiCredentials>();
|
||||
if (!wifi_credentials->ParseFromArray(bytes.data(), bytes.size())) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": Incoming bytes is invalid for WiFi credentials "
|
||||
"payload with payload_id - "
|
||||
<< it->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
wifi_credentials_attachment.set_password(wifi_credentials->password());
|
||||
wifi_credentials_attachment.set_is_hidden(wifi_credentials->hidden_ssid());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::UpdateFilePath(
|
||||
AttachmentContainer& attachment_container) {
|
||||
for (int i = 0; i < attachment_container.GetFileAttachments().size(); ++i) {
|
||||
FileAttachment& file = attachment_container.GetMutableFileAttachment(i);
|
||||
// Skip file if it already has file_path set.
|
||||
if (file.file_path().has_value()) {
|
||||
continue;
|
||||
}
|
||||
const auto it = attachment_payload_map_.find(file.id());
|
||||
if (it == attachment_payload_map_.end()) {
|
||||
NL_LOG(WARNING) << __func__ << ": No payload id found for file - "
|
||||
<< file.id();
|
||||
continue;
|
||||
}
|
||||
|
||||
const Payload* incoming_payload =
|
||||
nearby_connections_manager_->GetIncomingPayload(it->second);
|
||||
if (!incoming_payload || !incoming_payload->content.is_file()) {
|
||||
NL_LOG(WARNING) << __func__ << ": No payload found for file - "
|
||||
<< file.id();
|
||||
continue;
|
||||
}
|
||||
|
||||
auto file_path = incoming_payload->content.file_payload.file.path;
|
||||
NL_VLOG(1) << __func__ << ": Updated file_path="
|
||||
<< GetCompatibleU8String(file_path.u8string());
|
||||
file.set_file_path(file_path);
|
||||
}
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::RemoveIncomingPayloads(
|
||||
const IncomingShareTargetInfo& share_target_info) {
|
||||
NL_LOG(INFO) << __func__ << ": Cleaning up payloads due to transfer failure";
|
||||
@@ -3967,19 +3687,10 @@ void NearbySharingServiceImpl::RemoveIncomingPayloads(
|
||||
files_for_deletion.push_back(*it);
|
||||
}
|
||||
}
|
||||
const AttachmentContainer& container =
|
||||
share_target_info.attachment_container();
|
||||
for (const auto& file : container.GetFileAttachments()) {
|
||||
if (!file.file_path().has_value()) continue;
|
||||
auto file_path = *file.file_path();
|
||||
NL_VLOG(1) << __func__
|
||||
<< ": file_path=" << GetCompatibleU8String(file_path.u8string());
|
||||
if (attachment_payload_map_.find(file.id()) ==
|
||||
attachment_payload_map_.end()) {
|
||||
continue;
|
||||
}
|
||||
files_for_deletion.push_back(file_path);
|
||||
}
|
||||
std::vector<std::filesystem::path> payload_file_path =
|
||||
share_target_info.GetPayloadFilePaths();
|
||||
files_for_deletion.insert(files_for_deletion.end(), payload_file_path.begin(),
|
||||
payload_file_path.end());
|
||||
file_handler_.DeleteFilesFromDisk(std::move(files_for_deletion), []() {});
|
||||
}
|
||||
|
||||
@@ -3998,7 +3709,7 @@ void NearbySharingServiceImpl::Disconnect(int64_t share_target_id,
|
||||
// Failed to send or receive. No point in continuing, so disconnect
|
||||
// immediately.
|
||||
if (metadata.status() != TransferMetadata::Status::kComplete) {
|
||||
if (share_target_info->connection()) {
|
||||
if (share_target_info->IsConnected()) {
|
||||
share_target_info->connection()->Close();
|
||||
} else {
|
||||
nearby_connections_manager_->Disconnect(endpoint_id);
|
||||
@@ -4008,7 +3719,7 @@ void NearbySharingServiceImpl::Disconnect(int64_t share_target_id,
|
||||
|
||||
// Files received successfully. Receivers can immediately cancel.
|
||||
if (share_target_info->IsIncoming()) {
|
||||
if (share_target_info->connection()) {
|
||||
if (share_target_info->IsConnected()) {
|
||||
share_target_info->connection()->Close();
|
||||
} else {
|
||||
nearby_connections_manager_->Disconnect(endpoint_id);
|
||||
@@ -4114,12 +3825,6 @@ OutgoingShareTargetInfo* NearbySharingServiceImpl::GetOutgoingShareTargetInfo(
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
NearbyConnection* NearbySharingServiceImpl::GetConnection(
|
||||
int64_t share_target_id) {
|
||||
ShareTargetInfo* share_target_info = GetShareTargetInfo(share_target_id);
|
||||
return share_target_info ? share_target_info->connection() : nullptr;
|
||||
}
|
||||
|
||||
std::optional<std::vector<uint8_t>>
|
||||
NearbySharingServiceImpl::GetBluetoothMacAddressForShareTarget(
|
||||
OutgoingShareTargetInfo& info) {
|
||||
@@ -4144,14 +3849,6 @@ void NearbySharingServiceImpl::ClearOutgoingShareTargetInfoMap() {
|
||||
NL_DCHECK(outgoing_share_target_info_map_.empty());
|
||||
}
|
||||
|
||||
std::optional<int64_t> NearbySharingServiceImpl::GetAttachmentPayloadId(
|
||||
int64_t attachment_id) {
|
||||
const auto it = attachment_payload_map_.find(attachment_id);
|
||||
if (it == attachment_payload_map_.end()) return std::nullopt;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::UnregisterShareTarget(int64_t share_target_id) {
|
||||
NL_VLOG(1) << __func__ << ": Unregistering share target - "
|
||||
<< share_target_id;
|
||||
@@ -4283,7 +3980,7 @@ void NearbySharingServiceImpl::AbortAndCloseConnectionIfNecessary(
|
||||
info->UpdateTransferMetadata(metadata);
|
||||
|
||||
// Close connection if necessary.
|
||||
if (info->connection()) {
|
||||
if (info->IsConnected()) {
|
||||
// Final status already sent above. No need to send it again.
|
||||
info->set_disconnect_status(TransferMetadata::Status::kUnknown);
|
||||
info->connection()->Close();
|
||||
|
||||
@@ -315,12 +315,9 @@ class NearbySharingServiceImpl
|
||||
void OnTransferStarted(bool is_incoming);
|
||||
|
||||
void ReceivePayloads(
|
||||
ShareTargetInfo& share_target_info,
|
||||
IncomingShareTargetInfo& share_target_info,
|
||||
std::function<void(StatusCodes status_codes)> status_codes_callback);
|
||||
StatusCodes SendPayloads(ShareTargetInfo& info);
|
||||
void OnPayloadPathsRegistered(
|
||||
ShareTargetInfo& info,
|
||||
std::function<void(StatusCodes status_codes)> status_codes_callback);
|
||||
|
||||
void OnOutgoingConnection(absl::Time connect_start_time,
|
||||
NearbyConnection* connection,
|
||||
@@ -334,14 +331,6 @@ class NearbySharingServiceImpl
|
||||
void OnCreatePayloads(std::vector<uint8_t> endpoint_info,
|
||||
OutgoingShareTargetInfo& info, bool success);
|
||||
|
||||
void WriteResponseFrame(
|
||||
NearbyConnection& connection,
|
||||
nearby::sharing::service::proto::ConnectionResponseFrame::Status
|
||||
response_status);
|
||||
void WriteCancelFrame(NearbyConnection& connection);
|
||||
void WriteProgressUpdateFrame(NearbyConnection& connection,
|
||||
std::optional<bool> start_transfer,
|
||||
std::optional<float> progress);
|
||||
void Fail(int64_t share_target_id, TransferMetadata::Status status);
|
||||
void OnIncomingAdvertisementDecoded(
|
||||
absl::string_view endpoint_id,
|
||||
@@ -402,7 +391,6 @@ class NearbySharingServiceImpl
|
||||
|
||||
void OnPayloadTransferUpdate(int64_t share_target_id,
|
||||
TransferMetadata metadata);
|
||||
bool OnIncomingPayloadsComplete(int64_t share_target_id);
|
||||
void RemoveIncomingPayloads(const IncomingShareTargetInfo& share_target_info);
|
||||
void Disconnect(int64_t share_target_id, TransferMetadata metadata);
|
||||
void OnDisconnectingConnectionTimeout(absl::string_view endpoint_id);
|
||||
@@ -418,12 +406,10 @@ class NearbySharingServiceImpl
|
||||
IncomingShareTargetInfo* GetIncomingShareTargetInfo(int64_t share_target_id);
|
||||
OutgoingShareTargetInfo* GetOutgoingShareTargetInfo(int64_t share_target_id);
|
||||
|
||||
NearbyConnection* GetConnection(int64_t share_target_id);
|
||||
std::optional<std::vector<uint8_t>> GetBluetoothMacAddressForShareTarget(
|
||||
OutgoingShareTargetInfo& info);
|
||||
|
||||
void ClearOutgoingShareTargetInfoMap();
|
||||
std::optional<int64_t> GetAttachmentPayloadId(int64_t attachment_id);
|
||||
void UnregisterShareTarget(int64_t share_target_id);
|
||||
|
||||
void OnStartAdvertisingResult(bool used_device_name, Status status);
|
||||
@@ -578,9 +564,6 @@ class NearbySharingServiceImpl
|
||||
// unnecessary backend API call.
|
||||
absl::flat_hash_set<std::string> discovered_advertisements_retried_set_;
|
||||
|
||||
// A mapping of Attachment ID to payload ID .
|
||||
absl::flat_hash_map<int64_t, int64_t> attachment_payload_map_;
|
||||
|
||||
// This alarm is used to disconnect the sharing connection if both sides do
|
||||
// not press accept within the timeout.
|
||||
std::unique_ptr<Timer> mutual_acceptance_timeout_alarm_;
|
||||
|
||||
@@ -27,10 +27,13 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/internal/public/context.h"
|
||||
#include "sharing/internal/public/logging.h"
|
||||
#include "sharing/nearby_connection.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
#include "sharing/nearby_file_handler.h"
|
||||
#include "sharing/payload_tracker.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/share_target_info.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
@@ -39,6 +42,11 @@
|
||||
|
||||
namespace nearby::sharing {
|
||||
|
||||
using ::nearby::sharing::service::proto::Frame;
|
||||
using ::nearby::sharing::service::proto::IntroductionFrame;
|
||||
using ::nearby::sharing::service::proto::ProgressUpdateFrame;
|
||||
using ::nearby::sharing::service::proto::V1Frame;
|
||||
|
||||
OutgoingShareTargetInfo::OutgoingShareTargetInfo(
|
||||
std::string endpoint_id, const ShareTarget& share_target,
|
||||
std::function<void(OutgoingShareTargetInfo&, const TransferMetadata&)>
|
||||
@@ -154,20 +162,18 @@ bool OutgoingShareTargetInfo::CreateFilePayloads(
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<nearby::sharing::service::proto::IntroductionFrame>
|
||||
OutgoingShareTargetInfo::CreateIntroductionFrame() const {
|
||||
bool OutgoingShareTargetInfo::FillIntroductionFrame(
|
||||
IntroductionFrame* introduction) const {
|
||||
const AttachmentContainer& container = attachment_container();
|
||||
if (!container.HasAttachments()) {
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
if (file_payloads_.size() != container.GetFileAttachments().size() ||
|
||||
text_payloads_.size() != container.GetTextAttachments().size() ||
|
||||
wifi_credentials_payloads_.size() !=
|
||||
container.GetWifiCredentialsAttachments().size()) {
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
auto introduction =
|
||||
std::make_unique<nearby::sharing::service::proto::IntroductionFrame>();
|
||||
// Write introduction of file payloads.
|
||||
const std::vector<FileAttachment>& file_attachments =
|
||||
container.GetFileAttachments();
|
||||
@@ -209,7 +215,78 @@ OutgoingShareTargetInfo::CreateIntroductionFrame() const {
|
||||
wifi_credentials.security_type());
|
||||
wifi_credentials_metadata->set_payload_id(wifi_credentials_payloads_[i].id);
|
||||
}
|
||||
return introduction;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OutgoingShareTargetInfo::SendAllPayloads(
|
||||
Context* context, NearbyConnectionsManager& connection_manager,
|
||||
std::function<void(int64_t, TransferMetadata)> update_callback) {
|
||||
set_payload_tracker(std::make_unique<PayloadTracker>(
|
||||
context, share_target().id, attachment_container(),
|
||||
attachment_payload_map(), std::move(update_callback)));
|
||||
for (auto& payload : ExtractTextPayloads()) {
|
||||
connection_manager.Send(endpoint_id(), std::make_unique<Payload>(payload),
|
||||
payload_tracker());
|
||||
}
|
||||
for (auto& payload : ExtractFilePayloads()) {
|
||||
connection_manager.Send(endpoint_id(), std::make_unique<Payload>(payload),
|
||||
payload_tracker());
|
||||
}
|
||||
}
|
||||
|
||||
void OutgoingShareTargetInfo::InitSendPayload(
|
||||
Context* context, NearbyConnectionsManager& connection_manager,
|
||||
std::function<void(int64_t, TransferMetadata)> update_callback) {
|
||||
set_payload_tracker(std::make_unique<PayloadTracker>(
|
||||
context, share_target().id, attachment_container(),
|
||||
attachment_payload_map(), std::move(update_callback)));
|
||||
}
|
||||
|
||||
void OutgoingShareTargetInfo::SendNextPayload(
|
||||
NearbyConnectionsManager& connection_manager) {
|
||||
std::optional<Payload> payload = ExtractNextPayload();
|
||||
if (payload.has_value()) {
|
||||
NL_LOG(INFO) << __func__ << ": Send payload " << payload->id;
|
||||
connection_manager.Send(endpoint_id(), std::make_unique<Payload>(*payload),
|
||||
payload_tracker());
|
||||
} else {
|
||||
NL_LOG(WARNING) << __func__ << ": There is no paylaods to send.";
|
||||
}
|
||||
}
|
||||
|
||||
void OutgoingShareTargetInfo::WriteProgressUpdateFrame(
|
||||
std::optional<bool> start_transfer, std::optional<float> progress) {
|
||||
NL_LOG(INFO) << __func__ << ": Writing progress update frame. start_transfer="
|
||||
<< (start_transfer.has_value() ? *start_transfer : false)
|
||||
<< ", progress=" << (progress.has_value() ? *progress : 0.0);
|
||||
Frame frame;
|
||||
frame.set_version(Frame::V1);
|
||||
V1Frame* v1_frame = frame.mutable_v1();
|
||||
v1_frame->set_type(V1Frame::PROGRESS_UPDATE);
|
||||
ProgressUpdateFrame* progress_frame = v1_frame->mutable_progress_update();
|
||||
if (start_transfer.has_value()) {
|
||||
progress_frame->set_start_transfer(*start_transfer);
|
||||
}
|
||||
if (progress.has_value()) {
|
||||
progress_frame->set_progress(*progress);
|
||||
}
|
||||
|
||||
WriteFrame(frame);
|
||||
}
|
||||
|
||||
bool OutgoingShareTargetInfo::WriteIntroductionFrame() {
|
||||
Frame frame;
|
||||
frame.set_version(Frame::V1);
|
||||
V1Frame* v1_frame = frame.mutable_v1();
|
||||
v1_frame->set_type(V1Frame::INTRODUCTION);
|
||||
IntroductionFrame* introduction_frame = v1_frame->mutable_introduction();
|
||||
introduction_frame->set_start_transfer(true);
|
||||
if (!FillIntroductionFrame(introduction_frame)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WriteFrame(frame);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<Payload> OutgoingShareTargetInfo::ExtractTextPayloads() {
|
||||
|
||||
@@ -15,15 +15,17 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_SHARING_OUTGOING_SHARE_TARGET_INFO_H_
|
||||
#define THIRD_PARTY_NEARBY_SHARING_OUTGOING_SHARE_TARGET_INFO_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem> // NOLINT
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "sharing/internal/public/context.h"
|
||||
#include "sharing/nearby_connection.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
#include "sharing/nearby_file_handler.h"
|
||||
#include "sharing/share_target.h"
|
||||
@@ -79,13 +81,24 @@ class OutgoingShareTargetInfo : public ShareTargetInfo {
|
||||
bool CreateFilePayloads(
|
||||
const std::vector<NearbyFileHandler::FileInfo>& files);
|
||||
|
||||
std::unique_ptr<nearby::sharing::service::proto::IntroductionFrame>
|
||||
CreateIntroductionFrame() const;
|
||||
// Create a payload status listener to send status change to
|
||||
// |update_callback|. Send all payloads to NearbyConnectionManager.
|
||||
void SendAllPayloads(
|
||||
Context* context, NearbyConnectionsManager& connection_manager,
|
||||
std::function<void(int64_t, TransferMetadata)> update_callback);
|
||||
|
||||
std::vector<Payload> ExtractTextPayloads();
|
||||
std::vector<Payload> ExtractFilePayloads();
|
||||
std::vector<Payload> ExtractWifiCredentialsPayloads();
|
||||
std::optional<Payload> ExtractNextPayload();
|
||||
// Create a payload status listener to send status change to
|
||||
// |update_callback|.
|
||||
void InitSendPayload(
|
||||
Context* context, 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();
|
||||
|
||||
protected:
|
||||
void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override;
|
||||
@@ -93,6 +106,13 @@ class OutgoingShareTargetInfo : public ShareTargetInfo {
|
||||
|
||||
|
||||
private:
|
||||
std::vector<Payload> ExtractTextPayloads();
|
||||
std::vector<Payload> ExtractFilePayloads();
|
||||
std::vector<Payload> ExtractWifiCredentialsPayloads();
|
||||
std::optional<Payload> ExtractNextPayload();
|
||||
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_;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -24,8 +25,13 @@
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/fake_nearby_connection.h"
|
||||
#include "sharing/fake_nearby_connections_manager.h"
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/internal/test/fake_context.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
#include "sharing/nearby_file_handler.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
@@ -36,13 +42,19 @@
|
||||
|
||||
namespace nearby::sharing {
|
||||
namespace {
|
||||
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::Eq;
|
||||
using ::testing::Invoke;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::IsFalse;
|
||||
using ::testing::IsTrue;
|
||||
using ::testing::MockFunction;
|
||||
using ::testing::SizeIs;
|
||||
using ::testing::_;
|
||||
|
||||
constexpr absl::string_view kEndpointId = "ABCD";
|
||||
|
||||
@@ -204,11 +216,13 @@ TEST_F(OutgoingShareTargetInfoTest, CreateWifiCredentialsPayloads) {
|
||||
EXPECT_THAT(attachment_payload_map.at(wifi1_.id()), Eq(payloads[0].id));
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareTargetInfoTest, CreateIntroductionFrameWithoutPayloads) {
|
||||
EXPECT_THAT(info_.CreateIntroductionFrame(), Eq(nullptr));
|
||||
TEST_F(OutgoingShareTargetInfoTest, WriteIntroductionFrameWithoutPayloads) {
|
||||
EXPECT_THAT(info_.WriteIntroductionFrame(), IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareTargetInfoTest, CreateIntroductionFrameSuccess) {
|
||||
TEST_F(OutgoingShareTargetInfoTest, WriteIntroductionFrameSuccess) {
|
||||
FakeNearbyConnection connection;
|
||||
info_.OnConnected(absl::Now(), &connection);
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos;
|
||||
file_infos.push_back({
|
||||
.size = 12355L,
|
||||
@@ -217,41 +231,188 @@ TEST_F(OutgoingShareTargetInfoTest, CreateIntroductionFrameSuccess) {
|
||||
info_.CreateFilePayloads(file_infos);
|
||||
info_.CreateTextPayloads();
|
||||
info_.CreateWifiCredentialsPayloads();
|
||||
std::unique_ptr<IntroductionFrame> frame = info_.CreateIntroductionFrame();
|
||||
|
||||
EXPECT_THAT(info_.WriteIntroductionFrame(), IsTrue());
|
||||
|
||||
std::vector<uint8_t> frame_data = connection.GetWrittenData();
|
||||
Frame frame;
|
||||
ASSERT_THAT(frame.ParseFromArray(frame_data.data(), frame_data.size()),
|
||||
IsTrue());
|
||||
ASSERT_THAT(frame.version(), Eq(Frame::V1));
|
||||
ASSERT_THAT(frame.v1().type(), Eq(V1Frame::INTRODUCTION));
|
||||
const IntroductionFrame& intro_frame = frame.v1().introduction();
|
||||
EXPECT_THAT(intro_frame.start_transfer(), IsTrue());
|
||||
const std::vector<Payload>& text_payloads = info_.text_payloads();
|
||||
ASSERT_THAT(frame->text_metadata_size(), Eq(2));
|
||||
EXPECT_THAT(frame->text_metadata(0).id(), Eq(text1_.id()));
|
||||
EXPECT_THAT(frame->text_metadata(0).text_title(), Eq(text1_.text_title()));
|
||||
EXPECT_THAT(frame->text_metadata(0).type(), Eq(text1_.type()));
|
||||
EXPECT_THAT(frame->text_metadata(0).size(), Eq(text1_.size()));
|
||||
EXPECT_THAT(frame->text_metadata(0).payload_id(), Eq(text_payloads[0].id));
|
||||
ASSERT_THAT(intro_frame.text_metadata_size(), Eq(2));
|
||||
EXPECT_THAT(intro_frame.text_metadata(0).id(), Eq(text1_.id()));
|
||||
EXPECT_THAT(intro_frame.text_metadata(0).text_title(),
|
||||
Eq(text1_.text_title()));
|
||||
EXPECT_THAT(intro_frame.text_metadata(0).type(), Eq(text1_.type()));
|
||||
EXPECT_THAT(intro_frame.text_metadata(0).size(), Eq(text1_.size()));
|
||||
EXPECT_THAT(intro_frame.text_metadata(0).payload_id(),
|
||||
Eq(text_payloads[0].id));
|
||||
|
||||
EXPECT_THAT(frame->text_metadata(1).id(), Eq(text2_.id()));
|
||||
EXPECT_THAT(frame->text_metadata(1).text_title(), Eq(text2_.text_title()));
|
||||
EXPECT_THAT(frame->text_metadata(1).type(), Eq(text2_.type()));
|
||||
EXPECT_THAT(frame->text_metadata(1).size(), Eq(text2_.size()));
|
||||
EXPECT_THAT(frame->text_metadata(1).payload_id(), Eq(text_payloads[1].id));
|
||||
EXPECT_THAT(intro_frame.text_metadata(1).id(), Eq(text2_.id()));
|
||||
EXPECT_THAT(intro_frame.text_metadata(1).text_title(),
|
||||
Eq(text2_.text_title()));
|
||||
EXPECT_THAT(intro_frame.text_metadata(1).type(), Eq(text2_.type()));
|
||||
EXPECT_THAT(intro_frame.text_metadata(1).size(), Eq(text2_.size()));
|
||||
EXPECT_THAT(intro_frame.text_metadata(1).payload_id(),
|
||||
Eq(text_payloads[1].id));
|
||||
|
||||
const std::vector<Payload>& file_payloads = info_.file_payloads();
|
||||
ASSERT_THAT(frame->file_metadata_size(), Eq(1));
|
||||
EXPECT_THAT(frame->file_metadata(0).id(), Eq(file1_.id()));
|
||||
ASSERT_THAT(intro_frame.file_metadata_size(), Eq(1));
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).id(), Eq(file1_.id()));
|
||||
// File attachment size has been updated by CreateFilePayloads().
|
||||
EXPECT_THAT(frame->file_metadata(0).size(), Eq(file_infos[0].size));
|
||||
EXPECT_THAT(frame->file_metadata(0).name(), Eq(file1_.file_name()));
|
||||
EXPECT_THAT(frame->file_metadata(0).payload_id(), Eq(file_payloads[0].id));
|
||||
EXPECT_THAT(frame->file_metadata(0).type(), Eq(file1_.type()));
|
||||
EXPECT_THAT(frame->file_metadata(0).mime_type(), Eq(file1_.mime_type()));
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).size(), Eq(file_infos[0].size));
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).name(), Eq(file1_.file_name()));
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).payload_id(),
|
||||
Eq(file_payloads[0].id));
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).type(), Eq(file1_.type()));
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).mime_type(), Eq(file1_.mime_type()));
|
||||
|
||||
const std::vector<Payload>& wifi_payloads = info_.wifi_credentials_payloads();
|
||||
ASSERT_THAT(frame->wifi_credentials_metadata_size(), Eq(1));
|
||||
EXPECT_THAT(frame->wifi_credentials_metadata(0).id(), Eq(wifi1_.id()));
|
||||
EXPECT_THAT(frame->wifi_credentials_metadata(0).ssid(), Eq(wifi1_.ssid()));
|
||||
EXPECT_THAT(frame->wifi_credentials_metadata(0).security_type(),
|
||||
ASSERT_THAT(intro_frame.wifi_credentials_metadata_size(), Eq(1));
|
||||
EXPECT_THAT(intro_frame.wifi_credentials_metadata(0).id(), Eq(wifi1_.id()));
|
||||
EXPECT_THAT(intro_frame.wifi_credentials_metadata(0).ssid(),
|
||||
Eq(wifi1_.ssid()));
|
||||
EXPECT_THAT(intro_frame.wifi_credentials_metadata(0).security_type(),
|
||||
Eq(wifi1_.security_type()));
|
||||
EXPECT_THAT(frame->wifi_credentials_metadata(0).payload_id(),
|
||||
EXPECT_THAT(intro_frame.wifi_credentials_metadata(0).payload_id(),
|
||||
Eq(wifi_payloads[0].id));
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareTargetInfoTest, SendAllPayloads) {
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos;
|
||||
file_infos.push_back({
|
||||
.size = 12355L,
|
||||
.file_path = file1_.file_path().value(),
|
||||
});
|
||||
info_.CreateFilePayloads(file_infos);
|
||||
info_.CreateTextPayloads();
|
||||
info_.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;
|
||||
FakeContext context;
|
||||
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 = info_.attachment_payload_map().at(file1_.id());
|
||||
}))
|
||||
.WillOnce(Invoke(
|
||||
[this](std::unique_ptr<Payload> payload,
|
||||
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
|
||||
payload->id = info_.attachment_payload_map().at(text1_.id());
|
||||
}))
|
||||
.WillOnce(Invoke(
|
||||
[this](std::unique_ptr<Payload> payload,
|
||||
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
|
||||
payload->id = info_.attachment_payload_map().at(text2_.id());
|
||||
}));
|
||||
|
||||
info_.SendAllPayloads(&context, connections_manager,
|
||||
transfer_metadata_callback.AsStdFunction());
|
||||
|
||||
auto payload_listener = info_.payload_tracker().lock();
|
||||
EXPECT_THAT(payload_listener, IsTrue());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareTargetInfoTest, InitSendPayload) {
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos;
|
||||
file_infos.push_back({
|
||||
.size = 12355L,
|
||||
.file_path = file1_.file_path().value(),
|
||||
});
|
||||
info_.CreateFilePayloads(file_infos);
|
||||
info_.CreateTextPayloads();
|
||||
info_.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;
|
||||
FakeContext context;
|
||||
connections_manager.set_send_payload_callback(
|
||||
send_payload_callback.AsStdFunction());
|
||||
|
||||
info_.InitSendPayload(&context, connections_manager,
|
||||
transfer_metadata_callback.AsStdFunction());
|
||||
|
||||
auto payload_listener = info_.payload_tracker().lock();
|
||||
EXPECT_THAT(payload_listener, IsTrue());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareTargetInfoTest, SendNextPayload) {
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos;
|
||||
file_infos.push_back({
|
||||
.size = 12355L,
|
||||
.file_path = file1_.file_path().value(),
|
||||
});
|
||||
info_.CreateFilePayloads(file_infos);
|
||||
info_.CreateTextPayloads();
|
||||
info_.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;
|
||||
FakeContext context;
|
||||
connections_manager.set_send_payload_callback(
|
||||
send_payload_callback.AsStdFunction());
|
||||
|
||||
info_.InitSendPayload(&context, 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 = info_.attachment_payload_map().at(file1_.id());
|
||||
}));
|
||||
info_.SendNextPayload(connections_manager);
|
||||
|
||||
EXPECT_CALL(send_payload_callback, Call(_, _))
|
||||
.WillOnce(Invoke(
|
||||
[this](std::unique_ptr<Payload> payload,
|
||||
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
|
||||
payload->id = info_.attachment_payload_map().at(text1_.id());
|
||||
}));
|
||||
info_.SendNextPayload(connections_manager);
|
||||
|
||||
EXPECT_CALL(send_payload_callback, Call(_, _))
|
||||
.WillOnce(Invoke(
|
||||
[this](std::unique_ptr<Payload> payload,
|
||||
std::weak_ptr<NearbyConnectionsManager::PayloadStatusListener>) {
|
||||
payload->id = info_.attachment_payload_map().at(text2_.id());
|
||||
}));
|
||||
info_.SendNextPayload(connections_manager);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareTargetInfoTest, WriteInProgressUpdateFrameSuccess) {
|
||||
FakeNearbyConnection connection;
|
||||
info_.OnConnected(absl::Now(), &connection);
|
||||
|
||||
info_.WriteProgressUpdateFrame(true, 0.5);
|
||||
|
||||
std::vector<uint8_t> frame_data = connection.GetWrittenData();
|
||||
Frame frame;
|
||||
ASSERT_THAT(frame.ParseFromArray(frame_data.data(), frame_data.size()),
|
||||
IsTrue());
|
||||
ASSERT_THAT(frame.version(), Eq(Frame::V1));
|
||||
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));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -29,8 +29,10 @@
|
||||
#include "sharing/internal/public/context.h"
|
||||
#include "sharing/internal/public/logging.h"
|
||||
#include "sharing/nearby_connection.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/nearby_sharing_decoder.h"
|
||||
#include "sharing/paired_key_verification_runner.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/transfer_metadata.h"
|
||||
#include "sharing/transfer_metadata_builder.h"
|
||||
@@ -39,6 +41,9 @@ namespace nearby::sharing {
|
||||
namespace {
|
||||
|
||||
using ::location::nearby::proto::sharing::OSType;
|
||||
using ::nearby::sharing::service::proto::ConnectionResponseFrame;
|
||||
using ::nearby::sharing::service::proto::Frame;
|
||||
using ::nearby::sharing::service::proto::V1Frame;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -131,4 +136,45 @@ void ShareTargetInfo::SetAttachmentPayloadId(int64_t attachment_id,
|
||||
attachment_payload_map_[attachment_id] = payload_id;
|
||||
}
|
||||
|
||||
void ShareTargetInfo::CancelPayloads(
|
||||
NearbyConnectionsManager& connections_manager) {
|
||||
for (const auto& [attachment_id, payload_id] : attachment_payload_map_) {
|
||||
connections_manager.Cancel(payload_id);
|
||||
}
|
||||
}
|
||||
|
||||
void ShareTargetInfo::WriteFrame(const Frame& frame) {
|
||||
if (connection_ == nullptr) {
|
||||
NL_LOG(WARNING) << __func__ << ": Failed to write response frame, due to "
|
||||
"no connection established.";
|
||||
return;
|
||||
}
|
||||
std::vector<uint8_t> data(frame.ByteSizeLong());
|
||||
frame.SerializeToArray(data.data(), frame.ByteSizeLong());
|
||||
|
||||
connection_->Write(std::move(data));
|
||||
}
|
||||
|
||||
void ShareTargetInfo::WriteResponseFrame(
|
||||
ConnectionResponseFrame::Status response_status) {
|
||||
Frame frame;
|
||||
frame.set_version(Frame::V1);
|
||||
V1Frame* v1_frame = frame.mutable_v1();
|
||||
v1_frame->set_type(V1Frame::RESPONSE);
|
||||
v1_frame->mutable_connection_response()->set_status(response_status);
|
||||
|
||||
WriteFrame(frame);
|
||||
}
|
||||
|
||||
void ShareTargetInfo::WriteCancelFrame() {
|
||||
NL_LOG(INFO) << __func__ << ": Writing cancel frame.";
|
||||
|
||||
Frame frame;
|
||||
frame.set_version(Frame::V1);
|
||||
V1Frame* v1_frame = frame.mutable_v1();
|
||||
v1_frame->set_type(V1Frame::CANCEL);
|
||||
|
||||
WriteFrame(frame);
|
||||
}
|
||||
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "sharing/nearby_sharing_decoder.h"
|
||||
#include "sharing/paired_key_verification_runner.h"
|
||||
#include "sharing/payload_tracker.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/transfer_metadata.h"
|
||||
|
||||
@@ -63,6 +64,7 @@ class ShareTargetInfo {
|
||||
}
|
||||
|
||||
NearbyConnection* connection() const { return connection_; }
|
||||
bool IsConnected() const { return connection_ != nullptr; }
|
||||
|
||||
void UpdateTransferMetadata(const TransferMetadata& transfer_metadata);
|
||||
|
||||
@@ -77,10 +79,6 @@ class ShareTargetInfo {
|
||||
return payload_tracker_->GetWeakPtr();
|
||||
}
|
||||
|
||||
void set_payload_tracker(std::shared_ptr<PayloadTracker> payload_tracker) {
|
||||
payload_tracker_ = std::move(payload_tracker);
|
||||
}
|
||||
|
||||
int64_t session_id() const { return session_id_; }
|
||||
|
||||
void set_session_id(int64_t session_id) { session_id_ = session_id; }
|
||||
@@ -132,22 +130,34 @@ class ShareTargetInfo {
|
||||
return attachment_container_;
|
||||
}
|
||||
|
||||
AttachmentContainer& mutable_attachment_container() {
|
||||
return attachment_container_;
|
||||
}
|
||||
void CancelPayloads(NearbyConnectionsManager& connections_manager);
|
||||
|
||||
const absl::flat_hash_map<int64_t, int64_t>& attachment_payload_map()
|
||||
const {
|
||||
return attachment_payload_map_;
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetAttachmentPayloadId(int64_t attachment_id, int64_t payload_id);
|
||||
void WriteResponseFrame(
|
||||
nearby::sharing::service::proto::ConnectionResponseFrame::Status
|
||||
response_status);
|
||||
void WriteCancelFrame();
|
||||
|
||||
protected:
|
||||
virtual void InvokeTransferUpdateCallback(
|
||||
const TransferMetadata& metadata) = 0;
|
||||
virtual bool OnNewConnection(NearbyConnection* connection) = 0;
|
||||
|
||||
void SetAttachmentPayloadId(int64_t attachment_id, int64_t payload_id);
|
||||
|
||||
void set_payload_tracker(std::shared_ptr<PayloadTracker> payload_tracker) {
|
||||
payload_tracker_ = std::move(payload_tracker);
|
||||
}
|
||||
|
||||
AttachmentContainer& mutable_attachment_container() {
|
||||
return attachment_container_;
|
||||
}
|
||||
void WriteFrame(const nearby::sharing::service::proto::Frame& frame);
|
||||
|
||||
private:
|
||||
std::string endpoint_id_;
|
||||
std::optional<NearbyShareDecryptedPublicCertificate> certificate_;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "absl/time/time.h"
|
||||
#include "sharing/certificates/fake_nearby_share_certificate_manager.h"
|
||||
#include "sharing/fake_nearby_connection.h"
|
||||
#include "sharing/fake_nearby_connections_manager.h"
|
||||
#include "sharing/internal/test/fake_context.h"
|
||||
#include "sharing/nearby_connection.h"
|
||||
#include "sharing/nearby_sharing_decoder_impl.h"
|
||||
@@ -39,6 +40,9 @@ namespace nearby::sharing {
|
||||
namespace {
|
||||
|
||||
using ::location::nearby::proto::sharing::OSType;
|
||||
using ::nearby::sharing::service::proto::Frame;
|
||||
using ::nearby::sharing::service::proto::ConnectionResponseFrame;
|
||||
using ::nearby::sharing::service::proto::V1Frame;
|
||||
|
||||
constexpr absl::string_view kEndpointId = "12345";
|
||||
|
||||
@@ -63,6 +67,10 @@ class TestShareTargetInfo : public ShareTargetInfo {
|
||||
on_new_connection_result_ = result;
|
||||
}
|
||||
|
||||
void SetAttachmentPayloadId(int64_t attachment_id, int64_t payload_id) {
|
||||
ShareTargetInfo::SetAttachmentPayloadId(attachment_id, payload_id);
|
||||
}
|
||||
|
||||
protected:
|
||||
void InvokeTransferUpdateCallback(
|
||||
const TransferMetadata& metadata) override {
|
||||
@@ -227,5 +235,50 @@ TEST(ShareTargetInfoTest, OnDisconnect) {
|
||||
EXPECT_TRUE(info.LastTransferMetadata()->is_final_status());
|
||||
}
|
||||
|
||||
TEST(ShareTargetInfoTest, CancelPayloads) {
|
||||
ShareTarget share_target;
|
||||
TestShareTargetInfo info(std::string(kEndpointId), share_target);
|
||||
info.SetAttachmentPayloadId(1, 2);
|
||||
info.SetAttachmentPayloadId(3, 4);
|
||||
|
||||
FakeNearbyConnectionsManager connections_manager;
|
||||
info.CancelPayloads(connections_manager);
|
||||
|
||||
EXPECT_TRUE(connections_manager.WasPayloadCanceled(2));
|
||||
EXPECT_TRUE(connections_manager.WasPayloadCanceled(4));
|
||||
}
|
||||
|
||||
TEST(ShareTargetInfoTest, WriteResponseFrame) {
|
||||
ShareTarget share_target;
|
||||
TestShareTargetInfo info(std::string(kEndpointId), share_target);
|
||||
FakeNearbyConnection connection;
|
||||
EXPECT_TRUE(info.OnConnected(absl::Now(), &connection));
|
||||
|
||||
info.WriteResponseFrame(ConnectionResponseFrame::REJECT);
|
||||
|
||||
std::vector<uint8_t> frame_data = connection.GetWrittenData();
|
||||
Frame frame;
|
||||
ASSERT_TRUE(frame.ParseFromArray(frame_data.data(), frame_data.size()));
|
||||
ASSERT_EQ(frame.version(), Frame::V1);
|
||||
ASSERT_EQ(frame.v1().type(), V1Frame::RESPONSE);
|
||||
EXPECT_EQ(frame.v1().connection_response().status(),
|
||||
ConnectionResponseFrame::REJECT);
|
||||
}
|
||||
|
||||
TEST(ShareTargetInfoTest, WriteCancelFrame) {
|
||||
ShareTarget share_target;
|
||||
TestShareTargetInfo info(std::string(kEndpointId), share_target);
|
||||
FakeNearbyConnection connection;
|
||||
EXPECT_TRUE(info.OnConnected(absl::Now(), &connection));
|
||||
|
||||
info.WriteCancelFrame();
|
||||
|
||||
std::vector<uint8_t> frame_data = connection.GetWrittenData();
|
||||
Frame frame;
|
||||
ASSERT_TRUE(frame.ParseFromArray(frame_data.data(), frame_data.size()));
|
||||
ASSERT_EQ(frame.version(), Frame::V1);
|
||||
EXPECT_EQ(frame.v1().type(), V1Frame::CANCEL);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby::sharing
|
||||
|
||||
Reference in New Issue
Block a user