mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Create AttachmentContainer class.
PiperOrigin-RevId: 639137658
This commit is contained in:
committed by
Copybara-Service
parent
a91f428e71
commit
13504726f9
+53
-20
@@ -29,25 +29,18 @@ cc_library(
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "types",
|
||||
name = "attachments",
|
||||
srcs = [
|
||||
"advertisement.cc",
|
||||
"attachment.cc",
|
||||
"attachment_info.cc",
|
||||
"attachment_container.cc",
|
||||
"file_attachment.cc",
|
||||
"share_target.cc",
|
||||
"text_attachment.cc",
|
||||
"wifi_credentials_attachment.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"advertisement.h",
|
||||
"attachment.h",
|
||||
"attachment_info.h",
|
||||
"attachment_container.h",
|
||||
"file_attachment.h",
|
||||
"nearby_connection.h",
|
||||
"nearby_connections_manager.h",
|
||||
"nearby_sharing_decoder.h",
|
||||
"share_target.h",
|
||||
"text_attachment.h",
|
||||
"wifi_credentials_attachment.h",
|
||||
],
|
||||
@@ -57,18 +50,47 @@ cc_library(
|
||||
"//sharing:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":connection_types",
|
||||
"//internal/crypto_cros",
|
||||
"//internal/network:url",
|
||||
"//sharing/common:compatible_u8_string",
|
||||
"//sharing/common:enum",
|
||||
"//sharing/internal/base",
|
||||
"//sharing/proto:wire_format_cc_proto",
|
||||
"@com_google_absl//absl/random",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:string_view",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "types",
|
||||
srcs = [
|
||||
"advertisement.cc",
|
||||
"attachment_info.cc",
|
||||
"share_target.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"advertisement.h",
|
||||
"attachment_info.h",
|
||||
"nearby_connection.h",
|
||||
"nearby_connections_manager.h",
|
||||
"nearby_sharing_decoder.h",
|
||||
"share_target.h",
|
||||
],
|
||||
visibility = [
|
||||
"//location/nearby/cpp/sharing:__subpackages__",
|
||||
"//location/nearby/sharing/sdk/quick_share_server:__pkg__",
|
||||
"//sharing:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":attachments",
|
||||
":connection_types",
|
||||
"//internal/network:url",
|
||||
"//sharing/common:enum",
|
||||
"//sharing/internal/public:logging",
|
||||
"//sharing/proto:enums_cc_proto",
|
||||
"//sharing/proto:wire_format_cc_proto",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/random",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
"@com_google_absl//absl/types:span",
|
||||
@@ -164,6 +186,7 @@ cc_library(
|
||||
"//sharing:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":attachments",
|
||||
":connection_types",
|
||||
":transfer_metadata",
|
||||
":types",
|
||||
@@ -215,7 +238,6 @@ cc_library(
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@com_google_protobuf//:protobuf_lite",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -234,6 +256,7 @@ cc_library(
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":attachments",
|
||||
":connection_types",
|
||||
":nearby_sharing_service",
|
||||
":transfer_metadata",
|
||||
@@ -393,6 +416,7 @@ cc_test(
|
||||
srcs = ["nearby_sharing_service_impl_test.cc"],
|
||||
shard_count = 10,
|
||||
deps = [
|
||||
":attachments",
|
||||
":connection_types",
|
||||
":nearby_sharing_service",
|
||||
":test_support",
|
||||
@@ -491,8 +515,8 @@ cc_test(
|
||||
name = "nearby_sharing_service_extension_test",
|
||||
srcs = ["nearby_sharing_service_extension_test.cc"],
|
||||
deps = [
|
||||
":attachments",
|
||||
":nearby_sharing_service",
|
||||
":types",
|
||||
"//internal/platform/implementation/g3", # fixdeps: keep
|
||||
"//internal/test",
|
||||
"//sharing/internal/test:nearby_test",
|
||||
@@ -531,13 +555,13 @@ cc_test(
|
||||
name = "payload_tracker_test",
|
||||
srcs = ["payload_tracker_test.cc"],
|
||||
deps = [
|
||||
":attachments",
|
||||
":connection_types",
|
||||
":nearby_sharing_service",
|
||||
":transfer_metadata",
|
||||
":types",
|
||||
"//internal/platform/implementation/g3", # fixdeps: keep
|
||||
"//internal/test",
|
||||
"//sharing/internal/public:types",
|
||||
"//sharing/internal/test:nearby_test",
|
||||
"//sharing/proto:wire_format_cc_proto",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
@@ -552,9 +576,9 @@ cc_test(
|
||||
name = "share_target_test",
|
||||
srcs = ["share_target_test.cc"],
|
||||
deps = [
|
||||
":attachments",
|
||||
":types",
|
||||
"//internal/network:url",
|
||||
"//internal/platform/implementation/g3", # fixdeps: keep
|
||||
"//sharing/common:enum",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
@@ -565,8 +589,7 @@ cc_test(
|
||||
name = "text_attachment_test",
|
||||
srcs = ["text_attachment_test.cc"],
|
||||
deps = [
|
||||
":types",
|
||||
"//internal/platform/implementation/g3", # fixdeps: keep
|
||||
":attachments",
|
||||
"//sharing/proto:wire_format_cc_proto",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
@@ -614,6 +637,16 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "attachment_container_test",
|
||||
srcs = ["attachment_container_test.cc"],
|
||||
deps = [
|
||||
":attachments",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "wrapped_share_target_discovered_callback_test",
|
||||
srcs = ["wrapped_share_target_discovered_callback_test.cc"],
|
||||
|
||||
@@ -28,6 +28,7 @@ cc_library(
|
||||
deps = [
|
||||
"//internal/analytics:event_logger",
|
||||
"//proto:sharing_enums_cc_proto",
|
||||
"//sharing:attachments",
|
||||
"//sharing:types",
|
||||
"//sharing/common:enum",
|
||||
"//sharing/internal/public:logging",
|
||||
@@ -48,6 +49,7 @@ cc_test(
|
||||
"//internal/analytics:mock_event_logger",
|
||||
"//internal/platform/implementation/g3", # fixdeps: keep
|
||||
"//proto:sharing_enums_cc_proto",
|
||||
"//sharing:attachments",
|
||||
"//sharing:types",
|
||||
"//sharing/common:enum",
|
||||
"//sharing/proto:enums_cc_proto",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
struct ShareTarget;
|
||||
class AttachmentContainer;
|
||||
|
||||
// A single attachment to be sent by / received from a ShareTarget, can be
|
||||
// either a file or text.
|
||||
@@ -65,8 +65,8 @@ class Attachment {
|
||||
int32_t batch_id() const { return batch_id_; }
|
||||
SourceType source_type() const { return source_type_; }
|
||||
|
||||
// Move the attachment to share target.
|
||||
virtual void MoveToShareTarget(ShareTarget& share_target) = 0;
|
||||
// Move the attachment to a container
|
||||
virtual void MoveToContainer(AttachmentContainer& container) = 0;
|
||||
virtual absl::string_view GetDescription() const = 0;
|
||||
virtual ShareType GetShareType() const = 0;
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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_container.h"
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
#include "sharing/wifi_credentials_attachment.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
|
||||
AttachmentContainer::AttachmentContainer(
|
||||
std::vector<TextAttachment> text_attachments,
|
||||
std::vector<FileAttachment> file_attachments,
|
||||
std::vector<WifiCredentialsAttachment> wifi_credentials_attachments)
|
||||
: text_attachments_(std::move(text_attachments)),
|
||||
file_attachments_(std::move(file_attachments)),
|
||||
wifi_credentials_attachments_(std::move(wifi_credentials_attachments)) {}
|
||||
|
||||
int64_t AttachmentContainer::GetTotalAttachmentsSize() const {
|
||||
int64_t size_in_bytes = 0;
|
||||
|
||||
for (const auto& file : file_attachments_) {
|
||||
size_in_bytes += file.size();
|
||||
}
|
||||
|
||||
for (const auto& text : text_attachments_) {
|
||||
size_in_bytes += text.size();
|
||||
}
|
||||
|
||||
for (const auto& wifi_credentials : wifi_credentials_attachments_) {
|
||||
size_in_bytes += wifi_credentials.size();
|
||||
}
|
||||
|
||||
return size_in_bytes;
|
||||
}
|
||||
|
||||
void AttachmentContainer::ClearAttachments() {
|
||||
// Reset file paths for file attachments.
|
||||
for (auto& file : file_attachments_)
|
||||
file.set_file_path(std::nullopt);
|
||||
|
||||
// Reset body of text attachments.
|
||||
for (auto& text : text_attachments_)
|
||||
text.set_text_body(std::string());
|
||||
|
||||
// Reset password of Wi-Fi credentials attachments.
|
||||
for (auto& wifi_credentials : wifi_credentials_attachments_) {
|
||||
wifi_credentials.set_password(std::string());
|
||||
wifi_credentials.set_is_hidden(false);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nearby::sharing
|
||||
@@ -0,0 +1,104 @@
|
||||
// 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_CONTAINER_H_
|
||||
#define THIRD_PARTY_NEARBY_SHARING_ATTACHMENT_CONTAINER_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
#include "sharing/wifi_credentials_attachment.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
|
||||
// A container for attachments.
|
||||
// This class is thread-compatible (go/thread-compatible).
|
||||
class AttachmentContainer {
|
||||
public:
|
||||
AttachmentContainer(
|
||||
std::vector<TextAttachment> text_attachments,
|
||||
std::vector<FileAttachment> file_attachments,
|
||||
std::vector<WifiCredentialsAttachment> wifi_credentials_attachments);
|
||||
AttachmentContainer() = default;
|
||||
AttachmentContainer(const AttachmentContainer&) = default;
|
||||
AttachmentContainer(AttachmentContainer&&) = default;
|
||||
AttachmentContainer& operator=(const AttachmentContainer&) = default;
|
||||
AttachmentContainer& operator=(AttachmentContainer&&) = default;
|
||||
~AttachmentContainer() = default;
|
||||
|
||||
const std::vector<TextAttachment>& GetTextAttachments() const {
|
||||
return text_attachments_;
|
||||
}
|
||||
const std::vector<FileAttachment>& GetFileAttachments() const {
|
||||
return file_attachments_;
|
||||
}
|
||||
const std::vector<WifiCredentialsAttachment>& GetWifiCredentialsAttachments()
|
||||
const {
|
||||
return wifi_credentials_attachments_;
|
||||
}
|
||||
|
||||
void AddTextAttachment(TextAttachment text_attachment) {
|
||||
text_attachments_.push_back(std::move(text_attachment));
|
||||
}
|
||||
void AddFileAttachment(FileAttachment file_attachment) {
|
||||
file_attachments_.push_back(std::move(file_attachment));
|
||||
}
|
||||
void AddWifiCredentialsAttachment(
|
||||
WifiCredentialsAttachment wifi_credentials_attachment) {
|
||||
wifi_credentials_attachments_.push_back(
|
||||
std::move(wifi_credentials_attachment));
|
||||
}
|
||||
|
||||
TextAttachment& GetMutableTextAttachment(int index) {
|
||||
return text_attachments_[index];
|
||||
}
|
||||
|
||||
FileAttachment& GetMutableFileAttachment(int index) {
|
||||
return file_attachments_[index];
|
||||
}
|
||||
|
||||
WifiCredentialsAttachment& GetMutableWifiCredentialsAttachment(int index) {
|
||||
return wifi_credentials_attachments_[index];
|
||||
}
|
||||
|
||||
// Returns the total number of attachments of all types.
|
||||
int GetAttachmentCount() const {
|
||||
return text_attachments_.size() + file_attachments_.size() +
|
||||
wifi_credentials_attachments_.size();
|
||||
}
|
||||
|
||||
// Returns the total size of all attachments.
|
||||
int64_t GetTotalAttachmentsSize() const;
|
||||
|
||||
// Returns true if there are any attachments.
|
||||
bool HasAttachments() const {
|
||||
return !text_attachments_.empty() || !file_attachments_.empty() ||
|
||||
!wifi_credentials_attachments_.empty();
|
||||
}
|
||||
|
||||
// Clear the contents of all attachments, but leaving the attachments in
|
||||
// place.
|
||||
void ClearAttachments();
|
||||
|
||||
private:
|
||||
std::vector<TextAttachment> text_attachments_;
|
||||
std::vector<FileAttachment> file_attachments_;
|
||||
std::vector<WifiCredentialsAttachment> wifi_credentials_attachments_;
|
||||
};
|
||||
|
||||
} // namespace nearby::sharing
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_SHARING_ATTACHMENT_CONTAINER_H_
|
||||
@@ -0,0 +1,190 @@
|
||||
// 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_container.h"
|
||||
|
||||
#include <filesystem> // NOLINT
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "sharing/attachment.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 {
|
||||
|
||||
using testing::Eq;
|
||||
using testing::IsFalse;
|
||||
using testing::IsTrue;
|
||||
using testing::UnorderedElementsAre;
|
||||
|
||||
class AttachmentContainerTest : public ::testing::Test {
|
||||
protected:
|
||||
AttachmentContainerTest()
|
||||
: text1_(/*id=*/12345L,
|
||||
nearby::sharing::service::proto::TextMetadata::URL,
|
||||
"A bit of text body", "Some text title", /*size=*/18,
|
||||
"text/html", /*batch_id=*/987654,
|
||||
nearby::sharing::Attachment::SourceType::kDragAndDrop),
|
||||
text2_(/*id=*/98564L,
|
||||
nearby::sharing::service::proto::TextMetadata::ADDRESS,
|
||||
"A bit of text body 2", "Some text title 2", /*size=*/20,
|
||||
"text/plain",
|
||||
/*batch_id=*/456547,
|
||||
nearby::sharing::Attachment::SourceType::kContextMenu),
|
||||
file1_(/*id=*/436346, /*size=*/100000, "someFileName", "image/jpeg",
|
||||
nearby::sharing::service::proto::FileMetadata::IMAGE,
|
||||
"/usr/local/tmp", /*batch_id=*/66657L,
|
||||
nearby::sharing::Attachment::SourceType::kSelectFilesButton),
|
||||
wifi1_(
|
||||
/*id=*/57457L, "GoogleGuest",
|
||||
nearby::sharing::service::proto::WifiCredentialsMetadata::WPA_PSK,
|
||||
"somepassword", true, /*batch_id=*/99707L,
|
||||
nearby::sharing::Attachment::SourceType::kPaste) {
|
||||
file1_.set_file_path(
|
||||
std::filesystem::u8path("/usr/local/tmp/someFileName.jpg"));
|
||||
}
|
||||
|
||||
TextAttachment text1_;
|
||||
TextAttachment text2_;
|
||||
FileAttachment file1_;
|
||||
WifiCredentialsAttachment wifi1_;
|
||||
};
|
||||
|
||||
TEST_F(AttachmentContainerTest, Constructor) {
|
||||
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
std::vector<WifiCredentialsAttachment>{wifi1_});
|
||||
|
||||
EXPECT_THAT(container.GetTextAttachments(),
|
||||
UnorderedElementsAre(text1_, text2_));
|
||||
EXPECT_THAT(container.GetFileAttachments(), UnorderedElementsAre(file1_));
|
||||
EXPECT_THAT(container.GetWifiCredentialsAttachments(),
|
||||
UnorderedElementsAre(wifi1_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, AddTextAttachment) {
|
||||
AttachmentContainer container;
|
||||
|
||||
container.AddTextAttachment(text1_);
|
||||
container.AddTextAttachment(text2_);
|
||||
|
||||
EXPECT_THAT(container.GetTextAttachments(),
|
||||
UnorderedElementsAre(text1_, text2_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, AddFileAttachment) {
|
||||
AttachmentContainer container;
|
||||
|
||||
container.AddFileAttachment(file1_);
|
||||
|
||||
EXPECT_THAT(container.GetFileAttachments(), UnorderedElementsAre(file1_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, AddWifiCredentialsAttachment) {
|
||||
AttachmentContainer container;
|
||||
|
||||
container.AddWifiCredentialsAttachment(wifi1_);
|
||||
|
||||
EXPECT_THAT(container.GetWifiCredentialsAttachments(),
|
||||
UnorderedElementsAre(wifi1_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, GetMutableTextAttachment) {
|
||||
AttachmentContainer container;
|
||||
|
||||
container.AddTextAttachment(text1_);
|
||||
container.AddTextAttachment(text2_);
|
||||
|
||||
EXPECT_THAT(container.GetMutableTextAttachment(0), Eq(text1_));
|
||||
EXPECT_THAT(container.GetMutableTextAttachment(1), Eq(text2_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, GetMutableFileAttachment) {
|
||||
AttachmentContainer container;
|
||||
|
||||
container.AddFileAttachment(file1_);
|
||||
|
||||
EXPECT_THAT(container.GetMutableFileAttachment(0), Eq(file1_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, GetMutableWifiCredentialsAttachment) {
|
||||
AttachmentContainer container;
|
||||
|
||||
container.AddWifiCredentialsAttachment(wifi1_);
|
||||
|
||||
EXPECT_THAT(container.GetMutableWifiCredentialsAttachment(0), Eq(wifi1_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, AttachmentCount) {
|
||||
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
std::vector<WifiCredentialsAttachment>{wifi1_});
|
||||
|
||||
EXPECT_THAT(container.GetAttachmentCount(), Eq(4));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, GetTotalAttachmentsSize) {
|
||||
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
std::vector<WifiCredentialsAttachment>{});
|
||||
|
||||
EXPECT_THAT(container.GetTotalAttachmentsSize(), Eq(18 + 20 + 100000));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, HasAttachments) {
|
||||
AttachmentContainer container;
|
||||
|
||||
EXPECT_THAT(container.HasAttachments(), IsFalse());
|
||||
|
||||
container.AddWifiCredentialsAttachment(wifi1_);
|
||||
|
||||
EXPECT_THAT(container.HasAttachments(), IsTrue());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby::sharing
|
||||
@@ -14,22 +14,20 @@
|
||||
|
||||
#include "sharing/file_attachment.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem> // NOLINT(build/c++17)
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "sharing/attachment.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/common/compatible_u8_string.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/internal/base/mime.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
#include "sharing/share_target.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
@@ -80,8 +78,8 @@ FileAttachment::FileAttachment(int64_t id, int64_t size, std::string file_name,
|
||||
type_(type),
|
||||
parent_folder_(std::move(parent_folder)) {}
|
||||
|
||||
void FileAttachment::MoveToShareTarget(ShareTarget& share_target) {
|
||||
share_target.file_attachments.push_back(std::move(*this));
|
||||
void FileAttachment::MoveToContainer(AttachmentContainer& container) {
|
||||
container.AddFileAttachment(std::move(*this));
|
||||
}
|
||||
|
||||
absl::string_view FileAttachment::GetDescription() const { return file_name_; }
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_SHARING_FILE_ATTACHMENT_H_
|
||||
#define THIRD_PARTY_NEARBY_SHARING_FILE_ATTACHMENT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem> // NOLINT(build/c++17)
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -32,7 +31,7 @@ namespace sharing {
|
||||
|
||||
// A single attachment to be sent by / received from a |ShareTarget|, can be
|
||||
// either a file or text.
|
||||
struct ShareTarget;
|
||||
class AttachmentContainer;
|
||||
|
||||
class FileAttachment : public Attachment {
|
||||
public:
|
||||
@@ -60,7 +59,7 @@ class FileAttachment : public Attachment {
|
||||
}
|
||||
|
||||
// Attachment:
|
||||
void MoveToShareTarget(ShareTarget& share_target) override;
|
||||
void MoveToContainer(AttachmentContainer& container) override;
|
||||
absl::string_view GetDescription() const override;
|
||||
ShareType GetShareType() const override;
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "internal/network/url.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/internal/public/logging.h"
|
||||
#include "sharing/nearby_sharing_service.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
#include "sharing/wifi_credentials_attachment.h"
|
||||
|
||||
@@ -39,23 +39,21 @@ using StatusCodes = ::nearby::sharing::NearbySharingService::StatusCodes;
|
||||
} // namespace
|
||||
|
||||
NearbySharingService::StatusCodes NearbySharingServiceExtension::Open(
|
||||
const ShareTarget& share_target) {
|
||||
if (share_target.file_attachments.empty() &&
|
||||
share_target.text_attachments.empty() &&
|
||||
share_target.wifi_credentials_attachments.empty()) {
|
||||
return StatusCodes::kOk;
|
||||
const AttachmentContainer& container) {
|
||||
if (!container.HasAttachments()) {
|
||||
return StatusCodes::kInvalidArgument;
|
||||
}
|
||||
|
||||
if (!share_target.file_attachments.empty() &&
|
||||
!share_target.text_attachments.empty()) {
|
||||
if (!container.GetFileAttachments().empty() &&
|
||||
!container.GetTextAttachments().empty()) {
|
||||
NL_LOG(ERROR)
|
||||
<< __func__
|
||||
<< ": Text attachments and file attachments can't come together.";
|
||||
return StatusCodes::kError;
|
||||
}
|
||||
|
||||
if (share_target.text_attachments.size() == 1) {
|
||||
const TextAttachment& text_attachment = share_target.text_attachments[0];
|
||||
if (container.GetTextAttachments().size() == 1) {
|
||||
const TextAttachment& text_attachment = container.GetTextAttachments()[0];
|
||||
|
||||
switch (text_attachment.type()) {
|
||||
case TextMetadata::TEXT: {
|
||||
@@ -75,30 +73,30 @@ NearbySharingService::StatusCodes NearbySharingServiceExtension::Open(
|
||||
return StatusCodes::kOk;
|
||||
}
|
||||
|
||||
if (share_target.text_attachments.size() > 1) {
|
||||
if (container.GetTextAttachments().size() > 1) {
|
||||
NL_LOG(ERROR) << __func__
|
||||
<< ": Multiple text attachments are not supported currently.";
|
||||
return StatusCodes::kError;
|
||||
}
|
||||
|
||||
if (share_target.wifi_credentials_attachments.size() == 1) {
|
||||
if (container.GetWifiCredentialsAttachments().size() == 1) {
|
||||
const WifiCredentialsAttachment& wifi_credentials_attachment =
|
||||
share_target.wifi_credentials_attachments[0];
|
||||
container.GetWifiCredentialsAttachments()[0];
|
||||
JoinWifiNetwork(wifi_credentials_attachment.ssid(),
|
||||
wifi_credentials_attachment.password());
|
||||
return StatusCodes::kOk;
|
||||
}
|
||||
|
||||
if (share_target.wifi_credentials_attachments.size() > 1) {
|
||||
if (container.GetWifiCredentialsAttachments().size() > 1) {
|
||||
NL_LOG(ERROR) << __func__
|
||||
<< ": Multiple WiFi credentials attachments are not "
|
||||
"supported currently.";
|
||||
return StatusCodes::kError;
|
||||
}
|
||||
|
||||
const FileAttachment& file_attachment = share_target.file_attachments[0];
|
||||
const FileAttachment& file_attachment = container.GetFileAttachments()[0];
|
||||
|
||||
if ((share_target.file_attachments.size() > 1) ||
|
||||
if ((container.GetFileAttachments().size() > 1) ||
|
||||
((file_attachment.type() != FileMetadata::AUDIO) &&
|
||||
(file_attachment.type() != FileMetadata::VIDEO) &&
|
||||
(file_attachment.type() != FileMetadata::IMAGE))) {
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/network/url.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/internal/public/context.h"
|
||||
#include "sharing/nearby_sharing_service.h"
|
||||
#include "sharing/nearby_sharing_settings.h"
|
||||
#include "sharing/share_target.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
@@ -33,7 +33,7 @@ class NearbySharingServiceExtension {
|
||||
: context_(context), settings_(settings) {}
|
||||
|
||||
// Opens attachments from the remote |share_target|.
|
||||
NearbySharingService::StatusCodes Open(const ShareTarget& share_target);
|
||||
NearbySharingService::StatusCodes Open(const AttachmentContainer& container);
|
||||
|
||||
// Opens an url target on a browser instance.
|
||||
void OpenUrl(const ::nearby::network::Url& url);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "internal/test/fake_device_info.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/internal/test/fake_context.h"
|
||||
#include "sharing/internal/test/fake_preference_manager.h"
|
||||
@@ -28,7 +29,6 @@
|
||||
#include "sharing/nearby_sharing_service.h"
|
||||
#include "sharing/nearby_sharing_settings.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
#include "sharing/wifi_credentials_attachment.h"
|
||||
|
||||
@@ -66,120 +66,113 @@ class NearbySharingServiceExtensionTest : public ::testing::Test {
|
||||
&local_device_data_manager_};
|
||||
};
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest,
|
||||
OpenSharedTargetNoFileAndTextAttachment) {
|
||||
ShareTarget share_target;
|
||||
StatusCodes status_codes = service_extension()->Open(share_target);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenEmptyAttachments) {
|
||||
StatusCodes status_codes = service_extension()->Open(AttachmentContainer());
|
||||
EXPECT_EQ(status_codes, StatusCodes::kInvalidArgument);
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest,
|
||||
OpenSharedTargetBothFileAndTextAttachments) {
|
||||
ShareTarget share_target;
|
||||
share_target.text_attachments = {
|
||||
TextAttachment(TextMetadata::TEXT, "body", "title", "mime")};
|
||||
share_target.file_attachments = {
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.g1")};
|
||||
StatusCodes status_codes = service_extension()->Open(share_target);
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenBothFileAndTextAttachments) {
|
||||
AttachmentContainer container;
|
||||
container.AddTextAttachment(
|
||||
TextAttachment(TextMetadata::TEXT, "body", "title", "mime"));
|
||||
container.AddFileAttachment(
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.g1"));
|
||||
StatusCodes status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kError);
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenSharedTargetOneTextAttachment) {
|
||||
ShareTarget share_target;
|
||||
share_target.text_attachments = {
|
||||
TextAttachment(TextMetadata::TEXT, "body", "title", "mime")};
|
||||
StatusCodes status_codes = service_extension()->Open(share_target);
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenOneTextAttachment) {
|
||||
AttachmentContainer container;
|
||||
container.AddTextAttachment(
|
||||
TextAttachment(TextMetadata::TEXT, "body", "title", "mime"));
|
||||
StatusCodes status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest,
|
||||
OpenSharedMoreThanOneTextAttachments) {
|
||||
ShareTarget share_target;
|
||||
share_target.text_attachments = {
|
||||
TextAttachment(TextMetadata::TEXT, "body", "title1", "mime"),
|
||||
TextAttachment(TextMetadata::TEXT, "body", "title2", "mime")};
|
||||
StatusCodes status_codes = service_extension()->Open(share_target);
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenMoreThanOneTextAttachments) {
|
||||
AttachmentContainer container;
|
||||
container.AddTextAttachment(
|
||||
TextAttachment(TextMetadata::TEXT, "body", "title1", "mime"));
|
||||
container.AddTextAttachment(
|
||||
TextAttachment(TextMetadata::TEXT, "body", "title2", "mime"));
|
||||
StatusCodes status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kError);
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenShareTargetWithUrlAttacchment) {
|
||||
ShareTarget share_target;
|
||||
share_target.text_attachments = {TextAttachment(
|
||||
TextMetadata::URL, "http://www.google.com", std::nullopt, std::nullopt)};
|
||||
StatusCodes status_codes = service_extension()->Open(share_target);
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenUrlAttacchment) {
|
||||
AttachmentContainer container;
|
||||
container.AddTextAttachment(TextAttachment(
|
||||
TextMetadata::URL, "http://www.google.com", std::nullopt, std::nullopt));
|
||||
StatusCodes status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest,
|
||||
OpenShareTargetWithTextAddressAttacchment) {
|
||||
ShareTarget share_target;
|
||||
share_target.text_attachments = {TextAttachment(TextMetadata::ADDRESS, "body",
|
||||
std::nullopt, std::nullopt)};
|
||||
StatusCodes status_codes = service_extension()->Open(share_target);
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenTextAddressAttacchment) {
|
||||
AttachmentContainer container;
|
||||
container.AddTextAttachment(TextAttachment(TextMetadata::ADDRESS, "body",
|
||||
std::nullopt, std::nullopt));
|
||||
StatusCodes status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenShareTargetWithWifiAttacchment) {
|
||||
ShareTarget share_target;
|
||||
share_target.wifi_credentials_attachments = {WifiCredentialsAttachment(
|
||||
"ssid", service::proto::WifiCredentialsMetadata::WPA_PSK)};
|
||||
StatusCodes status_codes = service_extension()->Open(share_target);
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenWifiAttacchment) {
|
||||
AttachmentContainer container;
|
||||
container.AddWifiCredentialsAttachment(WifiCredentialsAttachment(
|
||||
"ssid", service::proto::WifiCredentialsMetadata::WPA_PSK));
|
||||
StatusCodes status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest,
|
||||
OpenShareTargetWithMultipleWifiAttacchments) {
|
||||
ShareTarget share_target;
|
||||
share_target.wifi_credentials_attachments = {
|
||||
WifiCredentialsAttachment(
|
||||
"ssid1", service::proto::WifiCredentialsMetadata::WPA_PSK),
|
||||
WifiCredentialsAttachment(
|
||||
"ssid2", service::proto::WifiCredentialsMetadata::WPA_PSK)};
|
||||
StatusCodes status_codes = service_extension()->Open(share_target);
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenMultipleWifiAttacchments) {
|
||||
AttachmentContainer container;
|
||||
container.AddWifiCredentialsAttachment(WifiCredentialsAttachment(
|
||||
"ssid1", service::proto::WifiCredentialsMetadata::WPA_PSK));
|
||||
container.AddWifiCredentialsAttachment(WifiCredentialsAttachment(
|
||||
"ssid2", service::proto::WifiCredentialsMetadata::WPA_PSK));
|
||||
StatusCodes status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kError);
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest,
|
||||
OpenShareTargetWithOneFileAttacchment) {
|
||||
ShareTarget share_target;
|
||||
share_target.file_attachments = {FileAttachment(
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenOneFileAttacchment) {
|
||||
AttachmentContainer container;
|
||||
container.AddFileAttachment(FileAttachment(
|
||||
/*id=*/1234, /*size=*/1000, /*file_name=*/"test.png",
|
||||
/*mime_type=*/"image", /*type=*/FileMetadata::IMAGE)};
|
||||
StatusCodes status_codes = service_extension()->Open(share_target);
|
||||
/*mime_type=*/"image", /*type=*/FileMetadata::IMAGE));
|
||||
StatusCodes status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenSharedTargetUseDownloadFolder) {
|
||||
ShareTarget share_target;
|
||||
share_target.file_attachments = {
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.g1"),
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.g2")};
|
||||
StatusCodes status_codes = service_extension()->Open(share_target);
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenUseDownloadFolder) {
|
||||
AttachmentContainer container;
|
||||
container.AddFileAttachment(
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.g1"));
|
||||
container.AddFileAttachment(
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.g2"));
|
||||
StatusCodes status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
FakeShell& shell = *context()->fake_shell();
|
||||
shell.set_return_error(true);
|
||||
status_codes = service_extension()->Open(share_target);
|
||||
status_codes = service_extension()->Open(container);
|
||||
EXPECT_NE(status_codes, StatusCodes::kOk);
|
||||
shell.set_return_error(false);
|
||||
status_codes = service_extension()->Open(share_target);
|
||||
status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceExtensionTest,
|
||||
OpenSharedTargetUseDefaultApplication) {
|
||||
ShareTarget share_target;
|
||||
TEST_F(NearbySharingServiceExtensionTest, OpenUseDefaultApplication) {
|
||||
AttachmentContainer container;
|
||||
NearbySharingService::StatusCodes status_codes;
|
||||
share_target.file_attachments = {
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.jpg")};
|
||||
status_codes = service_extension()->Open(share_target);
|
||||
container.AddFileAttachment(
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.jpg"));
|
||||
status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
share_target.file_attachments = {
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.wav")};
|
||||
status_codes = service_extension()->Open(share_target);
|
||||
container.AddFileAttachment(
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.wav"));
|
||||
status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
share_target.file_attachments = {
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.wmv")};
|
||||
status_codes = service_extension()->Open(share_target);
|
||||
container.AddFileAttachment(
|
||||
FileAttachment(std::filesystem::temp_directory_path() / "test.wmv"));
|
||||
status_codes = service_extension()->Open(container);
|
||||
EXPECT_EQ(status_codes, StatusCodes::kOk);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#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"
|
||||
#include "sharing/certificates/nearby_share_certificate_manager.h"
|
||||
@@ -706,14 +707,16 @@ void NearbySharingServiceImpl::SendAttachments(
|
||||
}
|
||||
|
||||
ShareTarget share_target = info->share_target();
|
||||
AttachmentContainer& container = share_target.attachment_container;
|
||||
for (std::unique_ptr<Attachment>& attachment : attachments) {
|
||||
attachment->MoveToShareTarget(share_target);
|
||||
attachment->MoveToContainer(container);
|
||||
}
|
||||
if (!share_target.has_attachments()) {
|
||||
if (!container.HasAttachments()) {
|
||||
std::move(status_codes_callback)(StatusCodes::kInvalidArgument);
|
||||
return;
|
||||
}
|
||||
for (const FileAttachment& attachment : share_target.file_attachments) {
|
||||
for (const FileAttachment& attachment :
|
||||
container.GetFileAttachments()) {
|
||||
if (!attachment.file_path()) {
|
||||
NL_LOG(WARNING) << __func__ << ": Got file attachment without path";
|
||||
std::move(status_codes_callback)(StatusCodes::kInvalidArgument);
|
||||
@@ -973,7 +976,8 @@ void NearbySharingServiceImpl::Open(
|
||||
share_target.GetAttachments(),
|
||||
info != nullptr ? info->session_id() : 0);
|
||||
|
||||
status_codes_callback(service_extension_->Open(share_target));
|
||||
status_codes_callback(
|
||||
service_extension_->Open(share_target.attachment_container));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2525,8 +2529,9 @@ void NearbySharingServiceImpl::ReceivePayloads(
|
||||
std::filesystem::path download_path =
|
||||
std::filesystem::u8path(settings_->GetCustomSavePath());
|
||||
|
||||
const AttachmentContainer& container = share_target.attachment_container;
|
||||
// Register payload path for all valid file payloads.
|
||||
for (auto& file : share_target.file_attachments) {
|
||||
for (const auto& file : container.GetFileAttachments()) {
|
||||
std::optional<int64_t> payload_id = GetAttachmentPayloadId(file.id());
|
||||
if (!payload_id) {
|
||||
NL_LOG(WARNING)
|
||||
@@ -2588,7 +2593,8 @@ void NearbySharingServiceImpl::OnPayloadPathsRegistered(
|
||||
receiving_session_id_, share_target.GetAttachments());
|
||||
|
||||
info->set_payload_tracker(std::make_shared<PayloadTracker>(
|
||||
context_, share_target, attachment_info_map_,
|
||||
context_, share_target.id, share_target.attachment_container,
|
||||
attachment_info_map_,
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnPayloadTransferUpdate,
|
||||
this)));
|
||||
|
||||
@@ -2624,7 +2630,7 @@ void NearbySharingServiceImpl::OnPayloadPathsRegistered(
|
||||
.build());
|
||||
|
||||
std::string endpoint_id = info->endpoint_id();
|
||||
if (share_target.GetTotalAttachmentsSize() >=
|
||||
if (share_target.attachment_container.GetTotalAttachmentsSize() >=
|
||||
kAttachmentsSizeThresholdOverHighQualityMedium) {
|
||||
// Upgrade bandwidth regardless of advertising visibility because either
|
||||
// the system or the user has verified the sender's identity; the
|
||||
@@ -2731,8 +2737,9 @@ void NearbySharingServiceImpl::SendIntroduction(
|
||||
introduction->set_start_transfer(true);
|
||||
NL_VLOG(1) << __func__ << ": Sending attachments to " << share_target.id;
|
||||
|
||||
const AttachmentContainer& container = share_target.attachment_container;
|
||||
// Write introduction of file payloads.
|
||||
for (const auto& file : share_target.file_attachments) {
|
||||
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";
|
||||
@@ -2748,7 +2755,7 @@ void NearbySharingServiceImpl::SendIntroduction(
|
||||
}
|
||||
|
||||
// Write introduction of text payloads.
|
||||
for (const auto& text : share_target.text_attachments) {
|
||||
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";
|
||||
@@ -2764,7 +2771,7 @@ void NearbySharingServiceImpl::SendIntroduction(
|
||||
|
||||
// Write introduction of Wi-Fi credentials payloads.
|
||||
for (const auto& wifi_credentials :
|
||||
share_target.wifi_credentials_attachments) {
|
||||
container.GetWifiCredentialsAttachments()) {
|
||||
std::optional<int64_t> payload_id =
|
||||
GetAttachmentPayloadId(wifi_credentials.id());
|
||||
if (!payload_id) {
|
||||
@@ -2832,18 +2839,18 @@ void NearbySharingServiceImpl::CreatePayloads(
|
||||
std::move(callback)(std::move(share_target), /*success=*/false);
|
||||
return;
|
||||
}
|
||||
|
||||
info.set_text_payloads(CreateTextPayloads(share_target.text_attachments));
|
||||
const AttachmentContainer& container = share_target.attachment_container;
|
||||
info.set_text_payloads(CreateTextPayloads(container.GetTextAttachments()));
|
||||
info.set_wifi_credentials_payloads(
|
||||
CreateWifiCredentialsPayloads(share_target.wifi_credentials_attachments));
|
||||
if (share_target.file_attachments.empty()) {
|
||||
CreateWifiCredentialsPayloads(container.GetWifiCredentialsAttachments()));
|
||||
if (container.GetFileAttachments().empty()) {
|
||||
std::move(callback)(std::move(share_target), /*success=*/true);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> file_paths;
|
||||
file_paths.reserve(share_target.file_attachments.size());
|
||||
for (const FileAttachment& attachment : share_target.file_attachments) {
|
||||
file_paths.reserve(container.GetFileAttachments().size());
|
||||
for (const FileAttachment& attachment : container.GetFileAttachments()) {
|
||||
file_paths.push_back(*attachment.file_path());
|
||||
}
|
||||
|
||||
@@ -2893,7 +2900,7 @@ void NearbySharingServiceImpl::OnCreatePayloads(
|
||||
nearby_connections_manager_->Connect(
|
||||
std::move(endpoint_info), info->endpoint_id(),
|
||||
std::move(bluetooth_mac_address), settings_->GetDataUsage(),
|
||||
GetTransportType(share_target),
|
||||
GetTransportType(share_target.attachment_container),
|
||||
[this, share_target, info](NearbyConnection* connection, Status status) {
|
||||
// Log analytics event of new connection.
|
||||
info->set_connection_layer_status(status);
|
||||
@@ -2920,7 +2927,8 @@ void NearbySharingServiceImpl::OnOpenFiles(
|
||||
ShareTarget share_target, std::function<void(ShareTarget, bool)> callback,
|
||||
std::vector<NearbyFileHandler::FileInfo> files) {
|
||||
OutgoingShareTargetInfo* info = GetOutgoingShareTargetInfo(share_target.id);
|
||||
if (!info || files.size() != share_target.file_attachments.size()) {
|
||||
AttachmentContainer& container = share_target.attachment_container;
|
||||
if (!info || files.size() != container.GetFileAttachments().size()) {
|
||||
std::move(callback)(std::move(share_target), /*success=*/false);
|
||||
return;
|
||||
}
|
||||
@@ -2929,7 +2937,7 @@ void NearbySharingServiceImpl::OnOpenFiles(
|
||||
payloads.reserve(files.size());
|
||||
|
||||
for (size_t i = 0; i < files.size(); ++i) {
|
||||
FileAttachment& attachment = share_target.file_attachments[i];
|
||||
FileAttachment& attachment = container.GetMutableFileAttachment(i);
|
||||
attachment.set_size(files[i].size);
|
||||
InputFile input_file;
|
||||
input_file.path = files[i].file_path;
|
||||
@@ -3138,7 +3146,8 @@ void NearbySharingServiceImpl::OnIncomingTransferUpdate(
|
||||
if (metadata.is_final_status()) {
|
||||
// Log analytics event of receiving attachment end.
|
||||
int64_t received_bytes =
|
||||
share_target.GetTotalAttachmentsSize() * metadata.progress() / 100;
|
||||
share_target.attachment_container.GetTotalAttachmentsSize() *
|
||||
metadata.progress() / 100;
|
||||
AttachmentTransmissionStatus transmission_status =
|
||||
ConvertToTransmissionStatus(metadata.status());
|
||||
|
||||
@@ -3186,7 +3195,8 @@ void NearbySharingServiceImpl::OnOutgoingTransferUpdate(
|
||||
if (metadata.is_final_status()) {
|
||||
// Log analytics event of sending attachment end.
|
||||
int64_t sent_bytes =
|
||||
share_target.GetTotalAttachmentsSize() * metadata.progress() / 100;
|
||||
share_target.attachment_container.GetTotalAttachmentsSize() *
|
||||
metadata.progress() / 100;
|
||||
AttachmentTransmissionStatus transmission_status =
|
||||
ConvertToTransmissionStatus(metadata.status());
|
||||
|
||||
@@ -3517,6 +3527,7 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
|
||||
nearby::sharing::service::proto::IntroductionFrame introduction_frame =
|
||||
std::move(frame->introduction());
|
||||
|
||||
AttachmentContainer& container = share_target.attachment_container;
|
||||
for (const auto& file : introduction_frame.file_metadata()) {
|
||||
if (file.size() <= 0) {
|
||||
Fail(share_target.id,
|
||||
@@ -3536,7 +3547,7 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
|
||||
file.mime_type(), file.type(),
|
||||
file.parent_folder());
|
||||
SetAttachmentPayloadId(attachment, file.payload_id());
|
||||
share_target.file_attachments.push_back(std::move(attachment));
|
||||
container.AddFileAttachment(std::move(attachment));
|
||||
|
||||
if (std::numeric_limits<int64_t>::max() - file.size() < file_size_sum) {
|
||||
Fail(share_target.id, TransferMetadata::Status::kNotEnoughSpace);
|
||||
@@ -3564,7 +3575,7 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
|
||||
TextAttachment attachment(text.id(), text.type(), text.text_title(),
|
||||
text.size());
|
||||
SetAttachmentPayloadId(attachment, text.payload_id());
|
||||
share_target.text_attachments.push_back(std::move(attachment));
|
||||
container.AddTextAttachment(std::move(attachment));
|
||||
}
|
||||
|
||||
if (kSupportReceivingWifiCredentials) {
|
||||
@@ -3578,12 +3589,11 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
|
||||
wifi_credentials.ssid(),
|
||||
wifi_credentials.security_type());
|
||||
SetAttachmentPayloadId(attachment, wifi_credentials.payload_id());
|
||||
share_target.wifi_credentials_attachments.push_back(
|
||||
std::move(attachment));
|
||||
container.AddWifiCredentialsAttachment(std::move(attachment));
|
||||
}
|
||||
}
|
||||
|
||||
if (!share_target.has_attachments()) {
|
||||
if (!container.HasAttachments()) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
<< ": No attachment is found for this share target. It can "
|
||||
"be result of unrecognizable attachment type";
|
||||
@@ -3616,7 +3626,7 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
|
||||
kUpgradeBandwidthAfterAccept)) {
|
||||
if (introduction_frame.has_start_transfer() &&
|
||||
introduction_frame.start_transfer()) {
|
||||
if (share_target.GetTotalAttachmentsSize() >=
|
||||
if (container.GetTotalAttachmentsSize() >=
|
||||
kAttachmentsSizeThresholdOverHighQualityMedium) {
|
||||
NL_LOG(INFO)
|
||||
<< __func__
|
||||
@@ -3697,7 +3707,8 @@ void NearbySharingServiceImpl::OnReceiveConnectionResponse(
|
||||
.build());
|
||||
|
||||
info->set_payload_tracker(std::make_unique<PayloadTracker>(
|
||||
context_, share_target, attachment_info_map_,
|
||||
context_, share_target.id, share_target.attachment_container,
|
||||
attachment_info_map_,
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnPayloadTransferUpdate,
|
||||
this)));
|
||||
|
||||
@@ -3906,8 +3917,9 @@ void NearbySharingServiceImpl::HandleProgressUpdateFrame(
|
||||
progress_update_frame.start_transfer()) {
|
||||
ShareTargetInfo* info = GetShareTargetInfo(share_target.id);
|
||||
|
||||
if (info != nullptr && share_target.GetTotalAttachmentsSize() >=
|
||||
kAttachmentsSizeThresholdOverHighQualityMedium) {
|
||||
if (info != nullptr &&
|
||||
share_target.attachment_container.GetTotalAttachmentsSize() >=
|
||||
kAttachmentsSizeThresholdOverHighQualityMedium) {
|
||||
NL_LOG(INFO)
|
||||
<< __func__
|
||||
<< ": Upgrade bandwidth when receiving progress update frame "
|
||||
@@ -4051,20 +4063,7 @@ void NearbySharingServiceImpl::OnPayloadTransferUpdate(
|
||||
if (!OnIncomingPayloadsComplete(share_target)) {
|
||||
payload_incomplete = true;
|
||||
|
||||
// Reset file paths for file attachments.
|
||||
for (auto& file : share_target.file_attachments)
|
||||
file.set_file_path(std::nullopt);
|
||||
|
||||
// Reset body of text attachments.
|
||||
for (auto& text : share_target.text_attachments)
|
||||
text.set_text_body(std::string());
|
||||
|
||||
// Reset password of Wi-Fi credentials attachments.
|
||||
for (auto& wifi_credentials :
|
||||
share_target.wifi_credentials_attachments) {
|
||||
wifi_credentials.set_password(std::string());
|
||||
wifi_credentials.set_is_hidden(false);
|
||||
}
|
||||
share_target.attachment_container.ClearAttachments();
|
||||
}
|
||||
|
||||
if (IsBackgroundScanningFeatureEnabled()) {
|
||||
@@ -4126,7 +4125,9 @@ bool NearbySharingServiceImpl::OnIncomingPayloadsComplete(
|
||||
UpdateFilePath(share_target);
|
||||
}
|
||||
|
||||
for (auto& text : share_target.text_attachments) {
|
||||
AttachmentContainer& container = share_target.attachment_container;
|
||||
for (int i = 0; i < container.GetTextAttachments().size(); ++i) {
|
||||
TextAttachment& text = container.GetMutableTextAttachment(i);
|
||||
AttachmentInfo& attachment_info = attachment_info_map_[text.id()];
|
||||
std::optional<int64_t> payload_id = attachment_info.payload_id;
|
||||
if (!payload_id) {
|
||||
@@ -4134,7 +4135,6 @@ bool NearbySharingServiceImpl::OnIncomingPayloadsComplete(
|
||||
<< text.id();
|
||||
return false;
|
||||
}
|
||||
|
||||
Payload* incoming_payload =
|
||||
nearby_connections_manager_->GetIncomingPayload(*payload_id);
|
||||
if (!incoming_payload || !incoming_payload->content.is_bytes()) {
|
||||
@@ -4158,8 +4158,9 @@ bool NearbySharingServiceImpl::OnIncomingPayloadsComplete(
|
||||
attachment_info.text_body = std::move(text_body);
|
||||
}
|
||||
|
||||
for (auto& wifi_credentials_attachment :
|
||||
share_target.wifi_credentials_attachments) {
|
||||
for (int i = 0; i < container.GetWifiCredentialsAttachments().size(); ++i) {
|
||||
WifiCredentialsAttachment& wifi_credentials_attachment =
|
||||
container.GetMutableWifiCredentialsAttachment(i);
|
||||
AttachmentInfo& attachment_info =
|
||||
attachment_info_map_[wifi_credentials_attachment.id()];
|
||||
std::optional<int64_t> payload_id = attachment_info.payload_id;
|
||||
@@ -4206,7 +4207,10 @@ bool NearbySharingServiceImpl::OnIncomingPayloadsComplete(
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::UpdateFilePath(ShareTarget& share_target) {
|
||||
for (auto& file : share_target.file_attachments) {
|
||||
for (int i = 0;
|
||||
i < share_target.attachment_container.GetFileAttachments().size(); ++i) {
|
||||
FileAttachment& file =
|
||||
share_target.attachment_container.GetMutableFileAttachment(i);
|
||||
// Skip file if it already has file_path set.
|
||||
if (file.file_path().has_value()) {
|
||||
continue;
|
||||
@@ -4254,7 +4258,8 @@ void NearbySharingServiceImpl::RemoveIncomingPayloads(
|
||||
files_for_deletion.push_back(*it);
|
||||
}
|
||||
}
|
||||
for (const auto& file : share_target.file_attachments) {
|
||||
const AttachmentContainer& container = share_target.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__
|
||||
@@ -4780,14 +4785,14 @@ NearbySharingServiceImpl::GetSenderUseCase() {
|
||||
}
|
||||
|
||||
TransportType NearbySharingServiceImpl::GetTransportType(
|
||||
const ShareTarget& share_target) const {
|
||||
if (share_target.GetTotalAttachmentsSize() >
|
||||
const AttachmentContainer& container) const {
|
||||
if (container.GetTotalAttachmentsSize() >
|
||||
kAttachmentsSizeThresholdOverHighQualityMedium) {
|
||||
NL_LOG(INFO) << __func__ << ": Transport type is kHighQuality";
|
||||
return TransportType::kHighQuality;
|
||||
}
|
||||
|
||||
if (share_target.file_attachments.empty()) {
|
||||
if (container.GetFileAttachments().empty()) {
|
||||
NL_LOG(INFO) << __func__ << ": Transport type is kNonDisruptive";
|
||||
return TransportType::kNonDisruptive;
|
||||
}
|
||||
|
||||
@@ -480,8 +480,8 @@ class NearbySharingServiceImpl
|
||||
// Returns use case of sender. It is used by group share feature.
|
||||
::location::nearby::proto::sharing::SharingUseCase GetSenderUseCase();
|
||||
|
||||
// Calculates transport type on share target.
|
||||
TransportType GetTransportType(const ShareTarget& share_target) const;
|
||||
// Calculates transport type based on attachment size.
|
||||
TransportType GetTransportType(const AttachmentContainer& container) const;
|
||||
|
||||
// Update file path for the file attachment.
|
||||
void UpdateFilePath(ShareTarget& share_target);
|
||||
|
||||
@@ -1172,15 +1172,19 @@ class NearbySharingServiceImplTest : public testing::Test {
|
||||
EXPECT_TRUE(metadata.is_final_status());
|
||||
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kComplete);
|
||||
|
||||
ASSERT_TRUE(share_target.has_attachments());
|
||||
EXPECT_EQ(1u, share_target.file_attachments.size());
|
||||
for (const FileAttachment& file : share_target.file_attachments) {
|
||||
const AttachmentContainer& container =
|
||||
share_target.attachment_container;
|
||||
ASSERT_TRUE(container.HasAttachments());
|
||||
EXPECT_EQ(1u, container.GetFileAttachments().size());
|
||||
for (const FileAttachment& file :
|
||||
container.GetFileAttachments()) {
|
||||
EXPECT_TRUE(file.file_path());
|
||||
file_path = *file.file_path();
|
||||
}
|
||||
|
||||
EXPECT_EQ(3u, share_target.text_attachments.size());
|
||||
for (const TextAttachment& text : share_target.text_attachments) {
|
||||
EXPECT_EQ(3u, container.GetTextAttachments().size());
|
||||
for (const TextAttachment& text :
|
||||
container.GetTextAttachments()) {
|
||||
EXPECT_EQ(text.text_body(), kTextPayload);
|
||||
}
|
||||
|
||||
@@ -1702,7 +1706,7 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
.WillOnce([&](ShareTarget share_target) {
|
||||
EXPECT_FALSE(share_target.is_incoming);
|
||||
EXPECT_TRUE(share_target.is_known);
|
||||
EXPECT_FALSE(share_target.has_attachments());
|
||||
EXPECT_FALSE(share_target.attachment_container.HasAttachments());
|
||||
EXPECT_EQ(share_target.device_name, kDeviceName);
|
||||
EXPECT_EQ(share_target.type, kDeviceType);
|
||||
EXPECT_TRUE(share_target.device_id);
|
||||
@@ -1756,7 +1760,7 @@ TEST_F(NearbySharingServiceImplTest, RegisterSendSurfaceEmptyCertificate) {
|
||||
.WillOnce([](ShareTarget share_target) {
|
||||
EXPECT_FALSE(share_target.is_incoming);
|
||||
EXPECT_FALSE(share_target.is_known);
|
||||
EXPECT_FALSE(share_target.has_attachments());
|
||||
EXPECT_FALSE(share_target.attachment_container.HasAttachments());
|
||||
EXPECT_EQ(share_target.device_name, kDeviceName);
|
||||
EXPECT_FALSE(share_target.image_url);
|
||||
EXPECT_EQ(share_target.type, kDeviceType);
|
||||
@@ -2541,7 +2545,7 @@ TEST_F(NearbySharingServiceImplTest, IncomingConnectionEmptyIntroductionFrame) {
|
||||
TransferMetadata::Status::kUnsupportedAttachmentType);
|
||||
EXPECT_TRUE(share_target.is_incoming);
|
||||
EXPECT_TRUE(share_target.is_known);
|
||||
EXPECT_FALSE(share_target.has_attachments());
|
||||
EXPECT_FALSE(share_target.attachment_container.HasAttachments());
|
||||
EXPECT_EQ(share_target.device_name, kDeviceName);
|
||||
EXPECT_EQ(share_target.type, kDeviceType);
|
||||
EXPECT_TRUE(share_target.device_id);
|
||||
@@ -2586,11 +2590,13 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
EXPECT_FALSE(metadata.is_final_status());
|
||||
EXPECT_EQ(TransferMetadata::Status::kAwaitingLocalConfirmation,
|
||||
metadata.status());
|
||||
const AttachmentContainer& container =
|
||||
share_target.attachment_container;
|
||||
EXPECT_TRUE(share_target.is_incoming);
|
||||
EXPECT_FALSE(share_target.is_known);
|
||||
EXPECT_TRUE(share_target.has_attachments());
|
||||
EXPECT_EQ(share_target.text_attachments.size(), 3u);
|
||||
EXPECT_EQ(share_target.file_attachments.size(), 1u);
|
||||
EXPECT_TRUE(container.HasAttachments());
|
||||
EXPECT_EQ(container.GetTextAttachments().size(), 3u);
|
||||
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
|
||||
EXPECT_EQ(share_target.device_name, kDeviceName);
|
||||
EXPECT_FALSE(share_target.image_url);
|
||||
EXPECT_EQ(share_target.type, kDeviceType);
|
||||
@@ -2702,11 +2708,13 @@ TEST_F(NearbySharingServiceImplTest, IncomingConnectionOutOfStorage) {
|
||||
EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_))
|
||||
.WillOnce(testing::Invoke([](const ShareTarget& share_target,
|
||||
TransferMetadata metadata) {
|
||||
const AttachmentContainer& container =
|
||||
share_target.attachment_container;
|
||||
EXPECT_TRUE(share_target.is_incoming);
|
||||
EXPECT_TRUE(share_target.is_known);
|
||||
EXPECT_TRUE(share_target.has_attachments());
|
||||
EXPECT_EQ(share_target.text_attachments.size(), 0u);
|
||||
EXPECT_EQ(share_target.file_attachments.size(), 1u);
|
||||
EXPECT_TRUE(container.HasAttachments());
|
||||
EXPECT_EQ(container.GetTextAttachments().size(), 0u);
|
||||
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
|
||||
EXPECT_EQ(share_target.device_name, kDeviceName);
|
||||
EXPECT_EQ(share_target.type, kDeviceType);
|
||||
EXPECT_TRUE(share_target.device_id);
|
||||
@@ -2826,11 +2834,13 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
EXPECT_FALSE(metadata.is_final_status());
|
||||
EXPECT_EQ(TransferMetadata::Status::kAwaitingLocalConfirmation,
|
||||
metadata.status());
|
||||
const AttachmentContainer& container =
|
||||
share_target.attachment_container;
|
||||
EXPECT_TRUE(share_target.is_incoming);
|
||||
EXPECT_TRUE(share_target.is_known);
|
||||
EXPECT_TRUE(share_target.has_attachments());
|
||||
EXPECT_EQ(share_target.text_attachments.size(), 3u);
|
||||
EXPECT_EQ(share_target.file_attachments.size(), 1u);
|
||||
EXPECT_TRUE(container.HasAttachments());
|
||||
EXPECT_EQ(container.GetTextAttachments().size(), 3u);
|
||||
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
|
||||
EXPECT_EQ(share_target.device_name, kDeviceName);
|
||||
EXPECT_EQ(share_target.type, kDeviceType);
|
||||
EXPECT_TRUE(share_target.device_id);
|
||||
@@ -2976,9 +2986,11 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
EXPECT_TRUE(metadata.is_final_status());
|
||||
EXPECT_EQ(metadata.status(),
|
||||
TransferMetadata::Status::kIncompletePayloads);
|
||||
ASSERT_TRUE(share_target.has_attachments());
|
||||
EXPECT_EQ(share_target.file_attachments.size(), 1u);
|
||||
const FileAttachment& file = share_target.file_attachments[0];
|
||||
const AttachmentContainer& container =
|
||||
share_target.attachment_container;
|
||||
ASSERT_TRUE(container.HasAttachments());
|
||||
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
|
||||
const FileAttachment& file = container.GetFileAttachments()[0];
|
||||
EXPECT_FALSE(file.file_path());
|
||||
success_notification.Notify();
|
||||
}));
|
||||
@@ -3040,9 +3052,11 @@ TEST_F(NearbySharingServiceImplTest, AcceptValidShareTargetPayloadFailed) {
|
||||
[&](const ShareTarget& share_target, TransferMetadata metadata) {
|
||||
EXPECT_TRUE(metadata.is_final_status());
|
||||
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kFailed);
|
||||
ASSERT_TRUE(share_target.has_attachments());
|
||||
EXPECT_EQ(share_target.file_attachments.size(), 1u);
|
||||
const FileAttachment& file = share_target.file_attachments[0];
|
||||
const AttachmentContainer& container =
|
||||
share_target.attachment_container;
|
||||
ASSERT_TRUE(container.HasAttachments());
|
||||
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
|
||||
const FileAttachment& file = container.GetFileAttachments()[0];
|
||||
EXPECT_FALSE(file.file_path());
|
||||
failure_notification.Notify();
|
||||
}));
|
||||
@@ -3105,9 +3119,11 @@ TEST_F(NearbySharingServiceImplTest, AcceptValidShareTargetPayloadCancelled) {
|
||||
[&](const ShareTarget& share_target, TransferMetadata metadata) {
|
||||
EXPECT_TRUE(metadata.is_final_status());
|
||||
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kCancelled);
|
||||
ASSERT_TRUE(share_target.has_attachments());
|
||||
EXPECT_EQ(share_target.file_attachments.size(), 1u);
|
||||
const FileAttachment& file = share_target.file_attachments[0];
|
||||
const AttachmentContainer& container =
|
||||
share_target.attachment_container;
|
||||
ASSERT_TRUE(container.HasAttachments());
|
||||
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
|
||||
const FileAttachment& file = container.GetFileAttachments()[0];
|
||||
EXPECT_FALSE(file.file_path());
|
||||
failure_notification.Notify();
|
||||
}));
|
||||
@@ -3208,9 +3224,11 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
TransferMetadata::Status::kAwaitingLocalConfirmation);
|
||||
EXPECT_TRUE(share_target.is_incoming);
|
||||
EXPECT_TRUE(share_target.is_known);
|
||||
EXPECT_TRUE(share_target.has_attachments());
|
||||
EXPECT_EQ(share_target.text_attachments.size(), 3u);
|
||||
EXPECT_EQ(share_target.file_attachments.size(), 1u);
|
||||
const AttachmentContainer& container =
|
||||
share_target.attachment_container;
|
||||
EXPECT_TRUE(container.HasAttachments());
|
||||
EXPECT_EQ(container.GetTextAttachments().size(), 3u);
|
||||
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
|
||||
EXPECT_EQ(share_target.device_name, kDeviceName);
|
||||
EXPECT_EQ(share_target.type, kDeviceType);
|
||||
EXPECT_TRUE(share_target.device_id);
|
||||
@@ -3260,9 +3278,11 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
metadata.status());
|
||||
EXPECT_TRUE(share_target.is_incoming);
|
||||
EXPECT_TRUE(share_target.is_known);
|
||||
EXPECT_TRUE(share_target.has_attachments());
|
||||
EXPECT_EQ(share_target.text_attachments.size(), 3u);
|
||||
EXPECT_EQ(share_target.file_attachments.size(), 1u);
|
||||
const AttachmentContainer& container =
|
||||
share_target.attachment_container;
|
||||
EXPECT_TRUE(container.HasAttachments());
|
||||
EXPECT_EQ(container.GetTextAttachments().size(), 3u);
|
||||
EXPECT_EQ(container.GetFileAttachments().size(), 1u);
|
||||
EXPECT_EQ(share_target.device_name, kDeviceName);
|
||||
EXPECT_EQ(share_target.type, kDeviceType);
|
||||
EXPECT_TRUE(share_target.device_id);
|
||||
@@ -4447,8 +4467,8 @@ TEST_F(NearbySharingServiceImplTest, RetryDiscoveredEndpointsDownloadLimit) {
|
||||
|
||||
TEST_F(NearbySharingServiceImplTest, OpenSharedTarget) {
|
||||
ShareTarget share_target;
|
||||
share_target.text_attachments = {
|
||||
TextAttachment(TextMetadata::TEXT, "body", "title", "mime")};
|
||||
share_target.attachment_container.AddTextAttachment(
|
||||
TextAttachment(TextMetadata::TEXT, "body", "title", "mime"));
|
||||
NearbySharingService::StatusCodes result;
|
||||
absl::Notification notification;
|
||||
service_->Open(share_target,
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/attachment_info.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_connections_types.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
#include "sharing/transfer_metadata.h"
|
||||
#include "sharing/transfer_metadata_builder.h"
|
||||
@@ -41,16 +41,17 @@ namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
PayloadTracker::PayloadTracker(
|
||||
Context* context, const ShareTarget& share_target,
|
||||
Context* context, int64_t share_target_id,
|
||||
const AttachmentContainer& container,
|
||||
const absl::flat_hash_map<int64_t, AttachmentInfo>& attachment_info_map,
|
||||
std::function<void(int64_t, TransferMetadata)> update_callback)
|
||||
: context_(context),
|
||||
share_target_id_(share_target.id),
|
||||
share_target_id_(share_target_id),
|
||||
update_callback_(std::move(update_callback)) {
|
||||
total_transfer_size_ = 0;
|
||||
confirmed_transfer_size_ = 0;
|
||||
|
||||
for (const auto& file : share_target.file_attachments) {
|
||||
for (const auto& file : container.GetFileAttachments()) {
|
||||
auto it = attachment_info_map.find(file.id());
|
||||
if (it == attachment_info_map.end() || !it->second.payload_id) {
|
||||
NL_LOG(WARNING)
|
||||
@@ -66,7 +67,7 @@ PayloadTracker::PayloadTracker(
|
||||
total_transfer_size_ += file.size();
|
||||
}
|
||||
|
||||
for (const auto& text : share_target.text_attachments) {
|
||||
for (const auto& text : container.GetTextAttachments()) {
|
||||
auto it = attachment_info_map.find(text.id());
|
||||
if (it == attachment_info_map.end() || !it->second.payload_id) {
|
||||
NL_LOG(WARNING)
|
||||
@@ -83,7 +84,7 @@ PayloadTracker::PayloadTracker(
|
||||
}
|
||||
|
||||
for (const auto& wifi_credentials :
|
||||
share_target.wifi_credentials_attachments) {
|
||||
container.GetWifiCredentialsAttachments()) {
|
||||
auto it = attachment_info_map.find(wifi_credentials.id());
|
||||
if (it == attachment_info_map.end() || !it->second.payload_id) {
|
||||
NL_LOG(WARNING) << __func__
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/attachment_info.h"
|
||||
#include "sharing/internal/public/context.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/transfer_metadata.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -40,7 +40,8 @@ namespace sharing {
|
||||
class PayloadTracker : public NearbyConnectionsManager::PayloadStatusListener {
|
||||
public:
|
||||
PayloadTracker(
|
||||
Context* context, const ShareTarget& share_target,
|
||||
Context* context, int64_t share_target_id,
|
||||
const AttachmentContainer& container,
|
||||
const absl::flat_hash_map<int64_t, AttachmentInfo>& attachment_info_map,
|
||||
std::function<void(int64_t, TransferMetadata)> update_callback);
|
||||
~PayloadTracker() override;
|
||||
|
||||
@@ -26,18 +26,19 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/test/fake_clock.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/attachment_info.h"
|
||||
#include "sharing/file_attachment.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/transfer_metadata.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
namespace {
|
||||
|
||||
constexpr int64_t kShareTargetId = 123456789L;
|
||||
constexpr int64_t kFileId = 1;
|
||||
constexpr int64_t kFileSize = 100 * 1024; // 100KB
|
||||
constexpr absl::string_view kFileName = "test.jpg";
|
||||
@@ -46,17 +47,16 @@ constexpr absl::string_view kMimeType = "image/jpg";
|
||||
class PayloadTrackerTest : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
share_target_.file_attachments.clear();
|
||||
share_target_.file_attachments.push_back(FileAttachment(
|
||||
container_.AddFileAttachment(FileAttachment(
|
||||
kFileId, kFileSize, std::string(kFileName), std::string(kMimeType),
|
||||
service::proto::FileMetadata::IMAGE));
|
||||
attachment_info_map_.clear();
|
||||
AttachmentInfo attachment_info;
|
||||
attachment_info.payload_id = kFileId;
|
||||
attachment_info_map_.emplace(share_target_.file_attachments.at(0).id(),
|
||||
attachment_info_map_.emplace(container_.GetFileAttachments()[0].id(),
|
||||
std::move(attachment_info));
|
||||
payload_tracker_ = std::make_unique<PayloadTracker>(
|
||||
context(), share_target_, attachment_info_map_,
|
||||
context(), kShareTargetId, container_, attachment_info_map_,
|
||||
[&](int64_t share_target_id, TransferMetadata transfer_metadata) {
|
||||
current_percentage_ = transfer_metadata.progress();
|
||||
});
|
||||
@@ -83,7 +83,7 @@ class PayloadTrackerTest : public ::testing::Test {
|
||||
|
||||
std::unique_ptr<PayloadTracker> payload_tracker_ = nullptr;
|
||||
float current_percentage_ = 0.0;
|
||||
ShareTarget share_target_;
|
||||
AttachmentContainer container_;
|
||||
absl::flat_hash_map<int64_t, AttachmentInfo> attachment_info_map_;
|
||||
};
|
||||
|
||||
|
||||
+23
-37
@@ -53,9 +53,9 @@ ShareTarget::ShareTarget(
|
||||
: device_name(std::move(device_name)),
|
||||
image_url(std::move(image_url)),
|
||||
type(type),
|
||||
text_attachments(std::move(text_attachments)),
|
||||
file_attachments(std::move(file_attachments)),
|
||||
wifi_credentials_attachments(std::move(wifi_credentials_attachments)),
|
||||
attachment_container(std::move(text_attachments),
|
||||
std::move(file_attachments),
|
||||
std::move(wifi_credentials_attachments)),
|
||||
is_incoming(is_incoming),
|
||||
full_name(std::move(full_name)),
|
||||
is_known(is_known),
|
||||
@@ -77,13 +77,15 @@ ShareTarget::~ShareTarget() = default;
|
||||
std::vector<int64_t> ShareTarget::GetAttachmentIds() const {
|
||||
std::vector<int64_t> attachment_ids;
|
||||
|
||||
attachment_ids.reserve(file_attachments.size() + text_attachments.size() +
|
||||
wifi_credentials_attachments.size());
|
||||
for (const auto& file : file_attachments) attachment_ids.push_back(file.id());
|
||||
attachment_ids.reserve(attachment_container.GetAttachmentCount());
|
||||
for (const auto& file : attachment_container.GetFileAttachments())
|
||||
attachment_ids.push_back(file.id());
|
||||
|
||||
for (const auto& text : text_attachments) attachment_ids.push_back(text.id());
|
||||
for (const auto& text : attachment_container.GetTextAttachments())
|
||||
attachment_ids.push_back(text.id());
|
||||
|
||||
for (const auto& wifi_credentials : wifi_credentials_attachments)
|
||||
for (const auto& wifi_credentials :
|
||||
attachment_container.GetWifiCredentialsAttachments())
|
||||
attachment_ids.push_back(wifi_credentials.id());
|
||||
|
||||
return attachment_ids;
|
||||
@@ -91,17 +93,17 @@ std::vector<int64_t> ShareTarget::GetAttachmentIds() const {
|
||||
|
||||
std::vector<std::unique_ptr<Attachment>> ShareTarget::GetAttachments() const {
|
||||
std::vector<std::unique_ptr<Attachment>> attachments;
|
||||
attachments.reserve(file_attachments.size() + text_attachments.size() +
|
||||
wifi_credentials_attachments.size());
|
||||
for (const auto& file : file_attachments) {
|
||||
attachments.reserve(attachment_container.GetAttachmentCount());
|
||||
for (const auto& file : attachment_container.GetFileAttachments()) {
|
||||
attachments.push_back(std::make_unique<FileAttachment>(file));
|
||||
}
|
||||
|
||||
for (const auto& text : text_attachments) {
|
||||
for (const auto& text : attachment_container.GetTextAttachments()) {
|
||||
attachments.push_back(std::make_unique<TextAttachment>(text));
|
||||
}
|
||||
|
||||
for (const auto& wifi_credentials : wifi_credentials_attachments) {
|
||||
for (const auto& wifi_credentials :
|
||||
attachment_container.GetWifiCredentialsAttachments()) {
|
||||
attachments.push_back(
|
||||
std::make_unique<WifiCredentialsAttachment>(wifi_credentials));
|
||||
}
|
||||
@@ -110,21 +112,7 @@ std::vector<std::unique_ptr<Attachment>> ShareTarget::GetAttachments() const {
|
||||
}
|
||||
|
||||
int64_t ShareTarget::GetTotalAttachmentsSize() const {
|
||||
int64_t size_in_bytes = 0;
|
||||
|
||||
for (const auto& file : file_attachments) {
|
||||
size_in_bytes += file.size();
|
||||
}
|
||||
|
||||
for (const auto& text : text_attachments) {
|
||||
size_in_bytes += text.size();
|
||||
}
|
||||
|
||||
for (const auto& wifi_credentials : wifi_credentials_attachments) {
|
||||
size_in_bytes += wifi_credentials.size();
|
||||
}
|
||||
|
||||
return size_in_bytes;
|
||||
return attachment_container.GetTotalAttachmentsSize();
|
||||
}
|
||||
|
||||
std::string ShareTarget::ToString() const {
|
||||
@@ -142,11 +130,14 @@ std::string ShareTarget::ToString() const {
|
||||
fmt.push_back(absl::StrFormat("device_id: %s", *device_id));
|
||||
}
|
||||
fmt.push_back(
|
||||
absl::StrFormat("file_attachments_size: %d", file_attachments.size()));
|
||||
absl::StrFormat("file_attachments_size: %d",
|
||||
attachment_container.GetFileAttachments().size()));
|
||||
fmt.push_back(
|
||||
absl::StrFormat("text_attachments_size: %d", text_attachments.size()));
|
||||
fmt.push_back(absl::StrFormat("wifi_credentials_attachments_size: %d",
|
||||
wifi_credentials_attachments.size()));
|
||||
absl::StrFormat("text_attachments_size: %d",
|
||||
attachment_container.GetTextAttachments().size()));
|
||||
fmt.push_back(absl::StrFormat(
|
||||
"wifi_credentials_attachments_size: %d",
|
||||
attachment_container.GetWifiCredentialsAttachments().size()));
|
||||
fmt.push_back(absl::StrFormat("is_known: %d", is_known));
|
||||
fmt.push_back(absl::StrFormat("is_incoming: %d", is_incoming));
|
||||
fmt.push_back(absl::StrFormat("for_self_share: %d", for_self_share));
|
||||
@@ -155,10 +146,5 @@ std::string ShareTarget::ToString() const {
|
||||
return absl::StrCat("ShareTarget<", absl::StrJoin(fmt, ", "), ">");
|
||||
}
|
||||
|
||||
bool ShareTarget::has_attachments() const {
|
||||
return !text_attachments.empty() || !file_attachments.empty() ||
|
||||
!wifi_credentials_attachments.empty();
|
||||
}
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "internal/network/url.h"
|
||||
#include "sharing/attachment.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
@@ -48,7 +49,6 @@ struct ShareTarget {
|
||||
ShareTarget& operator=(ShareTarget&&);
|
||||
~ShareTarget();
|
||||
|
||||
bool has_attachments() const;
|
||||
std::vector<int64_t> GetAttachmentIds() const;
|
||||
std::vector<std::unique_ptr<Attachment>> GetAttachments() const;
|
||||
int64_t GetTotalAttachmentsSize() const;
|
||||
@@ -59,9 +59,7 @@ struct ShareTarget {
|
||||
// Uri that points to an image of the ShareTarget, if one exists.
|
||||
std::optional<::nearby::network::Url> image_url;
|
||||
ShareTargetType type = ShareTargetType::kUnknown;
|
||||
std::vector<TextAttachment> text_attachments;
|
||||
std::vector<FileAttachment> file_attachments;
|
||||
std::vector<WifiCredentialsAttachment> wifi_credentials_attachments;
|
||||
AttachmentContainer attachment_container;
|
||||
bool is_incoming = false;
|
||||
std::optional<std::string> full_name;
|
||||
// True if the local device has the PublicCertificate this target is
|
||||
|
||||
@@ -15,22 +15,21 @@
|
||||
#include "sharing/text_attachment.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/network/url.h"
|
||||
#include "sharing/attachment.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
#include "sharing/share_target.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
@@ -147,8 +146,8 @@ TextAttachment::TextAttachment(int64_t id, Type type, std::string text_body,
|
||||
text_body_(std::move(text_body)),
|
||||
mime_type_(std::move(mime_type)) {}
|
||||
|
||||
void TextAttachment::MoveToShareTarget(ShareTarget& share_target) {
|
||||
share_target.text_attachments.push_back(std::move(*this));
|
||||
void TextAttachment::MoveToContainer(AttachmentContainer& container) {
|
||||
container.AddTextAttachment(std::move(*this));
|
||||
}
|
||||
|
||||
absl::string_view TextAttachment::GetDescription() const { return text_title_; }
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_SHARING_TEXT_ATTACHMENT_H_
|
||||
#define THIRD_PARTY_NEARBY_SHARING_TEXT_ATTACHMENT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
@@ -29,7 +28,7 @@ namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
// Represents a text attachment.
|
||||
struct ShareTarget;
|
||||
class AttachmentContainer;
|
||||
|
||||
class TextAttachment : public Attachment {
|
||||
public:
|
||||
@@ -56,7 +55,7 @@ class TextAttachment : public Attachment {
|
||||
Type type() const { return type_; }
|
||||
|
||||
// Attachment:
|
||||
void MoveToShareTarget(ShareTarget& share_target) override;
|
||||
void MoveToContainer(AttachmentContainer& container) override;
|
||||
absl::string_view GetDescription() const override;
|
||||
ShareType GetShareType() const override;
|
||||
|
||||
|
||||
@@ -14,15 +14,14 @@
|
||||
|
||||
#include "sharing/wifi_credentials_attachment.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "sharing/attachment.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/share_target.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
@@ -48,8 +47,9 @@ WifiCredentialsAttachment::WifiCredentialsAttachment(
|
||||
password_(std::move(password)),
|
||||
is_hidden_(is_hidden) {}
|
||||
|
||||
void WifiCredentialsAttachment::MoveToShareTarget(ShareTarget& share_target) {
|
||||
share_target.wifi_credentials_attachments.push_back(std::move(*this));
|
||||
void WifiCredentialsAttachment::MoveToContainer(
|
||||
AttachmentContainer& container) {
|
||||
container.AddWifiCredentialsAttachment(std::move(*this));
|
||||
}
|
||||
|
||||
absl::string_view WifiCredentialsAttachment::GetDescription() const {
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_SHARING_WIFI_CREDENTIALS_ATTACHMENT_H_
|
||||
#define THIRD_PARTY_NEARBY_SHARING_WIFI_CREDENTIALS_ATTACHMENT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
@@ -28,7 +27,7 @@ namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
// Represents a WiFi credentials attachment.
|
||||
struct ShareTarget;
|
||||
class AttachmentContainer;
|
||||
|
||||
class WifiCredentialsAttachment : public Attachment {
|
||||
public:
|
||||
@@ -57,7 +56,7 @@ class WifiCredentialsAttachment : public Attachment {
|
||||
bool is_hidden() const { return is_hidden_; }
|
||||
|
||||
// Attachment:
|
||||
void MoveToShareTarget(ShareTarget& share_target) override;
|
||||
void MoveToContainer(AttachmentContainer& container) override;
|
||||
absl::string_view GetDescription() const override;
|
||||
ShareType GetShareType() const override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user