Move IntroductionFrame handing to ShareTargetInfo.

PiperOrigin-RevId: 644192822
This commit is contained in:
Francis Tsui
2024-06-17 18:04:35 -07:00
committed by Copybara-Service
parent 2fccc4a48b
commit 23031698dd
14 changed files with 588 additions and 198 deletions
+33
View File
@@ -199,7 +199,9 @@ cc_library(
"//sharing/common:compatible_u8_string",
"//sharing/internal/public:logging",
"//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",
@@ -350,6 +352,17 @@ cc_library(
],
)
cc_library(
name = "attachment_compare",
testonly = True,
srcs = ["attachment_compare.cc"],
hdrs = ["attachment_compare.h"],
deps = [
":attachments",
"@com_google_absl//absl/strings",
],
)
cc_test(
name = "advertisement_test",
srcs = ["advertisement_test.cc"],
@@ -721,6 +734,7 @@ cc_test(
name = "attachment_container_test",
srcs = ["attachment_container_test.cc"],
deps = [
":attachment_compare",
":attachments",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_googletest//:gtest_main",
@@ -755,3 +769,22 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "incoming_share_target_info_test",
srcs = ["incoming_share_target_info_test.cc"],
deps = [
":attachment_compare",
":attachments",
":share_target_info",
":transfer_metadata",
":types",
"//internal/platform/implementation/g3", # fixdeps: keep
"//sharing/internal/public:logging",
"//sharing/proto:wire_format_cc_proto",
"//third_party/protobuf",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/strings:string_view",
"@com_google_googletest//:gtest_main",
],
)
+50
View File
@@ -0,0 +1,50 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sharing/attachment_compare.h"
#include "sharing/file_attachment.h"
#include "sharing/text_attachment.h"
#include "sharing/wifi_credentials_attachment.h"
namespace nearby::sharing {
bool operator==(const TextAttachment& lhs, const TextAttachment& rhs) {
return lhs.id() == rhs.id() && lhs.family() == rhs.family() &&
lhs.size() == rhs.size() && lhs.batch_id() == rhs.batch_id() &&
lhs.source_type() == rhs.source_type() && lhs.type() == rhs.type() &&
lhs.text_title() == rhs.text_title() &&
lhs.text_body() == rhs.text_body() &&
lhs.mime_type() == rhs.mime_type();
}
bool operator==(const FileAttachment& lhs, const FileAttachment& rhs) {
return lhs.id() == rhs.id() && lhs.family() == rhs.family() &&
lhs.size() == rhs.size() && lhs.batch_id() == rhs.batch_id() &&
lhs.source_type() == rhs.source_type() &&
lhs.file_name() == rhs.file_name() &&
lhs.mime_type() == rhs.mime_type() && lhs.type() == rhs.type() &&
lhs.file_path() == rhs.file_path() &&
lhs.parent_folder() == rhs.parent_folder();
}
bool operator==(const WifiCredentialsAttachment& lhs,
const WifiCredentialsAttachment& rhs) {
return lhs.id() == rhs.id() && lhs.family() == rhs.family() &&
lhs.size() == rhs.size() && lhs.batch_id() == rhs.batch_id() &&
lhs.ssid() == rhs.ssid() &&
lhs.security_type() == rhs.security_type() &&
lhs.password() == rhs.password() && lhs.is_hidden() == rhs.is_hidden();
}
} // namespace nearby::sharing
+31
View File
@@ -0,0 +1,31 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_SHARING_ATTACHMENT_COMPARE_H_
#define THIRD_PARTY_NEARBY_SHARING_ATTACHMENT_COMPARE_H_
#include "sharing/file_attachment.h"
#include "sharing/text_attachment.h"
#include "sharing/wifi_credentials_attachment.h"
namespace nearby::sharing {
bool operator==(const TextAttachment& lhs, const TextAttachment& rhs);
bool operator==(const FileAttachment& lhs, const FileAttachment& rhs);
bool operator==(const WifiCredentialsAttachment& lhs,
const WifiCredentialsAttachment& rhs);
} // namespace nearby::sharing
#endif // THIRD_PARTY_NEARBY_SHARING_ATTACHMENT_COMPARE_H_
+17
View File
@@ -50,6 +50,17 @@ int64_t AttachmentContainer::GetTotalAttachmentsSize() const {
return size_in_bytes;
}
int64_t AttachmentContainer::GetStorageSize() const {
int64_t size_in_bytes = 0;
// Only files require disk storage.
for (const auto& file : file_attachments_) {
size_in_bytes += file.size();
}
return size_in_bytes;
}
void AttachmentContainer::ClearAttachments() {
// Reset file paths for file attachments.
for (auto& file : file_attachments_)
@@ -66,6 +77,12 @@ void AttachmentContainer::ClearAttachments() {
}
}
void AttachmentContainer::Clear() {
file_attachments_.clear();
text_attachments_.clear();
wifi_credentials_attachments_.clear();
}
std::vector<int64_t> AttachmentContainer::GetAttachmentIds() const {
std::vector<int64_t> attachment_ids;
+6
View File
@@ -83,6 +83,9 @@ class AttachmentContainer {
// Returns the total size of all attachments.
int64_t GetTotalAttachmentsSize() const;
// Returns the total size of all attachments on disk.
int64_t GetStorageSize() const;
// Returns true if there are any attachments.
bool HasAttachments() const {
return !text_attachments_.empty() || !file_attachments_.empty() ||
@@ -93,6 +96,9 @@ class AttachmentContainer {
// place.
void ClearAttachments();
// Delete all attachments.
void Clear();
// Returns the list of attachment IDs of attachments in this container.
std::vector<int64_t> GetAttachmentIds() const;
+22 -29
View File
@@ -23,40 +23,12 @@
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "sharing/attachment.h"
#include "sharing/attachment_compare.h" // IWYU pragma: keep
#include "sharing/file_attachment.h"
#include "sharing/text_attachment.h"
#include "sharing/wifi_credentials_attachment.h"
namespace nearby::sharing {
bool operator==(const TextAttachment& lhs, const TextAttachment& rhs) {
return lhs.id() == rhs.id() && lhs.family() == rhs.family() &&
lhs.size() == rhs.size() && lhs.batch_id() == rhs.batch_id() &&
lhs.source_type() == rhs.source_type() && lhs.type() == rhs.type() &&
lhs.text_title() == rhs.text_title() &&
lhs.text_body() == rhs.text_body() &&
lhs.mime_type() == rhs.mime_type();
}
bool operator==(const FileAttachment& lhs, const FileAttachment& rhs) {
return lhs.id() == rhs.id() && lhs.family() == rhs.family() &&
lhs.size() == rhs.size() && lhs.batch_id() == rhs.batch_id() &&
lhs.source_type() == rhs.source_type() &&
lhs.file_name() == rhs.file_name() &&
lhs.mime_type() == rhs.mime_type() && lhs.type() == rhs.type() &&
lhs.file_path() == rhs.file_path() &&
lhs.parent_folder() == rhs.parent_folder();
}
bool operator==(const WifiCredentialsAttachment& lhs,
const WifiCredentialsAttachment& rhs) {
return lhs.id() == rhs.id() && lhs.family() == rhs.family() &&
lhs.size() == rhs.size() && lhs.batch_id() == rhs.batch_id() &&
lhs.ssid() == rhs.ssid() &&
lhs.security_type() == rhs.security_type() &&
lhs.password() == rhs.password() && lhs.is_hidden() == rhs.is_hidden();
}
namespace {
using testing::Eq;
@@ -209,6 +181,17 @@ TEST_F(AttachmentContainerTest, ClearAttachments) {
IsFalse());
}
TEST_F(AttachmentContainerTest, Clear) {
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
std::vector<FileAttachment>{file1_},
std::vector<WifiCredentialsAttachment>{wifi1_});
EXPECT_THAT(container.HasAttachments(), IsTrue());
container.Clear();
EXPECT_THAT(container.HasAttachments(), IsFalse());
}
TEST_F(AttachmentContainerTest, GetAttachmentIds) {
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
std::vector<FileAttachment>{file1_},
@@ -222,6 +205,16 @@ TEST_F(AttachmentContainerTest, GetAttachmentIds) {
wifi1_.id()));
}
TEST_F(AttachmentContainerTest, GetStorageSize) {
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
std::vector<FileAttachment>{file1_},
std::vector<WifiCredentialsAttachment>{wifi1_});
int64_t storage_size = container.GetStorageSize();
EXPECT_THAT(storage_size, Eq(file1_.size()));
}
} // namespace
} // namespace nearby::sharing
+90 -4
View File
@@ -14,17 +14,31 @@
#include "sharing/incoming_share_target_info.h"
#include <cstdint>
#include <functional>
#include <limits>
#include <optional>
#include <string>
#include <utility>
#include "sharing/attachment_container.h"
#include "sharing/constants.h"
#include "sharing/file_attachment.h"
#include "sharing/internal/public/logging.h"
#include "sharing/nearby_connection.h"
#include "sharing/proto/wire_format.pb.h"
#include "sharing/share_target.h"
#include "sharing/share_target_info.h"
#include "sharing/text_attachment.h"
#include "sharing/transfer_metadata.h"
#include "sharing/wifi_credentials_attachment.h"
namespace nearby {
namespace sharing {
namespace nearby::sharing {
namespace {
using ::nearby::sharing::service::proto::IntroductionFrame;
} // namespace
IncomingShareTargetInfo::IncomingShareTargetInfo(
std::string endpoint_id, const ShareTarget& share_target,
@@ -52,5 +66,77 @@ bool IncomingShareTargetInfo::OnNewConnection(NearbyConnection* connection) {
return true;
}
} // namespace sharing
} // namespace nearby
std::optional<TransferMetadata::Status>
IncomingShareTargetInfo::ProcessIntroduction(
const IntroductionFrame& introduction_frame) {
int64_t file_size_sum = 0;
AttachmentContainer& container = mutable_attachment_container();
for (const auto& file : introduction_frame.file_metadata()) {
if (file.size() <= 0) {
NL_LOG(WARNING)
<< __func__
<< ": Ignore introduction, due to invalid attachment size";
return TransferMetadata::Status::kUnsupportedAttachmentType;
}
NL_VLOG(1) << __func__ << ": Found file attachment: id=" << file.id()
<< ", type= " << file.type() << ", size=" << file.size()
<< ", payload_id=" << file.payload_id()
<< ", parent_folder=" << file.parent_folder()
<< ", mime_type=" << file.mime_type();
container.AddFileAttachment(
FileAttachment(file.id(), file.size(), file.name(), file.mime_type(),
file.type(), file.parent_folder()));
SetAttachmentPayloadId(file.id(), file.payload_id());
if (std::numeric_limits<int64_t>::max() - file.size() < file_size_sum) {
NL_LOG(WARNING) << __func__
<< ": Ignoring introduction, total file size overflowed "
"64 bit integer.";
container.Clear();
return TransferMetadata::Status::kNotEnoughSpace;
}
file_size_sum += file.size();
}
for (const auto& text : introduction_frame.text_metadata()) {
if (text.size() <= 0) {
NL_LOG(WARNING)
<< __func__
<< ": Ignore introduction, due to invalid attachment size";
return TransferMetadata::Status::kUnsupportedAttachmentType;
}
NL_VLOG(1) << __func__ << ": Found text attachment: id=" << text.id()
<< ", type= " << text.type() << ", size=" << text.size()
<< ", payload_id=" << text.payload_id();
container.AddTextAttachment(
TextAttachment(text.id(), text.type(), text.text_title(), text.size()));
SetAttachmentPayloadId(text.id(), text.payload_id());
}
if (kSupportReceivingWifiCredentials) {
for (const auto& wifi_credentials :
introduction_frame.wifi_credentials_metadata()) {
NL_VLOG(1) << __func__ << ": Found WiFi credentials attachment: id="
<< wifi_credentials.id()
<< ", ssid= " << wifi_credentials.ssid()
<< ", payload_id=" << wifi_credentials.payload_id();
container.AddWifiCredentialsAttachment(WifiCredentialsAttachment(
wifi_credentials.id(), wifi_credentials.ssid(),
wifi_credentials.security_type()));
SetAttachmentPayloadId(wifi_credentials.id(),
wifi_credentials.payload_id());
}
}
if (!container.HasAttachments()) {
NL_LOG(WARNING) << __func__
<< ": No attachment is found for this share target. It can "
"be result of unrecognizable attachment type";
return TransferMetadata::Status::kUnsupportedAttachmentType;
}
return std::nullopt;
}
} // namespace nearby::sharing
+11 -4
View File
@@ -16,14 +16,15 @@
#define THIRD_PARTY_NEARBY_SHARING_INCOMING_SHARE_TARGET_INFO_H_
#include <functional>
#include <optional>
#include <string>
#include "sharing/nearby_connection.h"
#include "sharing/proto/wire_format.pb.h"
#include "sharing/share_target.h"
#include "sharing/share_target_info.h"
#include "sharing/transfer_metadata.h"
namespace nearby {
namespace sharing {
namespace nearby::sharing {
class IncomingShareTargetInfo : public ShareTargetInfo {
public:
@@ -38,6 +39,13 @@ class IncomingShareTargetInfo : public ShareTargetInfo {
bool IsIncoming() const override { return true; }
// Returns nullopt on success.
// On failure, returns the status that should be used to terminate the
// connection.
std::optional<TransferMetadata::Status> ProcessIntroduction(
const nearby::sharing::service::proto::IntroductionFrame&
introduction_frame);
protected:
void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override;
bool OnNewConnection(NearbyConnection* connection) override;
@@ -47,7 +55,6 @@ class IncomingShareTargetInfo : public ShareTargetInfo {
transfer_update_callback_;
};
} // namespace sharing
} // namespace nearby
} // namespace nearby::sharing
#endif // THIRD_PARTY_NEARBY_SHARING_INCOMING_SHARE_TARGET_INFO_H_
+197
View File
@@ -0,0 +1,197 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sharing/incoming_share_target_info.h"
#include <cstdint>
#include <limits>
#include <optional>
#include <string>
#include <utility>
#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/file_attachment.h"
#include "sharing/internal/public/logging.h"
#include "sharing/proto/wire_format.pb.h"
#include "sharing/share_target.h"
#include "sharing/text_attachment.h"
#include "sharing/transfer_metadata.h"
#include "sharing/wifi_credentials_attachment.h"
#include "google/protobuf/text_format.h"
namespace nearby::sharing {
namespace {
using ::nearby::sharing::service::proto::FileMetadata;
using ::nearby::sharing::service::proto::IntroductionFrame;
using ::nearby::sharing::service::proto::TextMetadata;
using ::nearby::sharing::service::proto::WifiCredentialsMetadata;
using ::testing::Eq;
using ::testing::IsFalse;
using ::testing::IsTrue;
using ::testing::UnorderedElementsAre;
constexpr absl::string_view kEndpointId = "ABCD";
class IncomingShareTargetInfoTest : public ::testing::Test {
protected:
IncomingShareTargetInfoTest()
: info_(std::string(kEndpointId), share_target_,
[](const IncomingShareTargetInfo&, const TransferMetadata&) {}) {
NL_CHECK(
proto2::TextFormat::ParseFromString(R"pb(
file_metadata {
id: 1234
size: 100
name: "file_name1"
mime_type: "application/pdf"
type: DOCUMENT
parent_folder: "parent_folder1"
payload_id: 9876
}
file_metadata {
id: 1235
size: 200
name: "file_name2"
mime_type: "image/jpeg"
type: IMAGE
parent_folder: "parent_folder2"
payload_id: 9875
}
text_metadata {
id: 1236
size: 300
text_title: "text_title1"
type: URL
payload_id: 9874
}
text_metadata {
id: 1237
size: 400
text_title: "text_title2"
type: TEXT
payload_id: 9873
}
wifi_credentials_metadata {
id: 1238
ssid: "ssid1"
security_type: WPA_PSK
payload_id: 9872
}
wifi_credentials_metadata {
id: 1239
ssid: "ssid2"
security_type: WEP
payload_id: 9871
}
)pb",
&introduction_frame_));
}
ShareTarget share_target_;
IncomingShareTargetInfo info_;
IntroductionFrame introduction_frame_;
};
TEST_F(IncomingShareTargetInfoTest, ProcessIntroductionNoSupportedPayload) {
IntroductionFrame frame;
EXPECT_THAT(info_.ProcessIntroduction(frame),
Eq(TransferMetadata::Status::kUnsupportedAttachmentType));
EXPECT_THAT(info_.attachment_container().HasAttachments(), IsFalse());
}
TEST_F(IncomingShareTargetInfoTest, ProcessIntroductionEmptyFile) {
IntroductionFrame frame;
frame.mutable_file_metadata();
EXPECT_THAT(info_.ProcessIntroduction(frame),
Eq(TransferMetadata::Status::kUnsupportedAttachmentType));
EXPECT_THAT(info_.attachment_container().HasAttachments(), IsFalse());
}
TEST_F(IncomingShareTargetInfoTest, ProcessIntroductionFilesTooLarge) {
IntroductionFrame frame;
FileMetadata file1;
FileMetadata file2;
file1.set_size(std::numeric_limits<int64_t>::max());
file2.set_size(1);
frame.mutable_file_metadata()->Add(std::move(file1));
frame.mutable_file_metadata()->Add(std::move(file2));
EXPECT_THAT(info_.ProcessIntroduction(frame),
Eq(TransferMetadata::Status::kNotEnoughSpace));
EXPECT_THAT(info_.attachment_container().HasAttachments(), IsFalse());
}
TEST_F(IncomingShareTargetInfoTest, ProcessIntroductionEmptyText) {
IntroductionFrame frame;
frame.mutable_text_metadata();
EXPECT_THAT(info_.ProcessIntroduction(frame),
Eq(TransferMetadata::Status::kUnsupportedAttachmentType));
EXPECT_THAT(info_.attachment_container().HasAttachments(), IsFalse());
}
TEST_F(IncomingShareTargetInfoTest, ProcessIntroductionSuccess) {
FileMetadata filemeta1 = introduction_frame_.file_metadata(0);
FileAttachment file1(filemeta1.id(), filemeta1.size(), filemeta1.name(),
filemeta1.mime_type(), filemeta1.type(),
filemeta1.parent_folder());
FileMetadata filemeta2 = introduction_frame_.file_metadata(1);
FileAttachment file2(filemeta2.id(), filemeta2.size(), filemeta2.name(),
filemeta2.mime_type(), filemeta2.type(),
filemeta2.parent_folder());
TextMetadata textmeta1 = introduction_frame_.text_metadata(0);
TextAttachment text1(textmeta1.id(), textmeta1.type(), textmeta1.text_title(),
textmeta1.size());
TextMetadata textmeta2 = introduction_frame_.text_metadata(1);
TextAttachment text2(textmeta2.id(), textmeta2.type(), textmeta2.text_title(),
textmeta2.size());
WifiCredentialsMetadata wifimeta1 =
introduction_frame_.wifi_credentials_metadata(0);
WifiCredentialsAttachment wifi1(wifimeta1.id(), wifimeta1.ssid(),
wifimeta1.security_type());
WifiCredentialsMetadata wifimeta2 =
introduction_frame_.wifi_credentials_metadata(1);
WifiCredentialsAttachment wifi2(wifimeta2.id(), wifimeta2.ssid(),
wifimeta2.security_type());
EXPECT_THAT(info_.ProcessIntroduction(introduction_frame_), Eq(std::nullopt));
EXPECT_THAT(info_.attachment_container().HasAttachments(), IsTrue());
EXPECT_THAT(info_.attachment_container().GetFileAttachments(),
UnorderedElementsAre(file1, file2));
EXPECT_THAT(info_.attachment_container().GetTextAttachments(),
UnorderedElementsAre(text1, text2));
EXPECT_THAT(info_.attachment_container().GetWifiCredentialsAttachments(),
UnorderedElementsAre(wifi1, wifi2));
EXPECT_THAT(info_.attachment_payload_map().at(filemeta1.id()).payload_id,
Eq(filemeta1.payload_id()));
EXPECT_THAT(info_.attachment_payload_map().at(filemeta2.id()).payload_id,
Eq(filemeta2.payload_id()));
EXPECT_THAT(info_.attachment_payload_map().at(textmeta1.id()).payload_id,
Eq(textmeta1.payload_id()));
EXPECT_THAT(info_.attachment_payload_map().at(textmeta2.id()).payload_id,
Eq(textmeta2.payload_id()));
EXPECT_THAT(info_.attachment_payload_map().at(wifimeta1.id()).payload_id,
Eq(wifimeta1.payload_id()));
EXPECT_THAT(info_.attachment_payload_map().at(wifimeta2.id()).payload_id,
Eq(wifimeta2.payload_id()));
}
} // namespace
} // namespace nearby::sharing
+16 -159
View File
@@ -22,7 +22,6 @@
#include <filesystem> // NOLINT(build/c++17)
#include <functional>
#include <ios>
#include <limits>
#include <memory>
#include <optional>
#include <ostream>
@@ -38,7 +37,6 @@
#include "absl/functional/bind_front.h"
#include "absl/random/random.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
@@ -55,7 +53,6 @@
#include "sharing/advertisement.h"
#include "sharing/analytics/analytics_information.h"
#include "sharing/analytics/analytics_recorder.h"
#include "sharing/attachment.h"
#include "sharing/attachment_container.h"
#include "sharing/attachment_info.h"
#include "sharing/certificates/common.h"
@@ -2728,72 +2725,18 @@ void NearbySharingServiceImpl::SendIntroduction(
}
// Build the introduction.
auto introduction =
std::make_unique<nearby::sharing::service::proto::IntroductionFrame>();
introduction->set_start_transfer(true);
NL_VLOG(1) << __func__ << ": Sending attachments to "
<< info.share_target().id;
const AttachmentContainer& container = info.attachment_container();
// Write introduction of file payloads.
for (const auto& file : container.GetFileAttachments()) {
std::optional<int64_t> payload_id = GetAttachmentPayloadId(file.id());
if (!payload_id) {
NL_VLOG(1) << __func__ << ": Skipping unknown file attachment";
continue;
}
auto* file_metadata = introduction->add_file_metadata();
file_metadata->set_id(file.id());
file_metadata->set_name(absl::StrCat(file.file_name()));
file_metadata->set_payload_id(*payload_id);
file_metadata->set_type(file.type());
file_metadata->set_mime_type(absl::StrCat(file.mime_type()));
file_metadata->set_size(file.size());
}
// Write introduction of text payloads.
for (const auto& text : container.GetTextAttachments()) {
std::optional<int64_t> payload_id = GetAttachmentPayloadId(text.id());
if (!payload_id) {
NL_VLOG(1) << __func__ << ": Skipping unknown text attachment";
continue;
}
auto* text_metadata = introduction->add_text_metadata();
text_metadata->set_id(text.id());
text_metadata->set_text_title(std::string(text.text_title()));
text_metadata->set_type(text.type());
text_metadata->set_size(text.size());
text_metadata->set_payload_id(*payload_id);
}
// Write introduction of Wi-Fi credentials payloads.
for (const auto& wifi_credentials :
container.GetWifiCredentialsAttachments()) {
std::optional<int64_t> payload_id =
GetAttachmentPayloadId(wifi_credentials.id());
if (!payload_id) {
NL_VLOG(1) << __func__
<< ": Skipping unknown WiFi credentials attachment";
continue;
}
auto* wifi_credentials_metadata =
introduction->add_wifi_credentials_metadata();
wifi_credentials_metadata->set_id(wifi_credentials.id());
wifi_credentials_metadata->set_ssid(std::string(wifi_credentials.ssid()));
wifi_credentials_metadata->set_security_type(
wifi_credentials.security_type());
wifi_credentials_metadata->set_payload_id(*payload_id);
}
if (introduction->file_metadata_size() == 0 &&
introduction->text_metadata_size() == 0 &&
introduction->wifi_credentials_metadata_size() == 0) {
std::unique_ptr<nearby::sharing::service::proto::IntroductionFrame>
introduction = info.CreateIntroductionFrame();
if (!introduction) {
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;
@@ -3429,109 +3372,27 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
NL_LOG(INFO) << __func__ << ": Successfully read the introduction frame.";
int64_t file_size_sum = 0;
nearby::sharing::service::proto::IntroductionFrame introduction_frame =
std::move(frame->introduction());
AttachmentContainer& container = info->mutable_attachment_container();
for (const auto& file : introduction_frame.file_metadata()) {
if (file.size() <= 0) {
Fail(share_target_id,
TransferMetadata::Status::kUnsupportedAttachmentType);
NL_LOG(WARNING)
<< __func__
<< ": Ignore introduction, due to invalid attachment size";
return;
}
NL_VLOG(1) << __func__ << ": Found file attachment: id=" << file.id()
<< ", type= " << file.type() << ", size=" << file.size()
<< ", payload_id=" << file.payload_id()
<< ", parent_folder=" << file.parent_folder()
<< ", mime_type=" << file.mime_type();
FileAttachment attachment(file.id(), file.size(), file.name(),
file.mime_type(), file.type(),
file.parent_folder());
SetAttachmentPayloadId(attachment, file.payload_id());
container.AddFileAttachment(std::move(attachment));
if (std::numeric_limits<int64_t>::max() - file.size() < file_size_sum) {
Fail(share_target_id, TransferMetadata::Status::kNotEnoughSpace);
NL_LOG(WARNING) << __func__
<< ": Ignoring introduction, total file size overflowed "
"64 bit integer.";
return;
}
file_size_sum += file.size();
}
for (const auto& text : introduction_frame.text_metadata()) {
if (text.size() <= 0) {
Fail(share_target_id,
TransferMetadata::Status::kUnsupportedAttachmentType);
NL_LOG(WARNING)
<< __func__
<< ": Ignore introduction, due to invalid attachment size";
return;
}
NL_VLOG(1) << __func__ << ": Found text attachment: id=" << text.id()
<< ", type= " << text.type() << ", size=" << text.size()
<< ", payload_id=" << text.payload_id();
TextAttachment attachment(text.id(), text.type(), text.text_title(),
text.size());
SetAttachmentPayloadId(attachment, text.payload_id());
container.AddTextAttachment(std::move(attachment));
}
if (kSupportReceivingWifiCredentials) {
for (const auto& wifi_credentials :
introduction_frame.wifi_credentials_metadata()) {
NL_VLOG(1) << __func__ << ": Found WiFi credentials attachment: id="
<< wifi_credentials.id()
<< ", ssid= " << wifi_credentials.ssid()
<< ", payload_id=" << wifi_credentials.payload_id();
WifiCredentialsAttachment attachment(wifi_credentials.id(),
wifi_credentials.ssid(),
wifi_credentials.security_type());
SetAttachmentPayloadId(attachment, wifi_credentials.payload_id());
container.AddWifiCredentialsAttachment(std::move(attachment));
}
}
if (!container.HasAttachments()) {
NL_LOG(WARNING) << __func__
<< ": No attachment is found for this share target. It can "
"be result of unrecognizable attachment type";
Fail(share_target_id, TransferMetadata::Status::kUnsupportedAttachmentType);
NL_VLOG(1) << __func__
<< ": We don't support the attachments sent by the sender. "
"We have informed "
<< share_target_id;
std::optional<TransferMetadata::Status> status =
info->ProcessIntroduction(frame->introduction());
if (status.has_value()) {
Fail(share_target_id, *status);
return;
}
attachment_info_map_ = info->attachment_payload_map();
// Log analytics event of receiving introduction.
analytics_recorder_->NewReceiveIntroduction(
receiving_session_id_, info->share_target(),
/*referrer_package=*/std::nullopt, info->os_type());
if (file_size_sum == 0) {
OnStorageCheckCompleted(share_target_id, std::move(four_digit_token),
/*is_out_of_storage=*/false);
return;
}
// Controls BWU using a flag when receiving an introduction frame, since it
// could be a problem before accepted by a user.
if (!NearbyFlags::GetInstance().GetBoolFlag(
sharing::config_package_nearby::nearby_sharing_feature::
kUpgradeBandwidthAfterAccept)) {
if (introduction_frame.has_start_transfer() &&
introduction_frame.start_transfer()) {
if (container.GetTotalAttachmentsSize() >=
if (frame->introduction().has_start_transfer() &&
frame->introduction().start_transfer()) {
if (info->attachment_container().GetTotalAttachmentsSize() >=
kAttachmentsSizeThresholdOverHighQualityMedium) {
NL_LOG(INFO)
<< __func__
@@ -3545,7 +3406,8 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
std::filesystem::u8path(settings_->GetCustomSavePath());
bool is_out_of_storage =
IsOutOfStorage(device_info_, download_path, file_size_sum);
IsOutOfStorage(device_info_, download_path,
info->attachment_container().GetStorageSize());
OnStorageCheckCompleted(share_target_id, std::move(four_digit_token),
is_out_of_storage);
@@ -4322,11 +4184,6 @@ void NearbySharingServiceImpl::ClearOutgoingShareTargetInfoMap() {
NL_DCHECK(outgoing_share_target_info_map_.empty());
}
void NearbySharingServiceImpl::SetAttachmentPayloadId(
const Attachment& attachment, int64_t payload_id) {
attachment_info_map_[attachment.id()].payload_id = payload_id;
}
std::optional<int64_t> NearbySharingServiceImpl::GetAttachmentPayloadId(
int64_t attachment_id) {
auto it = attachment_info_map_.find(attachment_id);
-2
View File
@@ -44,7 +44,6 @@
#include "proto/sharing_enums.pb.h"
#include "sharing/advertisement.h"
#include "sharing/analytics/analytics_recorder.h"
#include "sharing/attachment.h"
#include "sharing/attachment_container.h"
#include "sharing/attachment_info.h"
#include "sharing/certificates/nearby_share_certificate_manager.h"
@@ -426,7 +425,6 @@ class NearbySharingServiceImpl
OutgoingShareTargetInfo& info);
void ClearOutgoingShareTargetInfoMap();
void SetAttachmentPayloadId(const Attachment& attachment, int64_t payload_id);
std::optional<int64_t> GetAttachmentPayloadId(int64_t attachment_id);
void UnregisterShareTarget(int64_t share_target_id);
+59
View File
@@ -18,6 +18,7 @@
#include <cstdint>
#include <filesystem> // NOLINT
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <utility>
@@ -153,6 +154,64 @@ bool OutgoingShareTargetInfo::CreateFilePayloads(
return true;
}
std::unique_ptr<nearby::sharing::service::proto::IntroductionFrame>
OutgoingShareTargetInfo::CreateIntroductionFrame() const {
const AttachmentContainer& container = attachment_container();
if (!container.HasAttachments()) {
return nullptr;
}
if (file_payloads_.size() != container.GetFileAttachments().size() ||
text_payloads_.size() != container.GetTextAttachments().size() ||
wifi_credentials_payloads_.size() !=
container.GetWifiCredentialsAttachments().size()) {
return nullptr;
}
auto introduction =
std::make_unique<nearby::sharing::service::proto::IntroductionFrame>();
// Write introduction of file payloads.
const std::vector<FileAttachment>& file_attachments =
container.GetFileAttachments();
for (int i = 0; i < file_attachments.size(); ++i) {
const FileAttachment& file = file_attachments[i];
auto* file_metadata = introduction->add_file_metadata();
file_metadata->set_id(file.id());
file_metadata->set_name(std::string(file.file_name()));
file_metadata->set_payload_id(file_payloads_[i].id);
file_metadata->set_type(file.type());
file_metadata->set_mime_type(std::string(file.mime_type()));
file_metadata->set_size(file.size());
}
// Write introduction of text payloads.
const std::vector<TextAttachment>& text_attachments =
container.GetTextAttachments();
for (int i = 0; i < text_attachments.size(); ++i) {
const TextAttachment& text = text_attachments[i];
auto* text_metadata = introduction->add_text_metadata();
text_metadata->set_id(text.id());
text_metadata->set_text_title(std::string(text.text_title()));
text_metadata->set_type(text.type());
text_metadata->set_size(text.size());
text_metadata->set_payload_id(text_payloads_[i].id);
}
// Write introduction of Wi-Fi credentials payloads.
const std::vector<WifiCredentialsAttachment>& wifi_credentials_attachments =
container.GetWifiCredentialsAttachments();
for (int i = 0; i < wifi_credentials_attachments.size(); ++i) {
const WifiCredentialsAttachment& wifi_credentials =
wifi_credentials_attachments[i];
auto* wifi_credentials_metadata =
introduction->add_wifi_credentials_metadata();
wifi_credentials_metadata->set_id(wifi_credentials.id());
wifi_credentials_metadata->set_ssid(std::string(wifi_credentials.ssid()));
wifi_credentials_metadata->set_security_type(
wifi_credentials.security_type());
wifi_credentials_metadata->set_payload_id(wifi_credentials_payloads_[i].id);
}
return introduction;
}
std::vector<Payload> OutgoingShareTargetInfo::ExtractTextPayloads() {
return std::move(text_payloads_);
}
+4
View File
@@ -17,6 +17,7 @@
#include <filesystem> // NOLINT
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <utility>
@@ -78,6 +79,9 @@ class OutgoingShareTargetInfo : public ShareTargetInfo {
bool CreateFilePayloads(
const std::vector<NearbyFileHandler::FileInfo>& files);
std::unique_ptr<nearby::sharing::service::proto::IntroductionFrame>
CreateIntroductionFrame() const;
std::vector<Payload> ExtractTextPayloads();
std::vector<Payload> ExtractFilePayloads();
std::vector<Payload> ExtractWifiCredentialsPayloads();
@@ -15,6 +15,7 @@
#include "sharing/outgoing_share_target_info.h"
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>
@@ -35,6 +36,7 @@
namespace nearby::sharing {
namespace {
using ::nearby::sharing::service::proto::IntroductionFrame;
using ::nearby::sharing::service::proto::WifiCredentials;
using ::testing::Eq;
using ::testing::IsEmpty;
@@ -213,5 +215,55 @@ TEST_F(OutgoingShareTargetInfoTest, CreateWifiCredentialsPayloads) {
EXPECT_THAT(attachment_payload_map.at(wifi1_.id()).payload_id.value(),
Eq(payloads[0].id));
}
TEST_F(OutgoingShareTargetInfoTest, CreateIntroductionFrameWithoutPayloads) {
EXPECT_THAT(info_.CreateIntroductionFrame(), Eq(nullptr));
}
TEST_F(OutgoingShareTargetInfoTest, CreateIntroductionFrameSuccess) {
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();
std::unique_ptr<IntroductionFrame> frame = info_.CreateIntroductionFrame();
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));
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));
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()));
// 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()));
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(),
Eq(wifi1_.security_type()));
EXPECT_THAT(frame->wifi_credentials_metadata(0).payload_id(),
Eq(wifi_payloads[0].id));
}
} // namespace
} // namespace nearby::sharing