mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Merge remote-tracking branch 'nearby/main' into apply-upstream
# Conflicts: # MODULE.bazel # connections/implementation/mediums/ble_v2.cc # internal/platform/implementation/BUILD
This commit is contained in:
+69
-9
@@ -61,6 +61,8 @@ cc_library(
|
||||
"//sharing/common:enum",
|
||||
"//sharing/internal/base",
|
||||
"//sharing/proto:wire_format_cc_proto",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/random",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
@@ -113,7 +115,6 @@ cc_library(
|
||||
"transfer_metadata.h",
|
||||
"transfer_metadata_builder.h",
|
||||
],
|
||||
compatible_with = ["//buildenv/target:non_prod"],
|
||||
visibility = [
|
||||
"//location/nearby/apps/better_together/windows/nearby_share:__subpackages__",
|
||||
"//location/nearby/cpp/sharing:__subpackages__",
|
||||
@@ -220,6 +221,7 @@ cc_library(
|
||||
":attachments",
|
||||
":connection_types",
|
||||
":incoming_frame_reader",
|
||||
":nearby_sharing_util",
|
||||
":paired_key_verification_runner",
|
||||
":thread_timer",
|
||||
":transfer_metadata",
|
||||
@@ -269,16 +271,15 @@ cc_library(
|
||||
":thread_timer",
|
||||
":transfer_metadata",
|
||||
":types",
|
||||
"//internal/flags:nearby_flags",
|
||||
"//internal/platform:types",
|
||||
"//proto:sharing_enums_cc_proto",
|
||||
"//sharing/analytics",
|
||||
"//sharing/certificates",
|
||||
"//sharing/flags/generated:generated_flags",
|
||||
"//sharing/internal/public:logging",
|
||||
"//sharing/proto:enums_cc_proto",
|
||||
"//sharing/proto:share_cc_proto",
|
||||
"//sharing/proto:wire_format_cc_proto",
|
||||
"@com_google_absl//absl/base:nullability",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/strings",
|
||||
@@ -287,6 +288,25 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "nearby_sharing_util",
|
||||
srcs = ["nearby_sharing_util.cc"],
|
||||
hdrs = ["nearby_sharing_util.h"],
|
||||
deps = [
|
||||
":types",
|
||||
"//internal/base:file_path",
|
||||
"//internal/platform:types",
|
||||
"//proto:sharing_enums_cc_proto",
|
||||
"//sharing/certificates",
|
||||
"//sharing/common:enum",
|
||||
"//sharing/internal/base",
|
||||
"//sharing/internal/public:logging",
|
||||
"@com_google_absl//absl/hash",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:string_view",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "nearby_sharing_service",
|
||||
srcs = [
|
||||
@@ -300,7 +320,6 @@ cc_library(
|
||||
"nearby_sharing_service_factory.cc",
|
||||
"nearby_sharing_service_impl.cc",
|
||||
"nearby_sharing_settings.cc",
|
||||
"nearby_sharing_util.cc",
|
||||
"service_observers.cc",
|
||||
"service_observers.h",
|
||||
"transfer_manager.cc",
|
||||
@@ -319,7 +338,6 @@ cc_library(
|
||||
"nearby_sharing_service_factory.h",
|
||||
"nearby_sharing_service_impl.h",
|
||||
"nearby_sharing_settings.h",
|
||||
"nearby_sharing_util.h",
|
||||
"payload_listener.h",
|
||||
"share_target_discovered_callback.h",
|
||||
"transfer_manager.h",
|
||||
@@ -341,6 +359,7 @@ cc_library(
|
||||
":incoming_frame_reader",
|
||||
":nearby_connection_impl",
|
||||
":nearby_sharing_decoder",
|
||||
":nearby_sharing_util",
|
||||
":outgoing_targets_manager",
|
||||
":paired_key_verification_runner",
|
||||
":share_session",
|
||||
@@ -356,6 +375,7 @@ cc_library(
|
||||
"//internal/flags:nearby_flags",
|
||||
"//internal/network:url",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:mac_address",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation:account_manager",
|
||||
@@ -366,6 +386,7 @@ cc_library(
|
||||
"//sharing/common",
|
||||
"//sharing/common:enum",
|
||||
"//sharing/contacts",
|
||||
"//sharing/contacts:contacts_interface",
|
||||
"//sharing/fast_initiation:nearby_fast_initiation",
|
||||
"//sharing/flags/generated:generated_flags",
|
||||
"//sharing/internal/api:platform",
|
||||
@@ -384,7 +405,6 @@ cc_library(
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/functional:bind_front",
|
||||
"@com_google_absl//absl/hash",
|
||||
"@com_google_absl//absl/meta:type_traits",
|
||||
"@com_google_absl//absl/random",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
@@ -570,7 +590,7 @@ cc_test(
|
||||
"//internal/test",
|
||||
"//sharing/common:enum",
|
||||
"//sharing/flags/generated:generated_flags",
|
||||
"//sharing/internal/public:types",
|
||||
"//sharing/internal/public:logging",
|
||||
"//sharing/internal/test:nearby_test",
|
||||
"//sharing/proto:enums_cc_proto",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
@@ -612,14 +632,12 @@ cc_test(
|
||||
"//sharing/certificates:test_support",
|
||||
"//sharing/common",
|
||||
"//sharing/common:enum",
|
||||
"//sharing/contacts",
|
||||
"//sharing/contacts:test_support",
|
||||
"//sharing/fast_initiation:nearby_fast_initiation",
|
||||
"//sharing/fast_initiation:test_support",
|
||||
"//sharing/flags/generated:generated_flags",
|
||||
"//sharing/internal/api:mock_sharing_platform",
|
||||
"//sharing/internal/api:platform",
|
||||
"//sharing/internal/public:types",
|
||||
"//sharing/internal/test:nearby_test",
|
||||
"//sharing/local_device_data",
|
||||
"//sharing/local_device_data:test_support",
|
||||
@@ -720,6 +738,23 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "nearby_sharing_util_test",
|
||||
srcs = ["nearby_sharing_util_test.cc"],
|
||||
deps = [
|
||||
":nearby_sharing_util",
|
||||
"//internal/platform/implementation:platform_impl",
|
||||
"//sharing/certificates",
|
||||
"//sharing/proto:enums_cc_proto",
|
||||
"//sharing/proto:share_cc_proto",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:string_view",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "payload_tracker_test",
|
||||
srcs = ["payload_tracker_test.cc"],
|
||||
@@ -855,6 +890,7 @@ cc_test(
|
||||
":types",
|
||||
"//internal/analytics:mock_event_logger",
|
||||
"//internal/base:file_path",
|
||||
"//internal/base:files",
|
||||
"//internal/network:url",
|
||||
"//internal/platform/implementation:platform_impl",
|
||||
"//internal/test",
|
||||
@@ -921,6 +957,8 @@ cc_test(
|
||||
deps = [
|
||||
":connection_types",
|
||||
":nearby_sharing_service",
|
||||
"//connections:core_types",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation:platform_impl",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
@@ -940,3 +978,25 @@ cc_test(
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "outgoing_targets_manager_test",
|
||||
srcs = ["outgoing_targets_manager_test.cc"],
|
||||
deps = [
|
||||
":attachments",
|
||||
":connection_types",
|
||||
":nearby_connection_impl",
|
||||
":outgoing_targets_manager",
|
||||
":share_session",
|
||||
":test_support",
|
||||
":transfer_metadata",
|
||||
":types",
|
||||
"//internal/base:file_path",
|
||||
"//internal/platform/implementation:platform_impl",
|
||||
"//internal/test",
|
||||
"//sharing/analytics",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/strings:string_view",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
@@ -38,9 +39,7 @@
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
namespace analytics {
|
||||
namespace nearby::sharing::analytics {
|
||||
namespace {
|
||||
|
||||
using ::location::nearby::proto::sharing::EventCategory;
|
||||
@@ -280,29 +279,32 @@ TEST_F(AnalyticsRecorderTest, NewDescribeAttachments) {
|
||||
SharingLog::FileAttachment::DOCUMENT);
|
||||
});
|
||||
|
||||
AttachmentContainer attachments(
|
||||
{TextAttachment(5, service::proto::TextMetadata::TEXT,
|
||||
std::string(kTextBody), kTextBody.size()),
|
||||
TextAttachment(6, service::proto::TextMetadata::PHONE_NUMBER,
|
||||
std::string(kTextBody), kTextBody.size()),
|
||||
TextAttachment(7, service::proto::TextMetadata::URL,
|
||||
std::string(kTextBody), kTextBody.size()),
|
||||
TextAttachment(8, service::proto::TextMetadata::ADDRESS,
|
||||
std::string(kTextBody), kTextBody.size()),
|
||||
TextAttachment(9, service::proto::TextMetadata::UNKNOWN,
|
||||
std::string(kTextBody), kTextBody.size())},
|
||||
{FileAttachment(1, 2, std::string(kFileName), "",
|
||||
service::proto::FileMetadata::IMAGE),
|
||||
FileAttachment(2, 3, std::string(kFileDocumentName),
|
||||
std::string(kFileMimeType),
|
||||
service::proto::FileMetadata::DOCUMENT),
|
||||
FileAttachment(3, 4, std::string(kFileName), "",
|
||||
service::proto::FileMetadata::AUDIO),
|
||||
FileAttachment(4, 5, std::string(kFileName), std::string(kTextMimeType),
|
||||
service::proto::FileMetadata::DOCUMENT)},
|
||||
{});
|
||||
std::unique_ptr<AttachmentContainer> attachments =
|
||||
AttachmentContainer::Builder(
|
||||
{TextAttachment(5, service::proto::TextMetadata::TEXT,
|
||||
std::string(kTextBody), kTextBody.size()),
|
||||
TextAttachment(6, service::proto::TextMetadata::PHONE_NUMBER,
|
||||
std::string(kTextBody), kTextBody.size()),
|
||||
TextAttachment(7, service::proto::TextMetadata::URL,
|
||||
std::string(kTextBody), kTextBody.size()),
|
||||
TextAttachment(8, service::proto::TextMetadata::ADDRESS,
|
||||
std::string(kTextBody), kTextBody.size()),
|
||||
TextAttachment(9, service::proto::TextMetadata::UNKNOWN,
|
||||
std::string(kTextBody), kTextBody.size())},
|
||||
{FileAttachment(1, 2, std::string(kFileName), "",
|
||||
service::proto::FileMetadata::IMAGE),
|
||||
FileAttachment(2, 3, std::string(kFileDocumentName),
|
||||
std::string(kFileMimeType),
|
||||
service::proto::FileMetadata::DOCUMENT),
|
||||
FileAttachment(3, 4, std::string(kFileName), "",
|
||||
service::proto::FileMetadata::AUDIO),
|
||||
FileAttachment(4, 5, std::string(kFileName),
|
||||
std::string(kTextMimeType),
|
||||
service::proto::FileMetadata::DOCUMENT)},
|
||||
{})
|
||||
.Build();
|
||||
|
||||
analytics_recoder().NewDescribeAttachments(attachments);
|
||||
analytics_recoder().NewDescribeAttachments(*attachments);
|
||||
}
|
||||
|
||||
TEST_F(AnalyticsRecorderTest, EmptyDescribeAttachments) {
|
||||
@@ -896,6 +898,4 @@ TEST_F(AnalyticsRecorderTest, GenerateID) {
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace analytics
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
} // namespace nearby::sharing::analytics
|
||||
|
||||
+5
-22
@@ -20,8 +20,7 @@
|
||||
#include "absl/random/random.h"
|
||||
#include "proto/sharing_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
namespace nearby::sharing {
|
||||
namespace {
|
||||
|
||||
using ::location::nearby::proto::sharing::AttachmentSourceType;
|
||||
@@ -33,32 +32,16 @@ int64_t CreateRandomId() {
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(b/258690183): Add unit tests for Attachment with same and different ids
|
||||
Attachment::Attachment(Attachment::Family family, int64_t size,
|
||||
int32_t batch_id, AttachmentSourceType source_type)
|
||||
: id_(CreateRandomId()),
|
||||
family_(family),
|
||||
size_(size),
|
||||
batch_id_(batch_id),
|
||||
source_type_(source_type) {}
|
||||
: Attachment(/*id=*/0, family, size, batch_id, source_type) {}
|
||||
|
||||
Attachment::Attachment(int64_t id, Attachment::Family family, int64_t size,
|
||||
int32_t batch_id, AttachmentSourceType source_type)
|
||||
: id_(id == 0 ? CreateRandomId() : id),
|
||||
family_(family),
|
||||
size_(size),
|
||||
batch_id_(batch_id),
|
||||
source_type_(source_type) {}
|
||||
source_type_(source_type),
|
||||
size_(size) {}
|
||||
|
||||
Attachment::Attachment(const Attachment&) = default;
|
||||
|
||||
Attachment::Attachment(Attachment&&) = default;
|
||||
|
||||
Attachment& Attachment::operator=(const Attachment&) = default;
|
||||
|
||||
Attachment& Attachment::operator=(Attachment&&) = default;
|
||||
|
||||
Attachment::~Attachment() = default;
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
} // namespace nearby::sharing
|
||||
|
||||
+7
-13
@@ -21,8 +21,7 @@
|
||||
#include "proto/sharing_enums.pb.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
namespace nearby::sharing {
|
||||
|
||||
// A single attachment to be sent by / received from a ShareTarget, can be
|
||||
// either a file or text.
|
||||
@@ -41,11 +40,7 @@ class Attachment {
|
||||
Attachment(
|
||||
int64_t id, Family family, int64_t size, int32_t batch_id,
|
||||
location::nearby::proto::sharing::AttachmentSourceType source_type);
|
||||
Attachment(const Attachment&);
|
||||
Attachment(Attachment&&);
|
||||
Attachment& operator=(const Attachment&);
|
||||
Attachment& operator=(Attachment&&);
|
||||
virtual ~Attachment();
|
||||
virtual ~Attachment() = default;
|
||||
|
||||
int64_t id() const { return id_; }
|
||||
Family family() const { return family_; }
|
||||
@@ -60,14 +55,13 @@ class Attachment {
|
||||
virtual ShareType GetShareType() const = 0;
|
||||
|
||||
private:
|
||||
int64_t id_;
|
||||
Family family_;
|
||||
const int64_t id_;
|
||||
const Family family_;
|
||||
const int32_t batch_id_;
|
||||
const location::nearby::proto::sharing::AttachmentSourceType source_type_;
|
||||
int64_t size_;
|
||||
int32_t batch_id_;
|
||||
location::nearby::proto::sharing::AttachmentSourceType source_type_;
|
||||
};
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
} // namespace nearby::sharing
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_SHARING_ATTACHMENT_H_
|
||||
|
||||
@@ -14,23 +14,81 @@
|
||||
|
||||
#include "sharing/attachment_container.h"
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "absl/memory/memory.h"
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
#include "sharing/wifi_credentials_attachment.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
|
||||
AttachmentContainer::Builder&
|
||||
AttachmentContainer::Builder::ReserveAttachmentsCount(
|
||||
int text_attachments_count, int file_attachments_count,
|
||||
int wifi_credentials_attachments_count) {
|
||||
text_attachments_.reserve(text_attachments_count);
|
||||
file_attachments_.reserve(file_attachments_count);
|
||||
wifi_credentials_attachments_.reserve(wifi_credentials_attachments_count);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AttachmentContainer::Builder& AttachmentContainer::Builder::AddTextAttachment(
|
||||
TextAttachment text_attachment) {
|
||||
text_attachments_.push_back(std::move(text_attachment));
|
||||
return *this;
|
||||
}
|
||||
|
||||
AttachmentContainer::Builder& AttachmentContainer::Builder::AddFileAttachment(
|
||||
FileAttachment file_attachment) {
|
||||
file_attachments_.push_back(std::move(file_attachment));
|
||||
return *this;
|
||||
}
|
||||
|
||||
AttachmentContainer::Builder&
|
||||
AttachmentContainer::Builder::AddWifiCredentialsAttachment(
|
||||
WifiCredentialsAttachment wifi_credentials_attachment) {
|
||||
wifi_credentials_attachments_.push_back(
|
||||
std::move(wifi_credentials_attachment));
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::unique_ptr<AttachmentContainer> AttachmentContainer::Builder::Build() {
|
||||
return absl::WrapUnique(new AttachmentContainer(
|
||||
std::move(text_attachments_), std::move(file_attachments_),
|
||||
std::move(wifi_credentials_attachments_)));
|
||||
}
|
||||
|
||||
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)) {}
|
||||
wifi_credentials_attachments_(std::move(wifi_credentials_attachments)) {
|
||||
BuildIndex();
|
||||
}
|
||||
|
||||
AttachmentContainer::AttachmentContainer(AttachmentContainer&& other) {
|
||||
text_attachments_ = std::move(other.text_attachments_);
|
||||
file_attachments_ = std::move(other.file_attachments_);
|
||||
wifi_credentials_attachments_ =
|
||||
std::move(other.wifi_credentials_attachments_);
|
||||
BuildIndex();
|
||||
}
|
||||
|
||||
AttachmentContainer& AttachmentContainer::operator=(
|
||||
AttachmentContainer&& other) {
|
||||
text_attachments_ = std::move(other.text_attachments_);
|
||||
file_attachments_ = std::move(other.file_attachments_);
|
||||
wifi_credentials_attachments_ =
|
||||
std::move(other.wifi_credentials_attachments_);
|
||||
BuildIndex();
|
||||
return *this;
|
||||
}
|
||||
|
||||
int64_t AttachmentContainer::GetTotalAttachmentsSize() const {
|
||||
int64_t size_in_bytes = 0;
|
||||
@@ -77,10 +135,16 @@ void AttachmentContainer::ClearAttachments() {
|
||||
}
|
||||
}
|
||||
|
||||
void AttachmentContainer::Clear() {
|
||||
file_attachments_.clear();
|
||||
text_attachments_.clear();
|
||||
wifi_credentials_attachments_.clear();
|
||||
void AttachmentContainer::BuildIndex() {
|
||||
for (const auto& text : text_attachments_) {
|
||||
attachment_id_map_[text.id()] = &text;
|
||||
}
|
||||
for (const auto& file : file_attachments_) {
|
||||
attachment_id_map_[file.id()] = &file;
|
||||
}
|
||||
for (const auto& wifi_credentials : wifi_credentials_attachments_) {
|
||||
attachment_id_map_[wifi_credentials.id()] = &wifi_credentials;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
#define THIRD_PARTY_NEARBY_SHARING_ATTACHMENT_CONTAINER_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "sharing/attachment.h"
|
||||
#include "sharing/file_attachment.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
#include "sharing/wifi_credentials_attachment.h"
|
||||
@@ -28,15 +31,40 @@ namespace nearby::sharing {
|
||||
// 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);
|
||||
class Builder {
|
||||
public:
|
||||
Builder() = default;
|
||||
Builder(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)) {}
|
||||
Builder& ReserveAttachmentsCount(int text_attachments_count,
|
||||
int file_attachments_count,
|
||||
int wifi_credentials_attachments_count);
|
||||
Builder& AddTextAttachment(TextAttachment text_attachment);
|
||||
Builder& AddFileAttachment(FileAttachment file_attachment);
|
||||
Builder& AddWifiCredentialsAttachment(
|
||||
WifiCredentialsAttachment wifi_credentials_attachment);
|
||||
|
||||
bool Empty() const {
|
||||
return text_attachments_.empty() && file_attachments_.empty() &&
|
||||
wifi_credentials_attachments_.empty();
|
||||
}
|
||||
|
||||
std::unique_ptr<AttachmentContainer> Build();
|
||||
|
||||
private:
|
||||
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(AttachmentContainer&&);
|
||||
AttachmentContainer& operator=(AttachmentContainer&&);
|
||||
~AttachmentContainer() = default;
|
||||
|
||||
const std::vector<TextAttachment>& GetTextAttachments() const {
|
||||
@@ -50,18 +78,6 @@ class AttachmentContainer {
|
||||
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];
|
||||
}
|
||||
@@ -74,6 +90,14 @@ class AttachmentContainer {
|
||||
return wifi_credentials_attachments_[index];
|
||||
}
|
||||
|
||||
const Attachment* GetAttachment(int64_t id) const {
|
||||
const auto it = attachment_id_map_.find(id);
|
||||
if (it == attachment_id_map_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// Returns the total number of attachments of all types.
|
||||
int GetAttachmentCount() const {
|
||||
return text_attachments_.size() + file_attachments_.size() +
|
||||
@@ -96,13 +120,18 @@ class AttachmentContainer {
|
||||
// place.
|
||||
void ClearAttachments();
|
||||
|
||||
// Delete all attachments.
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
AttachmentContainer(
|
||||
std::vector<TextAttachment> text_attachments,
|
||||
std::vector<FileAttachment> file_attachments,
|
||||
std::vector<WifiCredentialsAttachment> wifi_credentials_attachments);
|
||||
// Build id to attachment index.
|
||||
void BuildIndex();
|
||||
|
||||
std::vector<TextAttachment> text_attachments_;
|
||||
std::vector<FileAttachment> file_attachments_;
|
||||
std::vector<WifiCredentialsAttachment> wifi_credentials_attachments_;
|
||||
absl::flat_hash_map<int64_t, const Attachment*> attachment_id_map_;
|
||||
};
|
||||
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "sharing/attachment_container.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
@@ -72,132 +73,142 @@ class AttachmentContainerTest : public ::testing::Test {
|
||||
};
|
||||
|
||||
TEST_F(AttachmentContainerTest, Constructor) {
|
||||
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
std::vector<WifiCredentialsAttachment>{wifi1_});
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder()
|
||||
.AddTextAttachment(text1_)
|
||||
.AddTextAttachment(text2_)
|
||||
.AddFileAttachment(file1_)
|
||||
.AddWifiCredentialsAttachment(wifi1_)
|
||||
.Build();
|
||||
|
||||
EXPECT_THAT(container.GetTextAttachments(),
|
||||
EXPECT_THAT(container->GetTextAttachments(),
|
||||
UnorderedElementsAre(text1_, text2_));
|
||||
EXPECT_THAT(container.GetFileAttachments(), UnorderedElementsAre(file1_));
|
||||
EXPECT_THAT(container.GetWifiCredentialsAttachments(),
|
||||
EXPECT_THAT(container->GetFileAttachments(), UnorderedElementsAre(file1_));
|
||||
EXPECT_THAT(container->GetWifiCredentialsAttachments(),
|
||||
UnorderedElementsAre(wifi1_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, AddTextAttachment) {
|
||||
AttachmentContainer container;
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder()
|
||||
.AddTextAttachment(text1_)
|
||||
.AddTextAttachment(text2_)
|
||||
.Build();
|
||||
|
||||
container.AddTextAttachment(text1_);
|
||||
container.AddTextAttachment(text2_);
|
||||
|
||||
EXPECT_THAT(container.GetTextAttachments(),
|
||||
EXPECT_THAT(container->GetTextAttachments(),
|
||||
UnorderedElementsAre(text1_, text2_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, AddFileAttachment) {
|
||||
AttachmentContainer container;
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder().AddFileAttachment(file1_).Build();
|
||||
|
||||
container.AddFileAttachment(file1_);
|
||||
|
||||
EXPECT_THAT(container.GetFileAttachments(), UnorderedElementsAre(file1_));
|
||||
EXPECT_THAT(container->GetFileAttachments(), UnorderedElementsAre(file1_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, AddWifiCredentialsAttachment) {
|
||||
AttachmentContainer container;
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder()
|
||||
.AddWifiCredentialsAttachment(wifi1_)
|
||||
.Build();
|
||||
|
||||
container.AddWifiCredentialsAttachment(wifi1_);
|
||||
|
||||
EXPECT_THAT(container.GetWifiCredentialsAttachments(),
|
||||
EXPECT_THAT(container->GetWifiCredentialsAttachments(),
|
||||
UnorderedElementsAre(wifi1_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, GetMutableTextAttachment) {
|
||||
AttachmentContainer container;
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder()
|
||||
.AddTextAttachment(text1_)
|
||||
.AddTextAttachment(text2_)
|
||||
.Build();
|
||||
|
||||
container.AddTextAttachment(text1_);
|
||||
container.AddTextAttachment(text2_);
|
||||
|
||||
EXPECT_THAT(container.GetMutableTextAttachment(0), Eq(text1_));
|
||||
EXPECT_THAT(container.GetMutableTextAttachment(1), Eq(text2_));
|
||||
EXPECT_THAT(container->GetMutableTextAttachment(0), Eq(text1_));
|
||||
EXPECT_THAT(container->GetMutableTextAttachment(1), Eq(text2_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, GetMutableFileAttachment) {
|
||||
AttachmentContainer container;
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder().AddFileAttachment(file1_).Build();
|
||||
|
||||
container.AddFileAttachment(file1_);
|
||||
|
||||
EXPECT_THAT(container.GetMutableFileAttachment(0), Eq(file1_));
|
||||
EXPECT_THAT(container->GetMutableFileAttachment(0), Eq(file1_));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, GetMutableWifiCredentialsAttachment) {
|
||||
AttachmentContainer container;
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder()
|
||||
.AddWifiCredentialsAttachment(wifi1_)
|
||||
.Build();
|
||||
|
||||
container.AddWifiCredentialsAttachment(wifi1_);
|
||||
|
||||
EXPECT_THAT(container.GetMutableWifiCredentialsAttachment(0), Eq(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_});
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder()
|
||||
.AddTextAttachment(text1_)
|
||||
.AddTextAttachment(text2_)
|
||||
.AddFileAttachment(file1_)
|
||||
.AddWifiCredentialsAttachment(wifi1_)
|
||||
.Build();
|
||||
|
||||
EXPECT_THAT(container.GetAttachmentCount(), Eq(4));
|
||||
EXPECT_THAT(container->GetAttachmentCount(), Eq(4));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, GetTotalAttachmentsSize) {
|
||||
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
std::vector<WifiCredentialsAttachment>{});
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder()
|
||||
.AddTextAttachment(text1_)
|
||||
.AddTextAttachment(text2_)
|
||||
.AddFileAttachment(file1_)
|
||||
.Build();
|
||||
|
||||
EXPECT_THAT(container.GetTotalAttachmentsSize(), Eq(18 + 20 + 100000));
|
||||
EXPECT_THAT(container->GetTotalAttachmentsSize(), Eq(18 + 20 + 100000));
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, HasAttachments) {
|
||||
AttachmentContainer container;
|
||||
AttachmentContainer::Builder builder = AttachmentContainer::Builder();
|
||||
|
||||
EXPECT_THAT(container.HasAttachments(), IsFalse());
|
||||
EXPECT_THAT(builder.Empty(), IsTrue());
|
||||
|
||||
container.AddWifiCredentialsAttachment(wifi1_);
|
||||
builder.AddWifiCredentialsAttachment(wifi1_);
|
||||
|
||||
EXPECT_THAT(container.HasAttachments(), IsTrue());
|
||||
EXPECT_THAT(builder.Empty(), IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(AttachmentContainerTest, ClearAttachments) {
|
||||
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
std::vector<WifiCredentialsAttachment>{wifi1_});
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder()
|
||||
.AddTextAttachment(text1_)
|
||||
.AddTextAttachment(text2_)
|
||||
.AddFileAttachment(file1_)
|
||||
.AddWifiCredentialsAttachment(wifi1_)
|
||||
.Build();
|
||||
|
||||
container.ClearAttachments();
|
||||
container->ClearAttachments();
|
||||
|
||||
ASSERT_THAT(container.GetTextAttachments(), SizeIs(2));
|
||||
EXPECT_THAT(container.GetTextAttachments()[0].text_body(), IsEmpty());
|
||||
EXPECT_THAT(container.GetTextAttachments()[1].text_body(), IsEmpty());
|
||||
ASSERT_THAT(container.GetFileAttachments(), SizeIs(1));
|
||||
EXPECT_THAT(container.GetFileAttachments()[0].file_path(), Eq(std::nullopt));
|
||||
ASSERT_THAT(container.GetWifiCredentialsAttachments(), SizeIs(1));
|
||||
EXPECT_THAT(container.GetWifiCredentialsAttachments()[0].password(),
|
||||
ASSERT_THAT(container->GetTextAttachments(), SizeIs(2));
|
||||
EXPECT_THAT(container->GetTextAttachments()[0].text_body(), IsEmpty());
|
||||
EXPECT_THAT(container->GetTextAttachments()[1].text_body(), IsEmpty());
|
||||
ASSERT_THAT(container->GetFileAttachments(), SizeIs(1));
|
||||
EXPECT_THAT(container->GetFileAttachments()[0].file_path(), Eq(std::nullopt));
|
||||
ASSERT_THAT(container->GetWifiCredentialsAttachments(), SizeIs(1));
|
||||
EXPECT_THAT(container->GetWifiCredentialsAttachments()[0].password(),
|
||||
IsEmpty());
|
||||
EXPECT_THAT(container.GetWifiCredentialsAttachments()[0].is_hidden(),
|
||||
EXPECT_THAT(container->GetWifiCredentialsAttachments()[0].is_hidden(),
|
||||
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, GetStorageSize) {
|
||||
AttachmentContainer container(std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
std::vector<WifiCredentialsAttachment>{wifi1_});
|
||||
std::unique_ptr<AttachmentContainer> container =
|
||||
AttachmentContainer::Builder()
|
||||
.AddTextAttachment(text1_)
|
||||
.AddTextAttachment(text2_)
|
||||
.AddFileAttachment(file1_)
|
||||
.AddWifiCredentialsAttachment(wifi1_)
|
||||
.Build();
|
||||
|
||||
int64_t storage_size = container.GetStorageSize();
|
||||
int64_t storage_size = container->GetStorageSize();
|
||||
|
||||
EXPECT_THAT(storage_size, Eq(file1_.size()));
|
||||
}
|
||||
|
||||
@@ -124,13 +124,12 @@ cc_test(
|
||||
":test_support",
|
||||
"//internal/platform:mac_address",
|
||||
"//internal/platform/implementation:account_manager",
|
||||
"//internal/platform/implementation:platform_impl", # fixdeps: keep
|
||||
"//internal/platform/implementation:platform_impl",
|
||||
"//internal/test",
|
||||
"//proto/identity/v1:resources_cc_proto",
|
||||
"//proto/identity/v1:rpcs_cc_proto",
|
||||
"//sharing/common",
|
||||
"//sharing/common:enum",
|
||||
"//sharing/contacts:test_support",
|
||||
"//sharing/internal/api:mock_sharing_platform",
|
||||
"//sharing/internal/api:platform",
|
||||
"//sharing/internal/public:pref_names",
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
#include "sharing/certificates/nearby_share_encrypted_metadata_key.h"
|
||||
#include "sharing/certificates/nearby_share_private_certificate.h"
|
||||
#include "sharing/certificates/test_util.h"
|
||||
#include "sharing/contacts/fake_nearby_share_contact_manager.h"
|
||||
#include "sharing/internal/api/fake_nearby_share_client.h"
|
||||
#include "sharing/internal/api/mock_sharing_platform.h"
|
||||
#include "sharing/internal/public/pref_names.h"
|
||||
@@ -114,7 +113,6 @@ class NearbyShareCertificateManagerImplTest
|
||||
local_device_data_manager_ =
|
||||
std::make_unique<FakeNearbyShareLocalDeviceDataManager>(
|
||||
kDefaultDeviceName);
|
||||
contact_manager_ = std::make_unique<FakeNearbyShareContactManager>();
|
||||
|
||||
AccountManager::Account account{
|
||||
.display_name = GetNearbyShareTestMetadata().full_name(),
|
||||
@@ -501,7 +499,6 @@ class NearbyShareCertificateManagerImplTest
|
||||
FakeNearbyShareCertificateStorage::Factory cert_store_factory_;
|
||||
std::unique_ptr<FakeNearbyShareLocalDeviceDataManager>
|
||||
local_device_data_manager_;
|
||||
std::unique_ptr<FakeNearbyShareContactManager> contact_manager_;
|
||||
std::unique_ptr<NearbyShareCertificateManager> cert_manager_;
|
||||
};
|
||||
|
||||
|
||||
+15
-35
@@ -17,60 +17,49 @@ load("@rules_cc//cc:cc_test.bzl", "cc_test")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
cc_library(
|
||||
name = "contacts_interface",
|
||||
hdrs = [
|
||||
"nearby_share_contact_manager.h",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//sharing/proto:share_cc_proto",
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "contacts",
|
||||
srcs = [
|
||||
"nearby_share_contact_manager.cc",
|
||||
"nearby_share_contact_manager_impl.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"nearby_share_contact_manager.h",
|
||||
"nearby_share_contact_manager_impl.h",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//internal/base",
|
||||
"//internal/crypto_cros",
|
||||
"//internal/flags:nearby_flags",
|
||||
":contacts_interface",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation:account_manager",
|
||||
"//sharing/common",
|
||||
"//sharing/flags/generated:generated_flags",
|
||||
"//sharing/internal/api:platform",
|
||||
"//sharing/internal/base",
|
||||
"//sharing/internal/public:logging",
|
||||
"//sharing/internal/public:types",
|
||||
"//sharing/local_device_data",
|
||||
"//sharing/proto:share_cc_proto",
|
||||
"//sharing/scheduling",
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/functional:bind_front",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "test_support",
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"fake_nearby_share_contact_manager.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"fake_nearby_share_contact_manager.h",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":contacts",
|
||||
"//internal/platform/implementation:account_manager",
|
||||
"//internal/platform/implementation:types",
|
||||
"//sharing/internal/api:platform",
|
||||
"//sharing/internal/public:types",
|
||||
"//sharing/local_device_data",
|
||||
],
|
||||
deps = [":contacts_interface"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
@@ -83,20 +72,11 @@ cc_test(
|
||||
"//internal/platform/implementation:account_manager",
|
||||
"//internal/platform/implementation:platform_impl",
|
||||
"//internal/test",
|
||||
"//sharing/common",
|
||||
"//sharing/internal/api:mock_sharing_platform",
|
||||
"//sharing/internal/api:platform",
|
||||
"//sharing/internal/test:nearby_test",
|
||||
"//sharing/local_device_data:test_support",
|
||||
"//sharing/proto:share_cc_proto",
|
||||
"//sharing/scheduling",
|
||||
"//sharing/scheduling:test_support",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
// Copyright 2021-2023 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/contacts/fake_nearby_share_contact_manager.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "internal/platform/implementation/account_manager.h"
|
||||
#include "sharing/contacts/nearby_share_contact_manager.h"
|
||||
#include "sharing/internal/api/sharing_rpc_client.h"
|
||||
#include "sharing/internal/public/context.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
FakeNearbyShareContactManager::Factory::Factory() = default;
|
||||
|
||||
FakeNearbyShareContactManager::Factory::~Factory() = default;
|
||||
|
||||
std::unique_ptr<NearbyShareContactManager>
|
||||
FakeNearbyShareContactManager::Factory::CreateInstance(
|
||||
Context* context, AccountManager& account_manager,
|
||||
nearby::sharing::api::SharingRpcClientFactory* nearby_client_factory) {
|
||||
latest_nearby_client_factory_ = nearby_client_factory;
|
||||
latest_account_manager_ = &account_manager;
|
||||
|
||||
auto instance = std::make_unique<FakeNearbyShareContactManager>();
|
||||
instances_.push_back(instance.get());
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
FakeNearbyShareContactManager::FakeNearbyShareContactManager() = default;
|
||||
|
||||
FakeNearbyShareContactManager::~FakeNearbyShareContactManager() = default;
|
||||
|
||||
void FakeNearbyShareContactManager::GetContacts(ContactsCallback callback) {}
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
@@ -15,68 +15,19 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_SHARING_CONTACTS_FAKE_NEARBY_SHARE_CONTACT_MANAGER_H_
|
||||
#define THIRD_PARTY_NEARBY_SHARING_CONTACTS_FAKE_NEARBY_SHARE_CONTACT_MANAGER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "internal/platform/implementation/account_manager.h"
|
||||
#include "sharing/contacts/nearby_share_contact_manager.h"
|
||||
#include "sharing/contacts/nearby_share_contact_manager_impl.h"
|
||||
#include "sharing/internal/api/sharing_rpc_client.h"
|
||||
#include "sharing/internal/public/context.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
// A fake implementation of NearbyShareContactManager, along with a fake
|
||||
// factory, to be used in tests. Stores parameters input into
|
||||
// NearbyShareContactManager method calls. Use the notification methods from the
|
||||
// base class--NotifyContactsDownloaded() and NotifyContactsUploaded()--to alert
|
||||
// observers of changes; these methods are made public in this fake class.
|
||||
// A fake implementation of NearbyShareContactManager.
|
||||
class FakeNearbyShareContactManager : public NearbyShareContactManager {
|
||||
public:
|
||||
// Factory that creates FakeNearbyShareContactManager instances. Use in
|
||||
// NearbyShareContactManagerImpl::Factor::SetFactoryForTesting() in unit
|
||||
// tests.
|
||||
class Factory : public NearbyShareContactManagerImpl::Factory {
|
||||
public:
|
||||
Factory();
|
||||
~Factory() override;
|
||||
|
||||
// Returns all FakeNearbyShareContactManager instances created by
|
||||
// CreateInstance().
|
||||
std::vector<FakeNearbyShareContactManager*>& instances() {
|
||||
return instances_;
|
||||
}
|
||||
|
||||
nearby::sharing::api::SharingRpcClientFactory* latest_http_client_factory()
|
||||
const {
|
||||
return latest_nearby_client_factory_;
|
||||
}
|
||||
|
||||
AccountManager* latest_account_manager() const {
|
||||
return latest_account_manager_;
|
||||
}
|
||||
|
||||
private:
|
||||
// NearbyShareContactManagerImpl::Factory:
|
||||
std::unique_ptr<NearbyShareContactManager> CreateInstance(
|
||||
Context* context, AccountManager& account_manager,
|
||||
nearby::sharing::api::SharingRpcClientFactory* nearby_client_factory)
|
||||
override;
|
||||
|
||||
std::vector<FakeNearbyShareContactManager*> instances_;
|
||||
nearby::sharing::api::SharingRpcClientFactory*
|
||||
latest_nearby_client_factory_ = nullptr;
|
||||
AccountManager* latest_account_manager_ = nullptr;
|
||||
};
|
||||
|
||||
FakeNearbyShareContactManager();
|
||||
~FakeNearbyShareContactManager() override;
|
||||
FakeNearbyShareContactManager() = default;
|
||||
~FakeNearbyShareContactManager() override = default;
|
||||
|
||||
private:
|
||||
void GetContacts(ContactsCallback callback) override;
|
||||
void GetContacts(ContactsCallback callback) override {};
|
||||
};
|
||||
|
||||
} // namespace sharing
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright 2021-2023 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/contacts/nearby_share_contact_manager.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sharing/proto/rpc_resources.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
NearbyShareContactManager::NearbyShareContactManager() = default;
|
||||
|
||||
NearbyShareContactManager::~NearbyShareContactManager() = default;
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
@@ -26,27 +26,15 @@
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
// The Nearby Share contacts manager interfaces with the Nearby server in the
|
||||
// following ways:
|
||||
// 1) The user's contacts are downloaded from People API, using the Nearby
|
||||
// server as a proxy.
|
||||
// 2) All the user's contacts are uploaded to Nearby server, along with an
|
||||
// indication of what contacts are allowed for selected-contacts visibility
|
||||
// mode. The Nearby server will distribute all-contacts visibility
|
||||
// certificates accordingly. For privacy reasons, the Nearby server needs to
|
||||
// explicitly receive the list of contacts from the device instead of pulling
|
||||
// them directly from People API.
|
||||
//
|
||||
// All contact data and update notifications are conveyed via observer methods;
|
||||
// the manager does not return data directly from function calls.
|
||||
// The Nearby Share contacts manager retrieves the user's contact list from the
|
||||
// server.
|
||||
class NearbyShareContactManager {
|
||||
public:
|
||||
using ContactsCallback = absl::AnyInvocable<
|
||||
void(absl::StatusOr<std::vector<nearby::sharing::proto::ContactRecord>>,
|
||||
uint32_t num_unreachable_contacts_filtered_out) &&>;
|
||||
|
||||
NearbyShareContactManager();
|
||||
virtual ~NearbyShareContactManager();
|
||||
virtual ~NearbyShareContactManager() = default;
|
||||
|
||||
// Retrieves the user's contact list from the server.
|
||||
virtual void GetContacts(ContactsCallback callback) = 0;
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "internal/platform/implementation/account_manager.h"
|
||||
@@ -42,53 +41,32 @@ using ::nearby::sharing::proto::ContactRecord;
|
||||
using ::nearby::sharing::proto::ListContactPeopleRequest;
|
||||
using ::nearby::sharing::proto::ListContactPeopleResponse;
|
||||
|
||||
void FilterOutUnreachableContacts(std::vector<ContactRecord>& contacts) {
|
||||
contacts.erase(
|
||||
std::remove_if(contacts.begin(), contacts.end(),
|
||||
[](const nearby::sharing::proto::ContactRecord& contact) {
|
||||
return !contact.is_reachable();
|
||||
}),
|
||||
contacts.end());
|
||||
}
|
||||
// Class for maintaining a single instance of contacts download request. It
|
||||
// is responsible for downloading all available pages and making the results
|
||||
// or error available.
|
||||
class ContactDownloadContext {
|
||||
public:
|
||||
ContactDownloadContext(
|
||||
nearby::sharing::api::SharingRpcClient* nearby_share_client,
|
||||
NearbyShareContactManager::ContactsCallback download_callback)
|
||||
: nearby_share_client_(nearby_share_client),
|
||||
download_callback_(std::move(download_callback)) {}
|
||||
|
||||
} // namespace
|
||||
// Fetches the next page of contacts.
|
||||
// If |next_page_token_| is empty, it fetches the first page.
|
||||
// On successful download, if page token in the response is empty, the
|
||||
// |download_callback_| is invoked with all downloaded contacts.
|
||||
void FetchNextPage();
|
||||
|
||||
// static
|
||||
NearbyShareContactManagerImpl::Factory*
|
||||
NearbyShareContactManagerImpl::Factory::test_factory_ = nullptr;
|
||||
private:
|
||||
nearby::sharing::api::SharingRpcClient* const nearby_share_client_;
|
||||
std::optional<std::string> next_page_token_;
|
||||
int page_number_ = 1;
|
||||
std::vector<ContactRecord> contacts_;
|
||||
NearbyShareContactManager::ContactsCallback download_callback_;
|
||||
};
|
||||
|
||||
// static
|
||||
std::unique_ptr<NearbyShareContactManager>
|
||||
NearbyShareContactManagerImpl::Factory::Create(
|
||||
Context* context, AccountManager& account_manager,
|
||||
nearby::sharing::api::SharingRpcClientFactory* nearby_client_factory) {
|
||||
if (test_factory_) {
|
||||
return test_factory_->CreateInstance(context, account_manager,
|
||||
nearby_client_factory);
|
||||
}
|
||||
|
||||
return absl::WrapUnique(new NearbyShareContactManagerImpl(
|
||||
context, account_manager, nearby_client_factory));
|
||||
}
|
||||
|
||||
// static
|
||||
void NearbyShareContactManagerImpl::Factory::SetFactoryForTesting(
|
||||
Factory* test_factory) {
|
||||
test_factory_ = test_factory;
|
||||
}
|
||||
|
||||
NearbyShareContactManagerImpl::Factory::~Factory() = default;
|
||||
|
||||
NearbyShareContactManagerImpl::NearbyShareContactManagerImpl(
|
||||
Context* context, AccountManager& account_manager,
|
||||
nearby::sharing::api::SharingRpcClientFactory* nearby_client_factory)
|
||||
: account_manager_(account_manager),
|
||||
nearby_share_client_(nearby_client_factory->CreateInstance()),
|
||||
executor_(context->CreateSequencedTaskRunner()) {}
|
||||
|
||||
NearbyShareContactManagerImpl::~NearbyShareContactManagerImpl() = default;
|
||||
|
||||
void NearbyShareContactManagerImpl::ContactDownloadContext::FetchNextPage() {
|
||||
void ContactDownloadContext::FetchNextPage() {
|
||||
LOG(INFO) << "Downloading contacts page=" << page_number_++;
|
||||
ListContactPeopleRequest request;
|
||||
if (next_page_token_.has_value()) {
|
||||
@@ -112,7 +90,12 @@ void NearbyShareContactManagerImpl::ContactDownloadContext::FetchNextPage() {
|
||||
// We should filter here because we only care about contacts that we
|
||||
// can share with.
|
||||
uint32_t contacts_size = contacts_.size();
|
||||
FilterOutUnreachableContacts(contacts_);
|
||||
// Filter out unreachable contacts.
|
||||
contacts_.erase(std::remove_if(contacts_.begin(), contacts_.end(),
|
||||
[](const ContactRecord& contact) {
|
||||
return !contact.is_reachable();
|
||||
}),
|
||||
contacts_.end());
|
||||
uint32_t num_unreachable_contacts_filtered_out =
|
||||
contacts_size - contacts_.size();
|
||||
std::move(download_callback_)(std::move(contacts_),
|
||||
@@ -125,6 +108,15 @@ void NearbyShareContactManagerImpl::ContactDownloadContext::FetchNextPage() {
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NearbyShareContactManagerImpl::NearbyShareContactManagerImpl(
|
||||
Context* context, AccountManager& account_manager,
|
||||
nearby::sharing::api::SharingRpcClientFactory* nearby_client_factory)
|
||||
: account_manager_(account_manager),
|
||||
nearby_share_client_(nearby_client_factory->CreateInstance()),
|
||||
executor_(context->CreateSequencedTaskRunner()) {}
|
||||
|
||||
void NearbyShareContactManagerImpl::GetContacts(ContactsCallback callback) {
|
||||
executor_->PostTask([this, callback = std::move(callback)]() mutable {
|
||||
LOG(INFO) << "Start downloading contacts";
|
||||
|
||||
@@ -15,94 +15,26 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_IMPL_H_
|
||||
#define THIRD_PARTY_NEARBY_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_IMPL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "internal/platform/implementation/account_manager.h"
|
||||
#include "internal/platform/task_runner.h"
|
||||
#include "sharing/contacts/nearby_share_contact_manager.h"
|
||||
#include "sharing/internal/api/sharing_rpc_client.h"
|
||||
#include "sharing/internal/public/context.h"
|
||||
#include "sharing/proto/rpc_resources.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
// Implementation of NearbyShareContactManager that persists the set of allowed
|
||||
// contact IDs--for selected-contacts visibility mode--in prefs. Other
|
||||
// contact data is downloaded from People API, via the NearbyShare server, as
|
||||
// needed.
|
||||
//
|
||||
// The Nearby Share server must be explicitly informed of all contacts this
|
||||
// device is aware of--needed for all-contacts visibility mode--as well as what
|
||||
// contacts are allowed for selected-contacts visibility mode. These uploaded
|
||||
// contact lists are used by the server to distribute the device's public
|
||||
// certificates accordingly. This implementation persists a hash of the last
|
||||
// uploaded contact data, and after every contacts download, a subsequent upload
|
||||
// request is made if we detect that the contact list or allowlist has changed
|
||||
// since the last successful upload. We also schedule periodic contact uploads
|
||||
// just in case the server removed the record.
|
||||
//
|
||||
// In addition to supporting on-demand contact downloads, this implementation
|
||||
// periodically checks in with the Nearby Share server to see if the user's
|
||||
// contact list has changed since the last upload.
|
||||
class NearbyShareContactManagerImpl : public NearbyShareContactManager {
|
||||
public:
|
||||
class Factory {
|
||||
public:
|
||||
static std::unique_ptr<NearbyShareContactManager> Create(
|
||||
Context* context, AccountManager& account_manager,
|
||||
nearby::sharing::api::SharingRpcClientFactory* nearby_client_factory);
|
||||
static void SetFactoryForTesting(Factory* test_factory);
|
||||
|
||||
protected:
|
||||
virtual ~Factory();
|
||||
virtual std::unique_ptr<NearbyShareContactManager> CreateInstance(
|
||||
Context* context, AccountManager& account_manager,
|
||||
nearby::sharing::api::SharingRpcClientFactory*
|
||||
nearby_client_factory) = 0;
|
||||
|
||||
private:
|
||||
static Factory* test_factory_;
|
||||
};
|
||||
|
||||
~NearbyShareContactManagerImpl() override;
|
||||
|
||||
private:
|
||||
// Class for maintaining a single instance of contacts download request. It
|
||||
// is responsible for downloading all available pages and making the results
|
||||
// or error available.
|
||||
class ContactDownloadContext {
|
||||
public:
|
||||
ContactDownloadContext(
|
||||
nearby::sharing::api::SharingRpcClient* nearby_share_client,
|
||||
ContactsCallback download_callback)
|
||||
: nearby_share_client_(nearby_share_client),
|
||||
download_callback_(std::move(download_callback)) {}
|
||||
|
||||
// Fetches the next page of contacts.
|
||||
// If |next_page_token_| is empty, it fetches the first page.
|
||||
// On successful download, if page token in the response is empty, the
|
||||
// |download_callback_| is invoked with all downloaded contacts.
|
||||
void FetchNextPage();
|
||||
|
||||
private:
|
||||
nearby::sharing::api::SharingRpcClient* const nearby_share_client_;
|
||||
std::optional<std::string> next_page_token_;
|
||||
int page_number_ = 1;
|
||||
std::vector<nearby::sharing::proto::ContactRecord> contacts_;
|
||||
ContactsCallback download_callback_;
|
||||
};
|
||||
|
||||
NearbyShareContactManagerImpl(
|
||||
Context* context, AccountManager& account_manager,
|
||||
nearby::sharing::api::SharingRpcClientFactory* nearby_client_factory);
|
||||
|
||||
~NearbyShareContactManagerImpl() override = default;
|
||||
|
||||
private:
|
||||
// NearbyShareContactsManager:
|
||||
void GetContacts(ContactsCallback callback) override;
|
||||
|
||||
|
||||
@@ -26,14 +26,11 @@
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/implementation/account_manager.h"
|
||||
#include "internal/test/fake_account_manager.h"
|
||||
#include "sharing/contacts/nearby_share_contact_manager.h"
|
||||
#include "sharing/internal/api/fake_nearby_share_client.h"
|
||||
#include "sharing/internal/test/fake_context.h"
|
||||
#include "sharing/local_device_data/fake_nearby_share_local_device_data_manager.h"
|
||||
#include "sharing/proto/contact_rpc.pb.h"
|
||||
#include "sharing/proto/rpc_resources.pb.h"
|
||||
#include "sharing/scheduling/fake_nearby_share_scheduler_factory.h"
|
||||
#include "sharing/scheduling/nearby_share_scheduler_factory.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
namespace {
|
||||
@@ -61,19 +58,17 @@ class NearbyShareContactManagerImplTest
|
||||
~NearbyShareContactManagerImplTest() override = default;
|
||||
|
||||
void SetUp() override {
|
||||
NearbyShareSchedulerFactory::SetFactoryForTesting(&scheduler_factory_);
|
||||
AccountManager::Account account;
|
||||
account.id = kTestAccountId;
|
||||
account.email = kTestProfileUserName;
|
||||
fake_account_manager_.SetAccount(account);
|
||||
|
||||
manager_ = NearbyShareContactManagerImpl::Factory::Create(
|
||||
manager_ = std::make_unique<NearbyShareContactManagerImpl>(
|
||||
&fake_context_, fake_account_manager_, &nearby_client_factory_);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
manager_.reset();
|
||||
NearbyShareSchedulerFactory::SetFactoryForTesting(nullptr);
|
||||
}
|
||||
|
||||
void Sync() {
|
||||
@@ -101,8 +96,7 @@ class NearbyShareContactManagerImplTest
|
||||
FakeNearbyShareClientFactory nearby_client_factory_;
|
||||
FakeNearbyShareLocalDeviceDataManager local_device_data_manager_;
|
||||
std::unique_ptr<FakeAccountManager> account_manager_;
|
||||
FakeNearbyShareSchedulerFactory scheduler_factory_;
|
||||
std::unique_ptr<NearbyShareContactManager> manager_;
|
||||
std::unique_ptr<NearbyShareContactManagerImpl> manager_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
#include "sharing/internal/base/mime.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
namespace nearby::sharing {
|
||||
namespace {
|
||||
|
||||
using ::location::nearby::proto::sharing::AttachmentSourceType;
|
||||
@@ -61,12 +60,11 @@ FileAttachment::FileAttachment(FilePath file_path, absl::string_view mime_type,
|
||||
std::string parent_folder, int32_t batch_id,
|
||||
AttachmentSourceType source_type)
|
||||
: Attachment(Attachment::Family::kFile, /*size=*/0, batch_id, source_type),
|
||||
file_name_(file_path.GetFileName().ToString()),
|
||||
mime_type_(mime_type.empty() ? MimeTypeFromPath(file_path) : mime_type),
|
||||
type_(FileAttachmentTypeFromMimeType(mime_type_)),
|
||||
parent_folder_(std::move(parent_folder)) {
|
||||
file_name_ = file_path.GetFileName().ToString();
|
||||
file_path_ = std::move(file_path);
|
||||
}
|
||||
parent_folder_(std::move(parent_folder)),
|
||||
file_path_(std::move(file_path)) {}
|
||||
|
||||
FileAttachment::FileAttachment(int64_t id, int64_t size, std::string file_name,
|
||||
std::string mime_type, Type type,
|
||||
@@ -108,5 +106,4 @@ ShareType FileAttachment::GetShareType() const {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -39,8 +39,7 @@
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
namespace nearby::sharing {
|
||||
|
||||
// A single attachment to be sent by / received from a |ShareTarget|, can be
|
||||
// either a file or text.
|
||||
@@ -58,10 +57,6 @@ class FileAttachment : public Attachment {
|
||||
Type type, std::string parent_folder = "", int32_t batch_id = 0,
|
||||
location::nearby::proto::sharing::AttachmentSourceType source_type =
|
||||
location::nearby::proto::sharing::ATTACHMENT_SOURCE_UNKNOWN);
|
||||
FileAttachment(const FileAttachment&) = default;
|
||||
FileAttachment(FileAttachment&&) = default;
|
||||
FileAttachment& operator=(const FileAttachment&) = default;
|
||||
FileAttachment& operator=(FileAttachment&&) = default;
|
||||
~FileAttachment() override = default;
|
||||
|
||||
absl::string_view file_name() const { return file_name_; }
|
||||
@@ -82,14 +77,13 @@ class FileAttachment : public Attachment {
|
||||
|
||||
private:
|
||||
// File name should be in UTF8 format.
|
||||
std::string file_name_;
|
||||
std::string mime_type_;
|
||||
Type type_;
|
||||
const std::string file_name_;
|
||||
const std::string mime_type_;
|
||||
const Type type_;
|
||||
const std::string parent_folder_;
|
||||
std::optional<FilePath> file_path_;
|
||||
std::string parent_folder_;
|
||||
};
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
} // namespace nearby::sharing
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_SHARING_FILE_ATTACHMENT_H_
|
||||
|
||||
@@ -53,32 +53,20 @@ constexpr auto kEnableSelfShareUi =
|
||||
// Enable/disable sending desktop events
|
||||
constexpr auto kEnableSendingDesktopEvents =
|
||||
flags::Flag<bool>(kConfigPackage, "45459748", false);
|
||||
// Disable/enable the WebRTC medium in Nearby Sharing SDK.
|
||||
constexpr auto kEnableWebrtcMedium =
|
||||
flags::Flag<bool>(kConfigPackage, "45411620", false);
|
||||
// Set the logging level in Nearby Sharing SDK. The default logging level is
|
||||
// WARNING. The mapping of logging level to number: INFO: 0, WARNING: 1, ERROR:
|
||||
// 2, FATAL: 3, negative values are -(verbosity level).
|
||||
constexpr auto kLoggingLevel =
|
||||
flags::Flag<int64_t>(kConfigPackage, "45401358", 1);
|
||||
// When true, the sender will not require confirming the ukey2 token.
|
||||
constexpr auto kSenderSkipsConfirmation =
|
||||
flags::Flag<bool>(kConfigPackage, "45411353", true);
|
||||
// Enable/disable auto-update on settings page
|
||||
constexpr auto kShowAutoUpdateSetting =
|
||||
flags::Flag<bool>(kConfigPackage, "45409033", false);
|
||||
// When true, use gRpc client to access backend.
|
||||
constexpr auto kUseGrpcClient =
|
||||
flags::Flag<bool>(kConfigPackage, "45630055", false);
|
||||
// When true, delete the file payload which received unexpectedly.
|
||||
constexpr auto kDeleteUnexpectedReceivedFileFix =
|
||||
flags::Flag<bool>(kConfigPackage, "45657036", false);
|
||||
// The default time in milliseconds a cached entry can be in LOST state.
|
||||
constexpr auto kDiscoveryCacheLostExpiryMs =
|
||||
flags::Flag<int64_t>(kConfigPackage, "45658774", 500);
|
||||
// When true, enable Nearby Share gRPC async client.
|
||||
constexpr auto kEnableNearbyShareGrpcAsyncClient =
|
||||
flags::Flag<bool>(kConfigPackage, "45726584", false);
|
||||
flags::Flag<int64_t>(kConfigPackage, "45658774", 15000);
|
||||
// When true, enable wifi hotspot medium for HP Realtek devices.
|
||||
constexpr auto kEnableWifiHotspotForHpRealtekDevices =
|
||||
flags::Flag<bool>(kConfigPackage, "45673628", false);
|
||||
@@ -89,12 +77,6 @@ constexpr auto kUnregisterTargetDiscoveryCacheLostExpiryMs =
|
||||
// When true, enable alternate BLE service UUID for discovery.
|
||||
constexpr auto kUseAlternateServiceUuidForDiscovery =
|
||||
flags::Flag<bool>(kConfigPackage, "45683539", false);
|
||||
// Enable/disable QR Code UI
|
||||
constexpr auto kEnableQrCodeUi =
|
||||
flags::Flag<bool>(kConfigPackage, "45417647", false);
|
||||
// Show Admin mode warning message in the app
|
||||
constexpr auto kShowAdminModeWarning =
|
||||
flags::Flag<bool>(kConfigPackage, "45410558", false);
|
||||
// Update track
|
||||
constexpr auto kUpdateTrack =
|
||||
flags::Flag<absl::string_view>(kConfigPackage, "45409861", "");
|
||||
@@ -106,19 +88,19 @@ constexpr auto kEnableBetaLabel =
|
||||
flags::Flag<bool>(kConfigPackage, "45662570", true);
|
||||
// Enable the info banner to display duplicate Quick Share apps.
|
||||
constexpr auto kEnableConflictBanner =
|
||||
flags::Flag<bool>(kConfigPackage, "45661130", false);
|
||||
flags::Flag<bool>(kConfigPackage, "45661130", true);
|
||||
// When true, enables use of Flutter hooks.
|
||||
constexpr auto kEnableFlutterHooks =
|
||||
flags::Flag<bool>(kConfigPackage, "45720206", false);
|
||||
// When true, enables the mini pulse animation.
|
||||
constexpr auto kEnableMiniPulse =
|
||||
flags::Flag<bool>(kConfigPackage, "45724244", false);
|
||||
// When true, enables notifications implemented in native code.
|
||||
constexpr auto kEnableNativeNotifications =
|
||||
flags::Flag<bool>(kConfigPackage, "45743135", false);
|
||||
// When true, enables responsive UI.
|
||||
constexpr auto kEnableResponsiveUi =
|
||||
flags::Flag<bool>(kConfigPackage, "45727212", false);
|
||||
// When true, enables UI experiments.
|
||||
constexpr auto kEnableUiExperiments =
|
||||
flags::Flag<bool>(kConfigPackage, "45678202", false);
|
||||
|
||||
inline absl::btree_map<int, const flags::Flag<bool>&> GetBoolFlags() {
|
||||
return {
|
||||
@@ -129,22 +111,16 @@ inline absl::btree_map<int, const flags::Flag<bool>&> GetBoolFlags() {
|
||||
{45411589, kEnableRetryResumeTransfer},
|
||||
{45418908, kEnableSelfShareUi},
|
||||
{45459748, kEnableSendingDesktopEvents},
|
||||
{45411620, kEnableWebrtcMedium},
|
||||
{45411353, kSenderSkipsConfirmation},
|
||||
{45409033, kShowAutoUpdateSetting},
|
||||
{45630055, kUseGrpcClient},
|
||||
{45657036, kDeleteUnexpectedReceivedFileFix},
|
||||
{45726584, kEnableNearbyShareGrpcAsyncClient},
|
||||
{45673628, kEnableWifiHotspotForHpRealtekDevices},
|
||||
{45683539, kUseAlternateServiceUuidForDiscovery},
|
||||
{45417647, kEnableQrCodeUi},
|
||||
{45410558, kShowAdminModeWarning},
|
||||
{45662570, kEnableBetaLabel},
|
||||
{45661130, kEnableConflictBanner},
|
||||
{45720206, kEnableFlutterHooks},
|
||||
{45724244, kEnableMiniPulse},
|
||||
{45743135, kEnableNativeNotifications},
|
||||
{45727212, kEnableResponsiveUi},
|
||||
{45678202, kEnableUiExperiments},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,15 @@ std::optional<TransferMetadata::Status>
|
||||
IncomingShareSession::ProcessIntroduction(
|
||||
const IntroductionFrame& introduction_frame) {
|
||||
int64_t file_size_sum = 0;
|
||||
AttachmentContainer& container = mutable_attachment_container();
|
||||
int app_file_count = 0;
|
||||
for (const AppMetadata& apk : introduction_frame.app_metadata()) {
|
||||
app_file_count += apk.file_name_size();
|
||||
}
|
||||
AttachmentContainer::Builder builder;
|
||||
builder.ReserveAttachmentsCount(
|
||||
introduction_frame.text_metadata_size() + app_file_count,
|
||||
introduction_frame.file_metadata_size(),
|
||||
introduction_frame.wifi_credentials_metadata_size());
|
||||
for (const auto& file : introduction_frame.file_metadata()) {
|
||||
if (file.size() <= 0) {
|
||||
LOG(WARNING) << "Ignore introduction, due to invalid attachment size";
|
||||
@@ -97,7 +105,7 @@ IncomingShareSession::ProcessIntroduction(
|
||||
<< ", payload_id=" << file.payload_id()
|
||||
<< ", parent_folder=" << file.parent_folder()
|
||||
<< ", mime_type=" << file.mime_type();
|
||||
container.AddFileAttachment(
|
||||
builder.AddFileAttachment(
|
||||
FileAttachment(file.id(), file.size(), file.name(), file.mime_type(),
|
||||
file.type(), file.parent_folder()));
|
||||
SetAttachmentPayloadId(file.id(), file.payload_id());
|
||||
@@ -105,7 +113,6 @@ IncomingShareSession::ProcessIntroduction(
|
||||
if (std::numeric_limits<int64_t>::max() - file.size() < file_size_sum) {
|
||||
LOG(WARNING) << "Ignoring introduction, total file size overflowed 64 "
|
||||
"bit integer.";
|
||||
container.Clear();
|
||||
return TransferMetadata::Status::kNotEnoughSpace;
|
||||
}
|
||||
file_size_sum += file.size();
|
||||
@@ -126,7 +133,6 @@ IncomingShareSession::ProcessIntroduction(
|
||||
LOG(WARNING) << __func__
|
||||
<< ": Ignoring introduction, total file size overflowed "
|
||||
"64 bit integer.";
|
||||
container.Clear();
|
||||
return TransferMetadata::Status::kNotEnoughSpace;
|
||||
}
|
||||
// Map each apk file to a file attachment.
|
||||
@@ -141,7 +147,7 @@ IncomingShareSession::ProcessIntroduction(
|
||||
<< ", attachment id=" << apk_file_id
|
||||
<< ", file size=" << apk.file_size(index)
|
||||
<< ", payload_id=" << apk.payload_id(index);
|
||||
container.AddFileAttachment(std::move(apk_file));
|
||||
builder.AddFileAttachment(std::move(apk_file));
|
||||
SetAttachmentPayloadId(apk_file_id, apk.payload_id(index));
|
||||
}
|
||||
file_size_sum += apk.size();
|
||||
@@ -156,7 +162,7 @@ IncomingShareSession::ProcessIntroduction(
|
||||
VLOG(1) << "Found text attachment: id=" << text.id()
|
||||
<< ", type= " << text.type() << ", size=" << text.size()
|
||||
<< ", payload_id=" << text.payload_id();
|
||||
container.AddTextAttachment(
|
||||
builder.AddTextAttachment(
|
||||
TextAttachment(text.id(), text.type(), text.text_title(), text.size()));
|
||||
SetAttachmentPayloadId(text.id(), text.payload_id());
|
||||
}
|
||||
@@ -167,7 +173,7 @@ IncomingShareSession::ProcessIntroduction(
|
||||
VLOG(1) << "Found WiFi credentials attachment: id="
|
||||
<< wifi_credentials.id() << ", ssid= " << wifi_credentials.ssid()
|
||||
<< ", payload_id=" << wifi_credentials.payload_id();
|
||||
container.AddWifiCredentialsAttachment(WifiCredentialsAttachment(
|
||||
builder.AddWifiCredentialsAttachment(WifiCredentialsAttachment(
|
||||
wifi_credentials.id(), wifi_credentials.ssid(),
|
||||
wifi_credentials.security_type()));
|
||||
SetAttachmentPayloadId(wifi_credentials.id(),
|
||||
@@ -175,12 +181,13 @@ IncomingShareSession::ProcessIntroduction(
|
||||
}
|
||||
}
|
||||
|
||||
if (!container.HasAttachments()) {
|
||||
if (builder.Empty()) {
|
||||
LOG(WARNING) << __func__
|
||||
<< ": No attachment is found for this share target. It can "
|
||||
"be result of unrecognizable attachment type";
|
||||
return TransferMetadata::Status::kUnsupportedAttachmentType;
|
||||
}
|
||||
mutable_attachment_container() = std::move(*builder.Build());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -305,7 +312,7 @@ bool IncomingShareSession::UpdateFilePayloadPaths() {
|
||||
continue;
|
||||
}
|
||||
|
||||
FilePath file_path = incoming_payload->content.file_payload.file.path;
|
||||
FilePath file_path = incoming_payload->content.file_payload.file_path;
|
||||
VLOG(1) << __func__ << ": Updated file_path=" << file_path.ToString();
|
||||
file.set_file_path(file_path);
|
||||
}
|
||||
|
||||
@@ -89,8 +89,7 @@ constexpr absl::string_view kEndpointId = "ABCD";
|
||||
|
||||
std::unique_ptr<Payload> CreateFilePayload(int64_t payload_id,
|
||||
FilePath file_path) {
|
||||
auto file_payload =
|
||||
std::make_unique<Payload>(InputFile(file_path.ToString()));
|
||||
auto file_payload = std::make_unique<Payload>(file_path);
|
||||
file_payload->id = payload_id;
|
||||
return file_payload;
|
||||
}
|
||||
@@ -218,7 +217,6 @@ TEST_F(IncomingShareSessionTest, ProcessIntroductionNoSupportedPayload) {
|
||||
TEST_F(IncomingShareSessionTest, ProcessIntroductionEmptyFile) {
|
||||
session_.OnConnected(&connection_);
|
||||
IntroductionFrame frame;
|
||||
frame.mutable_file_metadata();
|
||||
|
||||
EXPECT_THAT(session_.ProcessIntroduction(frame),
|
||||
Eq(TransferMetadata::Status::kUnsupportedAttachmentType));
|
||||
@@ -243,7 +241,6 @@ TEST_F(IncomingShareSessionTest, ProcessIntroductionFilesTooLarge) {
|
||||
TEST_F(IncomingShareSessionTest, ProcessIntroductionEmptyText) {
|
||||
session_.OnConnected(&connection_);
|
||||
IntroductionFrame frame;
|
||||
frame.mutable_text_metadata();
|
||||
|
||||
EXPECT_THAT(session_.ProcessIntroduction(frame),
|
||||
Eq(TransferMetadata::Status::kUnsupportedAttachmentType));
|
||||
|
||||
@@ -23,15 +23,13 @@ namespace nearby::sharing::api {
|
||||
|
||||
class MockNetworkMonitor : public nearby::api::NetworkMonitor {
|
||||
public:
|
||||
MockNetworkMonitor() : nearby::api::NetworkMonitor(nullptr) {}
|
||||
MockNetworkMonitor() : nearby::api::NetworkMonitor(nullptr, nullptr) {}
|
||||
MockNetworkMonitor(const MockNetworkMonitor&) = delete;
|
||||
MockNetworkMonitor& operator=(const MockNetworkMonitor&) = delete;
|
||||
~MockNetworkMonitor() override = default;
|
||||
|
||||
MOCK_METHOD(bool, IsLanConnected, (), (override));
|
||||
MOCK_METHOD(bool, IsInternetConnected, (), (override));
|
||||
|
||||
MOCK_METHOD(ConnectionType, GetCurrentConnection, (), (override));
|
||||
};
|
||||
|
||||
} // namespace nearby::sharing::api
|
||||
|
||||
@@ -48,13 +48,12 @@ class MockSharingPlatform : public SharingPlatform {
|
||||
~MockSharingPlatform() override = default;
|
||||
|
||||
MOCK_METHOD(void, InitProductIdGetter,
|
||||
(absl::string_view (*product_id_getter)()), (override));
|
||||
(absl::string_view(*product_id_getter)()), (override));
|
||||
|
||||
MOCK_METHOD(std::unique_ptr<nearby::api::NetworkMonitor>,
|
||||
CreateNetworkMonitor,
|
||||
(std::function<void(nearby::api::NetworkMonitor::ConnectionType,
|
||||
bool, bool)>
|
||||
callback),
|
||||
(std::function<void(bool)> lan_connected_callback,
|
||||
std::function<void(bool)> internet_connected_callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(nearby::sharing::api::BluetoothAdapter&, GetBluetoothAdapter, (),
|
||||
|
||||
@@ -15,36 +15,23 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_NETWORK_MONITOR_H_
|
||||
#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_NETWORK_MONITOR_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace api {
|
||||
|
||||
class NetworkMonitor {
|
||||
public:
|
||||
enum class ConnectionType : int {
|
||||
kUnknown = 0, // A connection exists, but its type is unknown.
|
||||
// Also used as a default value.
|
||||
kEthernet = 1,
|
||||
kWifi = 2,
|
||||
k2G = 3,
|
||||
k3G = 4,
|
||||
k4G = 5,
|
||||
kNone = 6, // No connection.
|
||||
kBluetooth = 7,
|
||||
k5G = 8,
|
||||
kLast = k5G
|
||||
};
|
||||
|
||||
// Registers a callback for connection changes. The callback will be called
|
||||
// with the current connection type, whether the device is connected to a
|
||||
// LAN network and whether the device is connected to internet.
|
||||
explicit NetworkMonitor(
|
||||
std::function<void(ConnectionType, bool, bool)> callback) {
|
||||
callback_ = std::move(callback);
|
||||
}
|
||||
// Registers callbacks for connection changes. The callbacks will be called
|
||||
// when device is connected to a LAN network or when the device is connected
|
||||
// to internet.
|
||||
NetworkMonitor(
|
||||
absl::AnyInvocable<void(bool)> lan_connected_callback,
|
||||
absl::AnyInvocable<void(bool)> internet_connected_callback)
|
||||
: lan_connected_callback_(std::move(lan_connected_callback)),
|
||||
internet_connected_callback_(std::move(internet_connected_callback)){}
|
||||
|
||||
virtual ~NetworkMonitor() = default;
|
||||
|
||||
@@ -55,11 +42,9 @@ class NetworkMonitor {
|
||||
// Returns true if connected to internet.
|
||||
virtual bool IsInternetConnected() = 0;
|
||||
|
||||
// Returns the type of connection used currently to access the internet
|
||||
virtual ConnectionType GetCurrentConnection() = 0;
|
||||
|
||||
protected:
|
||||
std::function<void(ConnectionType, bool, bool)> callback_;
|
||||
absl::AnyInvocable<void(bool)> lan_connected_callback_;
|
||||
absl::AnyInvocable<void(bool)> internet_connected_callback_;
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -48,9 +48,8 @@ class SharingPlatform {
|
||||
absl::string_view (*product_id_getter)()) = 0;
|
||||
|
||||
virtual std::unique_ptr<nearby::api::NetworkMonitor> CreateNetworkMonitor(
|
||||
std::function<void(nearby::api::NetworkMonitor::ConnectionType, bool,
|
||||
bool)>
|
||||
callback) = 0;
|
||||
std::function<void(bool)> lan_connected_callback,
|
||||
std::function<void(bool)> internet_connected_callback) = 0;
|
||||
|
||||
virtual BluetoothAdapter& GetBluetoothAdapter() = 0;
|
||||
|
||||
|
||||
@@ -55,23 +55,20 @@ cc_library(
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":logging",
|
||||
":types",
|
||||
"//internal/flags:nearby_flags",
|
||||
"//internal/network:url",
|
||||
"//internal/platform:types",
|
||||
"//sharing/flags/generated:generated_flags",
|
||||
"//sharing/internal/api:platform",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "nearby_context_test",
|
||||
name = "connectivity_manager_impl_test",
|
||||
size = "small",
|
||||
timeout = "short",
|
||||
srcs = [
|
||||
|
||||
@@ -23,35 +23,21 @@ namespace nearby {
|
||||
|
||||
class ConnectivityManager {
|
||||
public:
|
||||
enum class ConnectionType {
|
||||
kUnknown = 0, // A connection exists, but its type is unknown.
|
||||
// Also used as a default value.
|
||||
kEthernet = 1,
|
||||
kWifi = 2,
|
||||
k2G = 3,
|
||||
k3G = 4,
|
||||
k4G = 5,
|
||||
kNone = 6, // No connection.
|
||||
kBluetooth = 7,
|
||||
k5G = 8,
|
||||
kLast = k5G
|
||||
};
|
||||
|
||||
virtual ~ConnectivityManager() = default;
|
||||
|
||||
virtual bool IsLanConnected() = 0;
|
||||
virtual bool IsInternetConnected() = 0;
|
||||
|
||||
virtual ConnectionType GetConnectionType() = 0;
|
||||
|
||||
// Registers a listener for connection changes. The listener will be called
|
||||
// with the current connection type, whether the device is connected to a
|
||||
// LAN network and whether the device is connected to internet.
|
||||
virtual void RegisterConnectionListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(ConnectionType, bool, bool)>) = 0;
|
||||
virtual void UnregisterConnectionListener(
|
||||
absl::string_view listener_name) = 0;
|
||||
// when the device is connected to a LAN network or when the device is
|
||||
// connected to internet.
|
||||
virtual void RegisterLanListener(absl::string_view listener_name,
|
||||
std::function<void(bool)>) = 0;
|
||||
virtual void UnregisterLanListener(absl::string_view listener_name) = 0;
|
||||
virtual void RegisterInternetListener(absl::string_view listener_name,
|
||||
std::function<void(bool)>) = 0;
|
||||
virtual void UnregisterInternetListener(absl::string_view listener_name) = 0;
|
||||
|
||||
// Is the device a HP device with Realtek wireless module.
|
||||
virtual bool IsHPRealtekDevice() = 0;
|
||||
};
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
@@ -29,50 +28,27 @@
|
||||
#include "sharing/flags/generated/nearby_sharing_feature_flags.h"
|
||||
#include "sharing/internal/api/network_monitor.h"
|
||||
#include "sharing/internal/api/sharing_platform.h"
|
||||
#include "sharing/internal/public/connectivity_manager.h"
|
||||
#include "sharing/internal/public/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
|
||||
using ::nearby::sharing::api::SharingPlatform;
|
||||
using ConnectionType = ConnectivityManager::ConnectionType;
|
||||
|
||||
std::string GetConnectionTypeString(ConnectionType connection_type) {
|
||||
switch (connection_type) {
|
||||
case ConnectionType::k2G:
|
||||
return "2G";
|
||||
case ConnectionType::k3G:
|
||||
return "3G";
|
||||
case ConnectionType::k4G:
|
||||
return "4G";
|
||||
case ConnectionType::k5G:
|
||||
return "5G";
|
||||
case ConnectionType::kBluetooth:
|
||||
return "Bluetooth";
|
||||
case ConnectionType::kEthernet:
|
||||
return "Ethernet";
|
||||
case ConnectionType::kWifi:
|
||||
return "WiFi";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ConnectivityManagerImpl::ConnectivityManagerImpl(SharingPlatform& platform)
|
||||
: platform_(platform) {
|
||||
network_monitor_ = platform.CreateNetworkMonitor(
|
||||
[this](api::NetworkMonitor::ConnectionType connection_type,
|
||||
bool is_lan_connected, bool is_internet_connected) {
|
||||
ConnectionType new_connection_type =
|
||||
static_cast<ConnectionType>(connection_type);
|
||||
VLOG(1) << ": New connection type:"
|
||||
<< GetConnectionTypeString(new_connection_type);
|
||||
for (auto& listener : listeners_) {
|
||||
listener.second(new_connection_type, is_lan_connected,
|
||||
is_internet_connected);
|
||||
[this](bool is_lan_connected) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
for (auto& listener : lan_listeners_) {
|
||||
listener.second(is_lan_connected);
|
||||
}
|
||||
},
|
||||
[this](bool is_internet_connected) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
for (auto& listener : internet_listeners_) {
|
||||
listener.second(is_internet_connected);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -113,23 +89,37 @@ bool ConnectivityManagerImpl::IsHPRealtekDevice() {
|
||||
return is_hp_realtek_device_.value();
|
||||
}
|
||||
|
||||
ConnectionType ConnectivityManagerImpl::GetConnectionType() {
|
||||
return static_cast<ConnectionType>(network_monitor_->GetCurrentConnection());
|
||||
void ConnectivityManagerImpl::RegisterLanListener(
|
||||
absl::string_view listener_name, std::function<void(bool)> callback) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
lan_listeners_.emplace(listener_name, std::move(callback));
|
||||
}
|
||||
|
||||
void ConnectivityManagerImpl::RegisterConnectionListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(ConnectionType, bool, bool)> callback) {
|
||||
listeners_.emplace(listener_name, std::move(callback));
|
||||
}
|
||||
|
||||
void ConnectivityManagerImpl::UnregisterConnectionListener(
|
||||
void ConnectivityManagerImpl::UnregisterLanListener(
|
||||
absl::string_view listener_name) {
|
||||
listeners_.erase(listener_name);
|
||||
absl::MutexLock lock(mutex_);
|
||||
lan_listeners_.erase(listener_name);
|
||||
}
|
||||
|
||||
int ConnectivityManagerImpl::GetListenerCount() const {
|
||||
return listeners_.size();
|
||||
void ConnectivityManagerImpl::RegisterInternetListener(
|
||||
absl::string_view listener_name, std::function<void(bool)> callback) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
internet_listeners_.emplace(listener_name, std::move(callback));
|
||||
}
|
||||
|
||||
void ConnectivityManagerImpl::UnregisterInternetListener(
|
||||
absl::string_view listener_name) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
internet_listeners_.erase(listener_name);
|
||||
}
|
||||
|
||||
int ConnectivityManagerImpl::GetLanListenerCountForTests() const {
|
||||
absl::MutexLock lock(mutex_);
|
||||
return lan_listeners_.size();
|
||||
}
|
||||
int ConnectivityManagerImpl::GetInternetListenerCountForTests() const {
|
||||
absl::MutexLock lock(mutex_);
|
||||
return internet_listeners_.size();
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "sharing/internal/api/network_monitor.h"
|
||||
#include "sharing/internal/api/sharing_platform.h"
|
||||
#include "sharing/internal/api/system_info.h"
|
||||
#include "sharing/internal/public/connectivity_manager.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -40,19 +39,22 @@ class ConnectivityManagerImpl : public ConnectivityManager {
|
||||
bool IsLanConnected() override;
|
||||
bool IsInternetConnected() override;
|
||||
bool IsHPRealtekDevice() override;
|
||||
ConnectionType GetConnectionType() override;
|
||||
|
||||
void RegisterConnectionListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(ConnectionType, bool, bool)> callback) override;
|
||||
void UnregisterConnectionListener(absl::string_view listener_name) override;
|
||||
void RegisterLanListener(absl::string_view listener_name,
|
||||
std::function<void(bool)>) override;
|
||||
void UnregisterLanListener(absl::string_view listener_name) override;
|
||||
void RegisterInternetListener(absl::string_view listener_name,
|
||||
std::function<void(bool)>) override;
|
||||
void UnregisterInternetListener(absl::string_view listener_name) override;
|
||||
|
||||
int GetListenerCount() const;
|
||||
int GetLanListenerCountForTests() const;
|
||||
int GetInternetListenerCountForTests() const;
|
||||
|
||||
private:
|
||||
absl::flat_hash_map<std::string,
|
||||
std::function<void(ConnectionType, bool, bool)>>
|
||||
listeners_;
|
||||
absl::flat_hash_map<std::string, std::function<void(bool)>> lan_listeners_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
absl::flat_hash_map<std::string, std::function<void(bool)>>
|
||||
internet_listeners_ ABSL_GUARDED_BY(mutex_);
|
||||
std::unique_ptr<api::NetworkMonitor> network_monitor_;
|
||||
nearby::sharing::api::SharingPlatform& platform_;
|
||||
mutable absl::Mutex mutex_;
|
||||
|
||||
@@ -42,25 +42,24 @@ TEST(ConnectivityManagerImpl, IsLanConnected) {
|
||||
auto network_monitor = std::make_unique<MockNetworkMonitor>();
|
||||
MockNetworkMonitor* mock_network_monitor = network_monitor.get();
|
||||
EXPECT_CALL(*mock_network_monitor, IsLanConnected()).WillOnce(Return(true));
|
||||
EXPECT_CALL(sharing_platform, CreateNetworkMonitor(_))
|
||||
EXPECT_CALL(sharing_platform, CreateNetworkMonitor(_, _))
|
||||
.WillOnce(Return(ByMove(std::move(network_monitor))));
|
||||
|
||||
ConnectivityManagerImpl connectivity_manager_impl(sharing_platform);
|
||||
EXPECT_TRUE(connectivity_manager_impl.IsLanConnected());
|
||||
}
|
||||
|
||||
TEST(ConnectivityManagerImpl, GetConnectionType) {
|
||||
TEST(ConnectivityManagerImpl, IsInternetConnected) {
|
||||
MockSharingPlatform sharing_platform;
|
||||
auto network_monitor = std::make_unique<MockNetworkMonitor>();
|
||||
MockNetworkMonitor* mock_network_monitor = network_monitor.get();
|
||||
EXPECT_CALL(sharing_platform, CreateNetworkMonitor(_))
|
||||
EXPECT_CALL(*mock_network_monitor, IsInternetConnected())
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(sharing_platform, CreateNetworkMonitor(_, _))
|
||||
.WillOnce(Return(ByMove(std::move(network_monitor))));
|
||||
EXPECT_CALL(*mock_network_monitor, GetCurrentConnection())
|
||||
.WillOnce(Return(MockNetworkMonitor::ConnectionType::kWifi));
|
||||
|
||||
ConnectivityManagerImpl connectivity_manager_impl(sharing_platform);
|
||||
EXPECT_EQ(connectivity_manager_impl.GetConnectionType(),
|
||||
ConnectivityManager::ConnectionType::kWifi);
|
||||
EXPECT_TRUE(connectivity_manager_impl.IsInternetConnected());
|
||||
}
|
||||
|
||||
TEST(ConnectivityManagerImpl, IsHPRealtekDeviceReturnsTrue) {
|
||||
@@ -111,49 +110,43 @@ TEST(ConnectivityManagerImpl, IsHPRealtekDevice_NotRealtekDevice) {
|
||||
EXPECT_FALSE(connectivity_manager_impl.IsHPRealtekDevice());
|
||||
}
|
||||
|
||||
TEST(ConnectivityManagerImpl, RegisterConnectionListener) {
|
||||
std::function<void(ConnectivityManager::ConnectionType, bool, bool)>
|
||||
listener_1 = [](ConnectivityManager::ConnectionType connection_type,
|
||||
bool is_lan_connected, bool is_internet_connected) {};
|
||||
std::function<void(ConnectivityManager::ConnectionType, bool, bool)>
|
||||
listener_2 = [](ConnectivityManager::ConnectionType connection_type,
|
||||
bool is_lan_connected, bool is_internet_connected) {};
|
||||
TEST(ConnectivityManagerImpl, RegisterLanListener) {
|
||||
auto
|
||||
listener_1 = [](bool is_lan_connected) {};
|
||||
auto
|
||||
listener_2 = [](bool is_lan_connected) {};
|
||||
|
||||
MockSharingPlatform sharing_platform;
|
||||
ConnectivityManagerImpl connectivity_manager_impl(sharing_platform);
|
||||
EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 0);
|
||||
EXPECT_EQ(connectivity_manager_impl.GetLanListenerCountForTests(), 0);
|
||||
|
||||
connectivity_manager_impl.RegisterConnectionListener("listener_1",
|
||||
connectivity_manager_impl.RegisterLanListener("listener_1",
|
||||
listener_1);
|
||||
EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 1);
|
||||
EXPECT_EQ(connectivity_manager_impl.GetLanListenerCountForTests(), 1);
|
||||
|
||||
connectivity_manager_impl.RegisterConnectionListener("listener_2",
|
||||
connectivity_manager_impl.RegisterLanListener("listener_2",
|
||||
listener_2);
|
||||
EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 2);
|
||||
EXPECT_EQ(connectivity_manager_impl.GetLanListenerCountForTests(), 2);
|
||||
}
|
||||
|
||||
TEST(ConnectivityManagerImpl, UnregisterConnectionListener) {
|
||||
std::function<void(ConnectivityManager::ConnectionType, bool, bool)>
|
||||
listener_1 = [](ConnectivityManager::ConnectionType connection_type,
|
||||
bool is_lan_connected, bool is_internet_connected) {};
|
||||
std::function<void(ConnectivityManager::ConnectionType, bool, bool)>
|
||||
listener_2 = [](ConnectivityManager::ConnectionType connection_type,
|
||||
bool is_lan_connected, bool is_internet_connected) {};
|
||||
TEST(ConnectivityManagerImpl, UnregisterLanListener) {
|
||||
auto listener_1 = [](bool is_lan_connected) {};
|
||||
auto listener_2 = [](bool is_lan_connected) {};
|
||||
|
||||
MockSharingPlatform sharing_platform;
|
||||
ConnectivityManagerImpl connectivity_manager_impl(sharing_platform);
|
||||
connectivity_manager_impl.RegisterConnectionListener("listener_1",
|
||||
connectivity_manager_impl.RegisterLanListener("listener_1",
|
||||
listener_1);
|
||||
connectivity_manager_impl.RegisterConnectionListener("listener_2",
|
||||
connectivity_manager_impl.RegisterLanListener("listener_2",
|
||||
listener_2);
|
||||
|
||||
EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 2);
|
||||
EXPECT_EQ(connectivity_manager_impl.GetLanListenerCountForTests(), 2);
|
||||
|
||||
connectivity_manager_impl.UnregisterConnectionListener("listener_1");
|
||||
EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 1);
|
||||
connectivity_manager_impl.UnregisterLanListener("listener_1");
|
||||
EXPECT_EQ(connectivity_manager_impl.GetLanListenerCountForTests(), 1);
|
||||
|
||||
connectivity_manager_impl.UnregisterConnectionListener("listener_2");
|
||||
EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 0);
|
||||
connectivity_manager_impl.UnregisterLanListener("listener_2");
|
||||
EXPECT_EQ(connectivity_manager_impl.GetLanListenerCountForTests(), 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -31,7 +31,6 @@ cc_library(
|
||||
"fake_connectivity_manager.h",
|
||||
"fake_context.h",
|
||||
"fake_fast_initiation_manager.h",
|
||||
"fake_network_monitor.h",
|
||||
"fake_preference_manager.h",
|
||||
"fake_public_certificate_db.h",
|
||||
],
|
||||
|
||||
@@ -33,52 +33,43 @@ class FakeConnectivityManager : public ConnectivityManager {
|
||||
void SetIsHPRealtekDevice(bool is_hp_realtek_device) {
|
||||
is_hp_realtek_device_ = is_hp_realtek_device;
|
||||
}
|
||||
ConnectionType GetConnectionType() override { return connection_type_; }
|
||||
|
||||
void RegisterConnectionListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(ConnectionType, bool, bool)> callback) override {
|
||||
listeners_.emplace(listener_name, std::move(callback));
|
||||
void RegisterLanListener(absl::string_view listener_name,
|
||||
std::function<void(bool)> callback) override {
|
||||
lan_listeners_.emplace(listener_name, std::move(callback));
|
||||
}
|
||||
void UnregisterConnectionListener(absl::string_view listener_name) override {
|
||||
listeners_.erase(listener_name);
|
||||
void UnregisterLanListener(absl::string_view listener_name) override {
|
||||
lan_listeners_.erase(listener_name);
|
||||
}
|
||||
void RegisterInternetListener(absl::string_view listener_name,
|
||||
std::function<void(bool)> callback) override {
|
||||
internet_listeners_.emplace(listener_name, std::move(callback));
|
||||
}
|
||||
void UnregisterInternetListener(absl::string_view listener_name) override {
|
||||
internet_listeners_.erase(listener_name);
|
||||
}
|
||||
|
||||
// Mocks connectivity methods.
|
||||
void SetLanConnected(bool connected) {
|
||||
is_lan_connected_ = connected;
|
||||
for (auto& listener : listeners_) {
|
||||
listener.second(connection_type_, is_lan_connected_,
|
||||
is_internet_connected_);
|
||||
for (auto& listener : lan_listeners_) {
|
||||
listener.second(is_lan_connected_);
|
||||
}
|
||||
}
|
||||
|
||||
void SetInternetConnected(bool connected) {
|
||||
is_internet_connected_ = connected;
|
||||
for (auto& listener : listeners_) {
|
||||
listener.second(connection_type_, is_lan_connected_,
|
||||
is_internet_connected_);
|
||||
for (auto& listener : internet_listeners_) {
|
||||
listener.second(is_internet_connected_);
|
||||
}
|
||||
}
|
||||
|
||||
// Mocks connectivity methods.
|
||||
void SetConnectionType(ConnectionType connection_type) {
|
||||
connection_type_ = connection_type;
|
||||
for (auto& listener : listeners_) {
|
||||
listener.second(connection_type_, is_lan_connected_,
|
||||
is_internet_connected_);
|
||||
}
|
||||
}
|
||||
int GetListenerCount() const { return listeners_.size(); }
|
||||
|
||||
private:
|
||||
bool is_lan_connected_ = true;
|
||||
bool is_internet_connected_ = true;
|
||||
bool is_hp_realtek_device_ = false;
|
||||
ConnectionType connection_type_ = ConnectionType::kWifi;
|
||||
absl::flat_hash_map<std::string,
|
||||
std::function<void(ConnectionType, bool, bool)>>
|
||||
listeners_;
|
||||
absl::flat_hash_map<std::string, std::function<void(bool)>> lan_listeners_;
|
||||
absl::flat_hash_map<std::string, std::function<void(bool)>>
|
||||
internet_listeners_;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "sharing/internal/test/fake_connectivity_manager.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "sharing/internal/public/connectivity_manager.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
@@ -28,40 +27,16 @@ TEST(FakeConnectivityManager, TestIsLanConnected) {
|
||||
EXPECT_FALSE(connection_manager.IsLanConnected());
|
||||
}
|
||||
|
||||
TEST(FakeConnectivityManager, TestGetCurrentConnection) {
|
||||
FakeConnectivityManager connection_manager;
|
||||
ConnectivityManager::ConnectionType connection =
|
||||
connection_manager.GetConnectionType();
|
||||
EXPECT_EQ(connection, ConnectivityManager::ConnectionType::kWifi);
|
||||
connection_manager.SetConnectionType(
|
||||
ConnectivityManager::ConnectionType::kEthernet);
|
||||
EXPECT_EQ(connection_manager.GetConnectionType(),
|
||||
ConnectivityManager::ConnectionType::kEthernet);
|
||||
}
|
||||
|
||||
TEST(FakeConnectivityManager, TestListener) {
|
||||
FakeConnectivityManager connection_manager;
|
||||
ConnectivityManager::ConnectionType connection_type =
|
||||
connection_manager.GetConnectionType();
|
||||
bool is_lan_connected = false;
|
||||
connection_manager.RegisterConnectionListener(
|
||||
"test", [&connection_type, &is_lan_connected](
|
||||
ConnectivityManager::ConnectionType connection,
|
||||
bool connected, bool internet_connected) {
|
||||
connection_type = connection;
|
||||
is_lan_connected = connected;
|
||||
connection_manager.RegisterLanListener(
|
||||
"test", [&is_lan_connected](bool lan_connected) {
|
||||
is_lan_connected = lan_connected;
|
||||
});
|
||||
EXPECT_EQ(connection_manager.GetListenerCount(), 1);
|
||||
connection_manager.SetConnectionType(
|
||||
ConnectivityManager::ConnectionType::kEthernet);
|
||||
connection_manager.SetLanConnected(true);
|
||||
EXPECT_EQ(connection_type, ConnectivityManager::ConnectionType::kEthernet);
|
||||
ASSERT_TRUE(is_lan_connected);
|
||||
connection_manager.UnregisterConnectionListener("test");
|
||||
EXPECT_EQ(connection_manager.GetListenerCount(), 0);
|
||||
connection_manager.SetConnectionType(
|
||||
ConnectivityManager::ConnectionType::kWifi);
|
||||
EXPECT_EQ(connection_type, ConnectivityManager::ConnectionType::kEthernet);
|
||||
connection_manager.UnregisterLanListener("test");
|
||||
EXPECT_TRUE(is_lan_connected);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
// Copyright 2022 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_INTERNAL_TEST_FAKE_NETWORK_MONITOR_H_
|
||||
#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_NETWORK_MONITOR_H_
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "sharing/internal/api/network_monitor.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
class FakeNetworkMonitor : public api::NetworkMonitor {
|
||||
public:
|
||||
explicit FakeNetworkMonitor(
|
||||
std::function<void(api::NetworkMonitor::ConnectionType, bool, bool)>
|
||||
callback)
|
||||
: api::NetworkMonitor(callback) {}
|
||||
|
||||
~FakeNetworkMonitor() override { callback_ = nullptr; }
|
||||
|
||||
bool IsLanConnected() override { return is_lan_connected_; }
|
||||
bool IsInternetConnected() override { return is_internet_connected_; }
|
||||
|
||||
api::NetworkMonitor::ConnectionType GetCurrentConnection() override {
|
||||
return api::NetworkMonitor::ConnectionType::kWifi;
|
||||
}
|
||||
|
||||
void SetLanConnected(bool connected) { is_lan_connected_ = connected; }
|
||||
void SetInternetConnected(bool connected) {
|
||||
is_internet_connected_ = connected;
|
||||
}
|
||||
|
||||
void TestNetworkChangeToEthernet() {
|
||||
callback_(api::NetworkMonitor::ConnectionType::kEthernet,
|
||||
is_lan_connected_, is_internet_connected_);
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_lan_connected_ = true;
|
||||
bool is_internet_connected_ = true;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_NETWORK_MONITOR_H_
|
||||
@@ -72,17 +72,14 @@ bool ShouldUseInternet(ConnectivityManager& connectivity_manager,
|
||||
// We won't use the internet in a low power mode.
|
||||
if (power_level == PowerLevel::kLowPower) return false;
|
||||
|
||||
ConnectivityManager::ConnectionType connection_type =
|
||||
connectivity_manager.GetConnectionType();
|
||||
|
||||
// Verify that this network has an internet connection.
|
||||
if (connection_type == ConnectivityManager::ConnectionType::kNone) {
|
||||
if (!connectivity_manager.IsInternetConnected()) {
|
||||
VLOG(1) << __func__ << ": No internet connection.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data_usage == DataUsage::WIFI_ONLY_DATA_USAGE &&
|
||||
connection_type != ConnectivityManager::ConnectionType::kWifi) {
|
||||
!connectivity_manager.IsLanConnected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -105,13 +102,7 @@ bool ShouldEnableWifiLan(ConnectivityManager& connectivity_manager) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ConnectivityManager::ConnectionType connection_type =
|
||||
connectivity_manager.GetConnectionType();
|
||||
bool is_connection_wifi_or_ethernet =
|
||||
connection_type == ConnectivityManager::ConnectionType::kWifi ||
|
||||
connection_type == ConnectivityManager::ConnectionType::kEthernet;
|
||||
|
||||
return is_connection_wifi_or_ethernet;
|
||||
return connectivity_manager.IsLanConnected();
|
||||
}
|
||||
|
||||
// Temporarily fix to get around wifi hotspot issues for HP Aero with Realtek.
|
||||
@@ -818,7 +809,7 @@ void NearbyConnectionsManagerImpl::DeleteUnknownFilePayloadAndCancel(
|
||||
Payload& payload) {
|
||||
if (payload.content.type == PayloadContent::Type::kFile) {
|
||||
MutexLock lock(&mutex_);
|
||||
file_paths_to_delete_.insert(payload.content.file_payload.file.path);
|
||||
file_paths_to_delete_.insert(payload.content.file_payload.file_path);
|
||||
}
|
||||
Cancel(payload.id);
|
||||
}
|
||||
@@ -909,7 +900,7 @@ void NearbyConnectionsManagerImpl::OnPayloadTransferUpdate(
|
||||
nearby_connections_service_->CancelPayload(kServiceId, payload->id,
|
||||
[](Status status) {});
|
||||
ProcessUnknownFilePathsToDelete(update.status, payload->content.type,
|
||||
payload->content.file_payload.file.path);
|
||||
payload->content.file_payload.file_path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <ios>
|
||||
@@ -39,14 +38,13 @@
|
||||
#include "internal/base/file_path.h"
|
||||
#include "internal/base/files.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/test/fake_clock.h"
|
||||
#include "internal/test/fake_device_info.h"
|
||||
#include "internal/test/fake_task_runner.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/constants.h"
|
||||
#include "sharing/fake_nearby_connections_service.h"
|
||||
#include "sharing/flags/generated/nearby_sharing_feature_flags.h"
|
||||
#include "sharing/internal/public/connectivity_manager.h"
|
||||
#include "sharing/internal/public/logging.h"
|
||||
#include "sharing/internal/test/fake_connectivity_manager.h"
|
||||
#include "sharing/internal/test/fake_context.h"
|
||||
#include "sharing/nearby_connection.h"
|
||||
@@ -142,7 +140,6 @@ class NearbyConnectionsManagerImplTest : public testing::Test {
|
||||
true);
|
||||
auto nearby_connections_service =
|
||||
std::make_unique<testing::NiceMock<FakeNearbyConnectionsService>>();
|
||||
SetConnectionType(ConnectivityManager::ConnectionType::kWifi);
|
||||
nearby_connections_ = nearby_connections_service.get();
|
||||
|
||||
nearby_connections_manager_ =
|
||||
@@ -156,10 +153,10 @@ class NearbyConnectionsManagerImplTest : public testing::Test {
|
||||
fake_task_runner_.SyncWithTimeout(absl::Seconds(1));
|
||||
}
|
||||
|
||||
void SetConnectionType(ConnectivityManager::ConnectionType connection_type) {
|
||||
fake_connectivity_manager_.SetConnectionType(connection_type);
|
||||
void SetConnectionStatus(bool lan_connected, bool internet_connected) {
|
||||
fake_connectivity_manager_.SetLanConnected(lan_connected);
|
||||
fake_connectivity_manager_.SetInternetConnected(internet_connected);
|
||||
}
|
||||
|
||||
void Fastforward(absl::Duration duration) {
|
||||
fake_context_.fake_clock()->FastForward(duration);
|
||||
}
|
||||
@@ -241,8 +238,7 @@ class NearbyConnectionsManagerImplTest : public testing::Test {
|
||||
nearby_connections_manager_->StartAdvertising(
|
||||
local_endpoint_info, &incoming_connection_listener,
|
||||
PowerLevel::kHighPower, DataUsage::ONLINE_DATA_USAGE, false,
|
||||
/*force_new_endpoint_id=*/false,
|
||||
std::move(callback));
|
||||
/*force_new_endpoint_id=*/false, std::move(callback));
|
||||
EXPECT_TRUE(
|
||||
notification.WaitForNotificationWithTimeout(kSynchronizationTimeOut));
|
||||
}
|
||||
@@ -407,13 +403,13 @@ class NearbyConnectionsManagerImplTest : public testing::Test {
|
||||
EXPECT_EQ(payload_id, payload->id);
|
||||
|
||||
FilePayload file_payload = std::move(payload->content.file_payload);
|
||||
std::vector<uint8_t> payload_bytes(file_payload.size);
|
||||
std::ifstream payload_stream(file_payload.file.path.GetPath(),
|
||||
std::vector<uint8_t> payload_bytes(expected_payload.size());
|
||||
std::ifstream payload_stream(file_payload.file_path.GetPath(),
|
||||
std::ios::in | std::ios::binary);
|
||||
ASSERT_TRUE(payload_stream.good());
|
||||
payload_stream.read(reinterpret_cast<char*>(payload_bytes.data()),
|
||||
file_payload.size);
|
||||
ASSERT_EQ(payload_stream.gcount(), file_payload.size);
|
||||
payload_bytes.size());
|
||||
ASSERT_EQ(payload_stream.gcount(), payload_bytes.size());
|
||||
EXPECT_EQ(expected_payload, payload_bytes);
|
||||
payload_stream.close();
|
||||
|
||||
@@ -423,7 +419,7 @@ class NearbyConnectionsManagerImplTest : public testing::Test {
|
||||
|
||||
// Manually setup payload id, because the tested id is not generated from
|
||||
// file name.
|
||||
auto payload = std::make_unique<Payload>(InputFile(file.ToString()));
|
||||
auto payload = std::make_unique<Payload>(file);
|
||||
payload->id = payload_id;
|
||||
|
||||
nearby_connections_manager_->Send(kRemoteEndpointId, std::move(payload),
|
||||
@@ -532,7 +528,6 @@ TEST_F(NearbyConnectionsManagerImplTest, DiscoveryFlow) {
|
||||
|
||||
TEST_F(NearbyConnectionsManagerImplTest,
|
||||
DisableWifiHotspotForHighQualityNonDisruptiveTransport) {
|
||||
SetConnectionType(ConnectivityManager::ConnectionType::kWifi);
|
||||
// StartDiscovery will succeed.
|
||||
NearbyConnectionsService::DiscoveryListener discovery_listener_remote;
|
||||
testing::NiceMock<MockDiscoveryListener> discovery_listener;
|
||||
@@ -569,7 +564,6 @@ TEST_F(NearbyConnectionsManagerImplTest,
|
||||
}
|
||||
|
||||
TEST_F(NearbyConnectionsManagerImplTest, DisableWifiHotspotForHPRealtekDevice) {
|
||||
SetConnectionType(ConnectivityManager::ConnectionType::kWifi);
|
||||
fake_connectivity_manager_.SetIsHPRealtekDevice(true);
|
||||
|
||||
// StartDiscovery will succeed.
|
||||
@@ -611,7 +605,9 @@ TEST_F(NearbyConnectionsManagerImplTest, DisableWifiHotspotForHPRealtekDevice) {
|
||||
// Begin: NearbyConnectionsManagerImplTestConnectionMediums
|
||||
/******************************************************************************/
|
||||
using ConnectionMediumsTestParam =
|
||||
std::tuple<DataUsage, ConnectivityManager::ConnectionType, bool, bool>;
|
||||
std::tuple<DataUsage, /*is_webrtc_enabled=*/bool,
|
||||
/*is_wifilan_enabled=*/bool, /*is_lan_connected=*/bool,
|
||||
/*is_internet_connected=*/bool>;
|
||||
class NearbyConnectionsManagerImplTestConnectionMediums
|
||||
: public NearbyConnectionsManagerImplTest,
|
||||
public testing::WithParamInterface<ConnectionMediumsTestParam> {};
|
||||
@@ -620,9 +616,15 @@ TEST_P(NearbyConnectionsManagerImplTestConnectionMediums,
|
||||
RequestConnection_MediumSelection) {
|
||||
const ConnectionMediumsTestParam& param = GetParam();
|
||||
DataUsage data_usage = std::get<0>(param);
|
||||
ConnectivityManager::ConnectionType connection_type = std::get<1>(param);
|
||||
bool is_webrtc_enabled = std::get<2>(GetParam());
|
||||
bool is_wifilan_enabled = std::get<3>(GetParam());
|
||||
bool is_webrtc_enabled = std::get<1>(GetParam());
|
||||
bool is_wifilan_enabled = std::get<2>(GetParam());
|
||||
bool is_lan_connected = std::get<3>(GetParam());
|
||||
bool is_internet_connected = std::get<4>(GetParam());
|
||||
LOG(INFO) << "Test params: data_usage: " << static_cast<int>(data_usage)
|
||||
<< ", is_webrtc_enabled: " << is_webrtc_enabled
|
||||
<< ", is_wifilan_enabled: " << is_wifilan_enabled
|
||||
<< ", is_lan_connected: " << is_lan_connected
|
||||
<< ", is_internet_connected: " << is_internet_connected;
|
||||
|
||||
if (is_webrtc_enabled) {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
@@ -642,18 +644,13 @@ TEST_P(NearbyConnectionsManagerImplTestConnectionMediums,
|
||||
config_package_nearby::nearby_sharing_feature::kEnableMediumWifiLan,
|
||||
false);
|
||||
}
|
||||
SetConnectionStatus(is_lan_connected, is_internet_connected);
|
||||
|
||||
SetConnectionType(connection_type);
|
||||
bool should_use_internet =
|
||||
data_usage != DataUsage::OFFLINE_DATA_USAGE &&
|
||||
connection_type != ConnectivityManager::ConnectionType::kNone &&
|
||||
!(data_usage == DataUsage::WIFI_ONLY_DATA_USAGE &&
|
||||
connection_type != ConnectivityManager::ConnectionType::kWifi);
|
||||
bool is_connection_wifi_or_ethernet =
|
||||
connection_type == ConnectivityManager::ConnectionType::kWifi ||
|
||||
connection_type == ConnectivityManager::ConnectionType::kEthernet;
|
||||
is_internet_connected && data_usage != DataUsage::OFFLINE_DATA_USAGE &&
|
||||
!(data_usage == DataUsage::WIFI_ONLY_DATA_USAGE && !is_lan_connected);
|
||||
should_use_web_rtc_ = is_webrtc_enabled && should_use_internet;
|
||||
should_use_wifilan_ = is_wifilan_enabled && is_connection_wifi_or_ethernet;
|
||||
should_use_wifilan_ = is_wifilan_enabled && is_lan_connected;
|
||||
|
||||
MediumSelection expected_mediums(/*bluetooth=*/true,
|
||||
/*ble=*/false,
|
||||
@@ -707,10 +704,8 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
testing::Combine(testing::Values(DataUsage::WIFI_ONLY_DATA_USAGE,
|
||||
DataUsage::OFFLINE_DATA_USAGE,
|
||||
DataUsage::ONLINE_DATA_USAGE),
|
||||
testing::Values(ConnectivityManager::ConnectionType::kNone,
|
||||
ConnectivityManager::ConnectionType::kWifi,
|
||||
ConnectivityManager::ConnectionType::k3G),
|
||||
testing::Bool(), testing::Bool()));
|
||||
testing::Bool(), testing::Bool(), testing::Bool(),
|
||||
testing::Bool()));
|
||||
/******************************************************************************/
|
||||
// End: NearbyConnectionsManagerImplTestConnectionMediums
|
||||
/******************************************************************************/
|
||||
@@ -1413,10 +1408,10 @@ TEST_F(NearbyConnectionsManagerImplTest,
|
||||
InitializeTemporaryFile(file1);
|
||||
InitializeTemporaryFile(file2);
|
||||
|
||||
payload_listener_remote.payload_cb(
|
||||
kRemoteEndpointId, Payload(kPayloadId, InputFile(file1.ToString())));
|
||||
payload_listener_remote.payload_cb(
|
||||
kRemoteEndpointId, Payload(kPayloadId2, InputFile(file2.ToString())));
|
||||
payload_listener_remote.payload_cb(kRemoteEndpointId,
|
||||
Payload(kPayloadId, file1));
|
||||
payload_listener_remote.payload_cb(kRemoteEndpointId,
|
||||
Payload(kPayloadId2, file2));
|
||||
|
||||
const std::vector<uint8_t> byte_payload(std::begin(kBytePayload),
|
||||
std::end(kBytePayload));
|
||||
@@ -1527,7 +1522,7 @@ TEST_F(NearbyConnectionsManagerImplTest, IncomingFilePayload) {
|
||||
InitializeTemporaryFile(file);
|
||||
|
||||
payload_listener_remote.payload_cb(
|
||||
kRemoteEndpointId, Payload(kPayloadId, InputFile(file.ToString())));
|
||||
kRemoteEndpointId, Payload(kPayloadId, file));
|
||||
|
||||
absl::Notification payload_notification;
|
||||
EXPECT_CALL(*payload_listener, OnStatusUpdate(::testing::_)).WillOnce([&]() {
|
||||
@@ -1545,14 +1540,14 @@ TEST_F(NearbyConnectionsManagerImplTest, IncomingFilePayload) {
|
||||
nearby_connections_manager_->GetIncomingPayload(kPayloadId);
|
||||
ASSERT_NE(payload, nullptr);
|
||||
ASSERT_TRUE(payload->content.is_file());
|
||||
std::vector<uint8_t> payload_bytes(payload->content.file_payload.size);
|
||||
std::vector<uint8_t> payload_bytes(expected_payload.size());
|
||||
std::ifstream payload_stream(
|
||||
payload->content.file_payload.file.path.GetPath(),
|
||||
payload->content.file_payload.file_path.GetPath(),
|
||||
std::ios::in | std::ios::binary);
|
||||
ASSERT_TRUE(payload_stream.good());
|
||||
payload_stream.read(reinterpret_cast<char*>(payload_bytes.data()),
|
||||
payload->content.file_payload.size);
|
||||
ASSERT_EQ(payload_stream.gcount(), payload->content.file_payload.size);
|
||||
payload_bytes.size());
|
||||
ASSERT_EQ(payload_stream.gcount(), payload_bytes.size());
|
||||
payload_stream.close();
|
||||
EXPECT_EQ(payload_bytes, expected_payload);
|
||||
}
|
||||
@@ -1577,8 +1572,8 @@ TEST_F(NearbyConnectionsManagerImplTest, ClearIncomingPayloads) {
|
||||
FilePath file = Files::GetTemporaryDirectory().append(FilePath("file.jpg"));
|
||||
InitializeTemporaryFile(file);
|
||||
|
||||
payload_listener_remote.payload_cb(
|
||||
kRemoteEndpointId, Payload(kPayloadId, InputFile(file.ToString())));
|
||||
payload_listener_remote.payload_cb(kRemoteEndpointId,
|
||||
Payload(kPayloadId, file));
|
||||
|
||||
absl::Notification payload_notification;
|
||||
EXPECT_CALL(*payload_listener, OnStatusUpdate(::testing::_)).WillOnce([&]() {
|
||||
@@ -1602,8 +1597,9 @@ TEST_F(NearbyConnectionsManagerImplTest, ClearIncomingPayloads) {
|
||||
// Begin: NearbyConnectionsManagerImplTestMediums
|
||||
/******************************************************************************/
|
||||
using MediumsTestParam =
|
||||
std::tuple<PowerLevel, DataUsage, ConnectivityManager::ConnectionType, bool,
|
||||
bool>;
|
||||
std::tuple<PowerLevel, DataUsage, /*is_webrtc_enabled=*/bool,
|
||||
/*is_wifilan_enabled=*/bool, /*is_lan_connected=*/bool,
|
||||
/*is_internet_connected=*/bool>;
|
||||
class NearbyConnectionsManagerImplTestMediums
|
||||
: public NearbyConnectionsManagerImplTest,
|
||||
public testing::WithParamInterface<MediumsTestParam> {};
|
||||
@@ -1612,9 +1608,16 @@ TEST_P(NearbyConnectionsManagerImplTestMediums, StartAdvertising_Options) {
|
||||
const MediumsTestParam& param = GetParam();
|
||||
PowerLevel power_level = std::get<0>(param);
|
||||
DataUsage data_usage = std::get<1>(param);
|
||||
ConnectivityManager::ConnectionType connection_type = std::get<2>(param);
|
||||
bool is_webrtc_enabled = std::get<3>(GetParam());
|
||||
bool is_wifilan_enabled = std::get<4>(GetParam());
|
||||
bool is_webrtc_enabled = std::get<2>(GetParam());
|
||||
bool is_wifilan_enabled = std::get<3>(GetParam());
|
||||
bool is_lan_connected = std::get<4>(GetParam());
|
||||
bool is_internet_connected = std::get<5>(GetParam());
|
||||
LOG(INFO) << "Test params: power_level: " << static_cast<int>(power_level)
|
||||
<< ", data_usage: " << static_cast<int>(data_usage)
|
||||
<< ", is_webrtc_enabled: " << is_webrtc_enabled
|
||||
<< ", is_wifilan_enabled: " << is_wifilan_enabled
|
||||
<< ", is_lan_connected: " << is_lan_connected
|
||||
<< ", is_internet_connected: " << is_internet_connected;
|
||||
|
||||
if (is_webrtc_enabled) {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
@@ -1634,19 +1637,13 @@ TEST_P(NearbyConnectionsManagerImplTestMediums, StartAdvertising_Options) {
|
||||
config_package_nearby::nearby_sharing_feature::kEnableMediumWifiLan,
|
||||
false);
|
||||
}
|
||||
|
||||
SetConnectionType(connection_type);
|
||||
SetConnectionStatus(is_lan_connected, is_internet_connected);
|
||||
|
||||
bool should_use_internet =
|
||||
data_usage != DataUsage::OFFLINE_DATA_USAGE &&
|
||||
connection_type != ConnectivityManager::ConnectionType::kNone &&
|
||||
!(data_usage == DataUsage::WIFI_ONLY_DATA_USAGE &&
|
||||
connection_type != ConnectivityManager::ConnectionType::kWifi);
|
||||
bool is_connection_wifi_or_ethernet =
|
||||
connection_type == ConnectivityManager::ConnectionType::kWifi ||
|
||||
connection_type == ConnectivityManager::ConnectionType::kEthernet;
|
||||
is_internet_connected && data_usage != DataUsage::OFFLINE_DATA_USAGE &&
|
||||
!(data_usage == DataUsage::WIFI_ONLY_DATA_USAGE && !is_lan_connected);
|
||||
should_use_web_rtc_ = is_webrtc_enabled && should_use_internet;
|
||||
should_use_wifilan_ = is_wifilan_enabled & is_connection_wifi_or_ethernet;
|
||||
should_use_wifilan_ = is_wifilan_enabled && is_lan_connected;
|
||||
|
||||
bool is_high_power = power_level == PowerLevel::kHighPower;
|
||||
|
||||
@@ -1706,10 +1703,8 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
testing::Values(DataUsage::WIFI_ONLY_DATA_USAGE,
|
||||
DataUsage::OFFLINE_DATA_USAGE,
|
||||
DataUsage::ONLINE_DATA_USAGE),
|
||||
testing::Values(ConnectivityManager::ConnectionType::kNone,
|
||||
ConnectivityManager::ConnectionType::kWifi,
|
||||
ConnectivityManager::ConnectionType::k3G),
|
||||
testing::Bool(), testing::Bool()));
|
||||
testing::Bool(), testing::Bool(), testing::Bool(),
|
||||
testing::Bool()));
|
||||
|
||||
/******************************************************************************/
|
||||
// End: NearbyConnectionsManagerImplTestMediums
|
||||
@@ -1867,8 +1862,8 @@ TEST_F(NearbyConnectionsManagerImplTest,
|
||||
incoming_connection_listener,
|
||||
payload_listener_remote) != nullptr);
|
||||
FilePath file = Files::GetTemporaryDirectory().append(FilePath("file.jpg"));
|
||||
payload_listener_remote.payload_cb(
|
||||
kRemoteEndpointId, Payload(kPayloadId, InputFile(file.ToString())));
|
||||
payload_listener_remote.payload_cb(kRemoteEndpointId,
|
||||
Payload(kPayloadId, file));
|
||||
|
||||
nearby_connections_manager_->OnPayloadTransferUpdateForTesting(
|
||||
kRemoteEndpointId,
|
||||
@@ -1900,8 +1895,8 @@ TEST_F(NearbyConnectionsManagerImplTest, OnPayloadReceivedForUnknownFile) {
|
||||
incoming_connection_listener,
|
||||
payload_listener_remote) != nullptr);
|
||||
FilePath file = Files::GetTemporaryDirectory().append(FilePath("file.jpg"));
|
||||
payload_listener_remote.payload_cb(
|
||||
kRemoteEndpointId, Payload(kPayloadId, InputFile(file.ToString())));
|
||||
payload_listener_remote.payload_cb(kRemoteEndpointId,
|
||||
Payload(kPayloadId, file));
|
||||
|
||||
// Flag is on. Add unknown file paths with kCanceled to the list.
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
@@ -1909,12 +1904,12 @@ TEST_F(NearbyConnectionsManagerImplTest, OnPayloadReceivedForUnknownFile) {
|
||||
kDeleteUnexpectedReceivedFileFix,
|
||||
true);
|
||||
nearby_connections_manager_->ClearIncomingPayloads();
|
||||
Payload payload(kPayloadId, InputFile(file.ToString()));
|
||||
Payload payload(kPayloadId, file);
|
||||
nearby_connections_manager_->OnPayloadReceivedForTesting(kRemoteEndpointId,
|
||||
payload);
|
||||
|
||||
FilePath file2 = Files::GetTemporaryDirectory().append(FilePath("file2.jpg"));
|
||||
Payload payload2(kPayloadId, InputFile(file2.ToString()));
|
||||
Payload payload2(kPayloadId, file2);
|
||||
nearby_connections_manager_->OnPayloadReceivedForTesting(kRemoteEndpointId,
|
||||
payload2);
|
||||
auto unknown_file_paths =
|
||||
@@ -1927,7 +1922,7 @@ TEST_F(NearbyConnectionsManagerImplTest, OnPayloadReceivedForUnknownFile) {
|
||||
nearby_connections_manager_->RegisterPayloadStatusListener(
|
||||
kPayloadId, payload_listener->GetWeakPtr());
|
||||
FilePath file3 = Files::GetTemporaryDirectory().append(FilePath("file3.jpg"));
|
||||
Payload payload3(kPayloadId, InputFile(file3.ToString()));
|
||||
Payload payload3(kPayloadId, file3);
|
||||
nearby_connections_manager_->OnPayloadReceivedForTesting(kRemoteEndpointId,
|
||||
payload3);
|
||||
unknown_file_paths =
|
||||
@@ -1959,7 +1954,7 @@ TEST_F(NearbyConnectionsManagerImplTest,
|
||||
|
||||
FilePath file = Files::GetTemporaryDirectory().append(FilePath("file.jpg"));
|
||||
|
||||
Payload payload(kPayloadId, InputFile(file.ToString()));
|
||||
Payload payload(kPayloadId, file);
|
||||
nearby_connections_manager_->OnPayloadReceivedForTesting(kRemoteEndpointId,
|
||||
payload);
|
||||
|
||||
@@ -1989,7 +1984,7 @@ TEST_F(NearbyConnectionsManagerImplTest,
|
||||
});
|
||||
|
||||
FilePath file2 = Files::GetTemporaryDirectory().append(FilePath("file2.jpg"));
|
||||
Payload payload2(kPayloadId, InputFile(file2.ToString()));
|
||||
Payload payload2(kPayloadId, file2);
|
||||
nearby_connections_manager_->OnPayloadReceivedForTesting(kRemoteEndpointId,
|
||||
payload2);
|
||||
unknown_file_paths =
|
||||
|
||||
@@ -21,6 +21,13 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/payload_type.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "internal/base/file_path.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/file.h"
|
||||
#include "sharing/internal/public/logging.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
@@ -28,24 +35,31 @@
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
using ::nearby::connections::PayloadType;
|
||||
using ::nearby::connections::ResultCallback;
|
||||
|
||||
using NcPayload = ::nearby::connections::Payload;
|
||||
using NcStatus = ::nearby::connections::Status;
|
||||
using NcStrategy = ::nearby::connections::Strategy;
|
||||
|
||||
Status ConvertToStatus(NcStatus status) {
|
||||
return static_cast<Status>(status.value);
|
||||
}
|
||||
|
||||
Payload ConvertToPayload(NcPayload payload) {
|
||||
switch (payload.GetType()) {
|
||||
case NcPayloadType::kBytes: {
|
||||
const NcByteArray& bytes = payload.AsBytes();
|
||||
case PayloadType::kBytes: {
|
||||
const ByteArray& bytes = payload.AsBytes();
|
||||
std::string data = std::string(bytes);
|
||||
return Payload(payload.GetId(),
|
||||
std::vector<uint8_t>(data.begin(), data.end()));
|
||||
}
|
||||
case NcPayloadType::kFile: {
|
||||
case PayloadType::kFile: {
|
||||
std::string file_path = payload.AsFile()->GetFilePath();
|
||||
std::string parent_folder = payload.GetParentFolder();
|
||||
VLOG(1) << __func__ << ": Payload file_path=" << file_path
|
||||
<< ", parent_folder = " << parent_folder;
|
||||
return Payload(payload.GetId(), InputFile(file_path), parent_folder);
|
||||
return Payload(payload.GetId(), FilePath(file_path), parent_folder);
|
||||
}
|
||||
default:
|
||||
return Payload();
|
||||
@@ -55,15 +69,14 @@ Payload ConvertToPayload(NcPayload payload) {
|
||||
NcPayload ConvertToServicePayload(Payload payload) {
|
||||
switch (payload.content.type) {
|
||||
case PayloadContent::Type::kFile: {
|
||||
int64_t file_size = payload.content.file_payload.size;
|
||||
std::string file_path = payload.content.file_payload.file.path.ToString();
|
||||
std::string file_path = payload.content.file_payload.file_path.ToString();
|
||||
std::string file_name =
|
||||
payload.content.file_payload.file.path.GetFileName().ToString();
|
||||
payload.content.file_payload.file_path.GetFileName().ToString();
|
||||
std::string parent_folder = payload.content.file_payload.parent_folder;
|
||||
std::replace(parent_folder.begin(), parent_folder.end(), '\\', '/');
|
||||
VLOG(1) << __func__ << ": NC Payload file_path=" << file_path
|
||||
<< ", parent_folder = " << parent_folder;
|
||||
nearby::InputFile input_file(file_path, file_size);
|
||||
nearby::InputFile input_file(file_path);
|
||||
NcPayload nc_payload(payload.id, parent_folder, file_name,
|
||||
std::move(input_file));
|
||||
return nc_payload;
|
||||
@@ -71,16 +84,16 @@ NcPayload ConvertToServicePayload(Payload payload) {
|
||||
case PayloadContent::Type::kBytes: {
|
||||
std::vector<uint8_t> bytes = payload.content.bytes_payload.bytes;
|
||||
return NcPayload(payload.id,
|
||||
NcByteArray(std::string(bytes.begin(), bytes.end())));
|
||||
ByteArray(std::string(bytes.begin(), bytes.end())));
|
||||
}
|
||||
default:
|
||||
return NcPayload();
|
||||
}
|
||||
}
|
||||
|
||||
NcResultCallback BuildResultCallback(
|
||||
ResultCallback BuildResultCallback(
|
||||
std::function<void(Status status)> callback) {
|
||||
return NcResultCallback{[&, callback = std::move(callback)](NcStatus status) {
|
||||
return ResultCallback{[&, callback = std::move(callback)](NcStatus status) {
|
||||
callback(ConvertToStatus(status));
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -24,17 +24,8 @@
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/connection_options.h"
|
||||
#include "connections/core.h"
|
||||
#include "connections/discovery_options.h"
|
||||
#include "connections/implementation/service_controller_router.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/out_of_band_connection_metadata.h"
|
||||
#include "connections/params.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/payload_type.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "internal/platform/listeners.h"
|
||||
@@ -43,27 +34,6 @@
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
using Core = ::nearby::connections::Core;
|
||||
using ServiceControllerRouter = ::nearby::connections::ServiceControllerRouter;
|
||||
using NcAdvertisingOptions = ::nearby::connections::AdvertisingOptions;
|
||||
using NcByteArray = ::nearby::ByteArray;
|
||||
using NcConnectionOptions = ::nearby::connections::ConnectionOptions;
|
||||
using NcConnectionRequestInfo = ::nearby::connections::ConnectionRequestInfo;
|
||||
using NcConnectionResponseInfo = ::nearby::connections::ConnectionResponseInfo;
|
||||
using NcDistanceInfo = ::nearby::connections::DistanceInfo;
|
||||
using NcDiscoveryListener = ::nearby::connections::DiscoveryListener;
|
||||
using NcDiscoveryOptions = ::nearby::connections::DiscoveryOptions;
|
||||
using NcMedium = ::nearby::connections::Medium;
|
||||
using NcOutOfBandConnectionMetadata =
|
||||
::nearby::connections::OutOfBandConnectionMetadata;
|
||||
using NcPayload = ::nearby::connections::Payload;
|
||||
using NcPayloadType = ::nearby::connections::PayloadType;
|
||||
using NcPayloadListener = ::nearby::connections::PayloadListener;
|
||||
using NcPayloadProgressInfo = ::nearby::connections::PayloadProgressInfo;
|
||||
using NcResultCallback = ::nearby::connections::ResultCallback;
|
||||
using NcStatus = ::nearby::connections::Status;
|
||||
using NcStrategy = ::nearby::connections::Strategy;
|
||||
|
||||
// Main interface to control the NearbyConnections library. Implemented in a
|
||||
// sandboxed process. This interface is used by the browser process to connect
|
||||
// to remote devices and send / receive raw data packets. Parsing of those
|
||||
@@ -71,7 +41,6 @@ using NcStrategy = ::nearby::connections::Strategy;
|
||||
// separate interface.
|
||||
class NearbyConnectionsService {
|
||||
public:
|
||||
using HANDLE = void*;
|
||||
virtual ~NearbyConnectionsService() = default;
|
||||
|
||||
struct ConnectionListener {
|
||||
@@ -171,12 +140,12 @@ class NearbyConnectionsService {
|
||||
virtual std::string Dump() const = 0;
|
||||
};
|
||||
|
||||
Status ConvertToStatus(NcStatus status);
|
||||
Payload ConvertToPayload(NcPayload payload);
|
||||
NcPayload ConvertToServicePayload(Payload payload);
|
||||
NcResultCallback BuildResultCallback(
|
||||
Status ConvertToStatus(nearby::connections::Status status);
|
||||
Payload ConvertToPayload(nearby::connections::Payload payload);
|
||||
nearby::connections::Payload ConvertToServicePayload(Payload payload);
|
||||
nearby::connections::ResultCallback BuildResultCallback(
|
||||
std::function<void(Status status)> callback);
|
||||
NcStrategy ConvertToServiceStrategy(Strategy strategy);
|
||||
nearby::connections::Strategy ConvertToServiceStrategy(Strategy strategy);
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
|
||||
@@ -27,10 +27,20 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/connection_options.h"
|
||||
#include "connections/core.h"
|
||||
#include "connections/discovery_options.h"
|
||||
#include "connections/implementation/service_controller_router.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/params.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/payload_type.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "internal/analytics/event_logger.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/mac_address.h"
|
||||
#include "sharing/internal/public/connectivity_manager.h"
|
||||
@@ -41,7 +51,24 @@ namespace nearby {
|
||||
namespace sharing {
|
||||
namespace {
|
||||
|
||||
Core* GetService(NearbyConnectionsService::HANDLE handle) {
|
||||
using ::nearby::connections::ConnectionRequestInfo;
|
||||
using ::nearby::connections::ConnectionResponseInfo;
|
||||
using ::nearby::connections::Core;
|
||||
using ::nearby::connections::PayloadProgressInfo;
|
||||
using ::nearby::connections::PayloadType;
|
||||
using ::nearby::connections::ServiceControllerRouter;
|
||||
|
||||
using NcAdvertisingOptions = ::nearby::connections::AdvertisingOptions;
|
||||
using NcConnectionOptions = ::nearby::connections::ConnectionOptions;
|
||||
using NcDiscoveryListener = ::nearby::connections::DiscoveryListener;
|
||||
using NcDiscoveryOptions = ::nearby::connections::DiscoveryOptions;
|
||||
using NcDistanceInfo = ::nearby::connections::DistanceInfo;
|
||||
using NcMedium = ::nearby::connections::Medium;
|
||||
using NcPayload = ::nearby::connections::Payload;
|
||||
using NcPayloadListener = ::nearby::connections::PayloadListener;
|
||||
using NcStatus = ::nearby::connections::Status;
|
||||
|
||||
Core* GetService(NearbyConnectionsServiceImpl::HANDLE handle) {
|
||||
return reinterpret_cast<Core*>(handle);
|
||||
}
|
||||
|
||||
@@ -88,12 +115,12 @@ void NearbyConnectionsServiceImpl::StartAdvertising(
|
||||
options.fast_advertisement_service_uuid =
|
||||
advertising_options.fast_advertisement_service_uuid.uuid;
|
||||
|
||||
NcConnectionRequestInfo connection_request_info;
|
||||
ConnectionRequestInfo connection_request_info;
|
||||
connection_request_info.endpoint_info =
|
||||
NcByteArray(std::string(endpoint_info.begin(), endpoint_info.end()));
|
||||
ByteArray(std::string(endpoint_info.begin(), endpoint_info.end()));
|
||||
connection_request_info.listener.initiated_cb =
|
||||
[&](const std::string& endpoint_id,
|
||||
const NcConnectionResponseInfo& info) {
|
||||
const ConnectionResponseInfo& info) {
|
||||
ConnectionInfo connection_info;
|
||||
connection_info.authentication_token = info.authentication_token;
|
||||
std::string remote_end_point = std::string(info.remote_endpoint_info);
|
||||
@@ -166,7 +193,7 @@ void NearbyConnectionsServiceImpl::StartDiscovery(
|
||||
|
||||
NcDiscoveryListener listener;
|
||||
listener.endpoint_found_cb = [this](const std::string& endpoint_id,
|
||||
const NcByteArray& endpoint_info,
|
||||
const ByteArray& endpoint_info,
|
||||
const std::string& service_id) {
|
||||
std::string endpoint_info_data = std::string(endpoint_info);
|
||||
discovery_listener_.endpoint_found_cb(
|
||||
@@ -224,12 +251,12 @@ void NearbyConnectionsServiceImpl::RequestConnection(
|
||||
}
|
||||
options.non_disruptive_hotspot_mode =
|
||||
connection_options.non_disruptive_hotspot_mode;
|
||||
NcConnectionRequestInfo connection_request_info;
|
||||
ConnectionRequestInfo connection_request_info;
|
||||
connection_request_info.endpoint_info =
|
||||
NcByteArray(std::string(endpoint_info.begin(), endpoint_info.end()));
|
||||
ByteArray(std::string(endpoint_info.begin(), endpoint_info.end()));
|
||||
connection_request_info.listener.initiated_cb =
|
||||
[&](const std::string& endpoint_id,
|
||||
const NcConnectionResponseInfo& info) {
|
||||
const ConnectionResponseInfo& info) {
|
||||
ConnectionInfo connection_info;
|
||||
connection_info.authentication_token = info.authentication_token;
|
||||
std::string remote_end_point = std::string(info.remote_endpoint_info);
|
||||
@@ -312,8 +339,8 @@ void NearbyConnectionsServiceImpl::AcceptConnection(
|
||||
VLOG(1) << "payload callback id=" << payload.GetId();
|
||||
|
||||
switch (payload.GetType()) {
|
||||
case NcPayloadType::kBytes:
|
||||
case NcPayloadType::kFile:
|
||||
case PayloadType::kBytes:
|
||||
case PayloadType::kFile:
|
||||
payload_listener->second.payload_cb(
|
||||
endpoint_id, ConvertToPayload(std::move(payload)));
|
||||
break;
|
||||
@@ -324,7 +351,7 @@ void NearbyConnectionsServiceImpl::AcceptConnection(
|
||||
},
|
||||
.payload_progress_cb =
|
||||
[&](absl::string_view endpoint_id,
|
||||
const NcPayloadProgressInfo& info) {
|
||||
const PayloadProgressInfo& info) {
|
||||
PayloadTransferUpdate transfer_update;
|
||||
transfer_update.bytes_transferred = info.bytes_transferred;
|
||||
transfer_update.payload_id = info.payload_id;
|
||||
|
||||
@@ -35,6 +35,8 @@ namespace sharing {
|
||||
|
||||
class NearbyConnectionsServiceImpl : public NearbyConnectionsService {
|
||||
public:
|
||||
using HANDLE = void*;
|
||||
|
||||
explicit NearbyConnectionsServiceImpl(
|
||||
nearby::ConnectivityManager* connectivity_manager,
|
||||
nearby::analytics::EventLogger* event_logger = nullptr);
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "connections/payload.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/file.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
|
||||
@@ -25,15 +27,17 @@ namespace {
|
||||
|
||||
using ::testing::Eq;
|
||||
|
||||
using NcPayload = ::nearby::connections::Payload;
|
||||
|
||||
TEST(NearbyConnectionSharingServicePayloadTest, ConvertBytesToPayload) {
|
||||
Payload payload = ConvertToPayload(NcPayload(1234, NcByteArray("test")));
|
||||
Payload payload = ConvertToPayload(NcPayload(1234, ByteArray("test")));
|
||||
EXPECT_THAT(payload.id, Eq(1234LL));
|
||||
EXPECT_THAT(payload.content.type, Eq(PayloadContent::Type::kBytes));
|
||||
}
|
||||
|
||||
TEST(NearbyConnectionSharingServicePayloadTest, ConvertFileToPayload) {
|
||||
Payload payload = ConvertToPayload(
|
||||
NcPayload(1234, nearby::InputFile("/为甚么/tmp/test.txt", /*size=*/100)));
|
||||
NcPayload(1234, nearby::InputFile("/为甚么/tmp/test.txt")));
|
||||
EXPECT_THAT(payload.id, Eq(1234LL));
|
||||
EXPECT_THAT(payload.content.type, Eq(PayloadContent::Type::kFile));
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/base/file_path.h"
|
||||
#include "internal/base/files.h"
|
||||
#include "internal/interop/authentication_status.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -357,14 +356,6 @@ enum class DistanceInfo {
|
||||
kFar = 4,
|
||||
};
|
||||
|
||||
struct InputFile {
|
||||
InputFile() = default;
|
||||
explicit InputFile(absl::string_view file_path)
|
||||
: path(file_path) {}
|
||||
|
||||
FilePath path;
|
||||
};
|
||||
|
||||
// A simple payload containing raw bytes.
|
||||
struct BytesPayload {
|
||||
// The bytes of this payload.
|
||||
@@ -376,8 +367,7 @@ struct FilePayload {
|
||||
// The file to which this payload points to. When sending this payload, the
|
||||
// NearbyConnections library reads from this file. When receiving a file
|
||||
// payload it writes to this file.
|
||||
InputFile file;
|
||||
int64_t size;
|
||||
FilePath file_path;
|
||||
std::string parent_folder;
|
||||
};
|
||||
|
||||
@@ -410,35 +400,21 @@ struct Payload {
|
||||
explicit Payload(std::vector<uint8_t> bytes)
|
||||
: Payload(GenerateId(), std::move(bytes)) {}
|
||||
|
||||
explicit Payload(InputFile file,
|
||||
absl::string_view parent_folder = absl::string_view()) {
|
||||
id = std::hash<std::string>()(file.path.ToString());
|
||||
|
||||
content.type = PayloadContent::Type::kFile;
|
||||
std::optional<uintmax_t> size = Files::GetFileSize(file.path);
|
||||
if (size.has_value()) {
|
||||
content.file_payload.size = *size;
|
||||
}
|
||||
|
||||
content.file_payload.file = std::move(file);
|
||||
content.file_payload.parent_folder = std::string(parent_folder);
|
||||
}
|
||||
explicit Payload(FilePath file_path,
|
||||
absl::string_view parent_folder = absl::string_view())
|
||||
: Payload(std::hash<std::string>()(file_path.ToString()), file_path,
|
||||
parent_folder) {}
|
||||
|
||||
Payload(int64_t id, std::vector<uint8_t> bytes) : id(id) {
|
||||
content.type = PayloadContent::Type::kBytes;
|
||||
content.bytes_payload.bytes = std::move(bytes);
|
||||
}
|
||||
|
||||
Payload(int64_t id, InputFile file,
|
||||
Payload(int64_t id, FilePath file_path,
|
||||
absl::string_view parent_folder = absl::string_view())
|
||||
: id(id) {
|
||||
content.type = PayloadContent::Type::kFile;
|
||||
std::optional<uintmax_t> size = Files::GetFileSize(file.path);
|
||||
if (size.has_value()) {
|
||||
content.file_payload.size = *size;
|
||||
}
|
||||
|
||||
content.file_payload.file = std::move(file);
|
||||
content.file_payload.file_path = file_path;
|
||||
content.file_payload.parent_folder = std::string(parent_folder);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,20 +21,6 @@
|
||||
namespace nearby::sharing {
|
||||
using ::testing::Eq;
|
||||
|
||||
TEST(NearbyConnectionSharingTypesPayloadTest, FromInputFileUTF8) {
|
||||
InputFile input_file("/为甚么/tmp/test.txt");
|
||||
Payload payload(input_file);
|
||||
EXPECT_THAT(payload.id, Eq(7724502655048749887LL));
|
||||
EXPECT_THAT(payload.content.type, Eq(PayloadContent::Type::kFile));
|
||||
}
|
||||
|
||||
TEST(NearbyConnectionSharingTypesPayloadTest, FromInputFileWithId) {
|
||||
InputFile input_file("/为甚么/tmp/test.txt");
|
||||
Payload payload(1234, input_file);
|
||||
EXPECT_THAT(payload.id, Eq(1234LL));
|
||||
EXPECT_THAT(payload.content.type, Eq(PayloadContent::Type::kFile));
|
||||
}
|
||||
|
||||
TEST(NearbyConnectionSharingTypesPayloadTest, FromBytes) {
|
||||
Payload payload({1, 2, 3, 4, 5});
|
||||
EXPECT_THAT(payload.content.type, Eq(PayloadContent::Type::kBytes));
|
||||
|
||||
@@ -38,22 +38,6 @@ namespace {
|
||||
|
||||
using ::nearby::sharing::api::SharingPlatform;
|
||||
|
||||
// Called on the FileTaskRunner to actually open the files passed.
|
||||
std::vector<NearbyFileHandler::FileInfo> DoOpenFiles(
|
||||
absl::Span<const FilePath> file_paths) {
|
||||
std::vector<NearbyFileHandler::FileInfo> files;
|
||||
for (const auto& file_path : file_paths) {
|
||||
std::optional<uintmax_t> size = Files::GetFileSize(file_path);
|
||||
if (!size.has_value()) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": Failed to open file. File=" << file_path.ToString();
|
||||
return {};
|
||||
}
|
||||
files.push_back({*size, file_path});
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NearbyFileHandler::NearbyFileHandler(SharingPlatform& platform,
|
||||
@@ -68,15 +52,6 @@ NearbyFileHandler::NearbyFileHandler(SharingPlatform& platform,
|
||||
|
||||
NearbyFileHandler::~NearbyFileHandler() = default;
|
||||
|
||||
void NearbyFileHandler::OpenFiles(std::vector<FilePath> file_paths,
|
||||
OpenFilesCallback callback) {
|
||||
sequenced_task_runner_->PostTask(
|
||||
[callback = std::move(callback), file_paths = std::move(file_paths)]() {
|
||||
auto opened_files = DoOpenFiles(file_paths);
|
||||
callback(opened_files);
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyFileHandler::DeleteFilesFromDisk(
|
||||
std::vector<FilePath> file_paths, DeleteFilesFromDiskCallback callback) {
|
||||
sequenced_task_runner_->PostTask([callback = std::move(callback),
|
||||
|
||||
@@ -33,12 +33,6 @@ namespace sharing {
|
||||
// releasing files need to run on a MayBlock task runner.
|
||||
class NearbyFileHandler {
|
||||
public:
|
||||
struct FileInfo {
|
||||
uint64_t size;
|
||||
FilePath file_path;
|
||||
};
|
||||
|
||||
using OpenFilesCallback = std::function<void(std::vector<FileInfo>)>;
|
||||
using DeleteFilesFromDiskCallback = std::function<void()>;
|
||||
|
||||
// Pass in a TaskRunner to use for testing.
|
||||
@@ -46,10 +40,6 @@ class NearbyFileHandler {
|
||||
std::unique_ptr<TaskRunner> runner = nullptr);
|
||||
~NearbyFileHandler();
|
||||
|
||||
// Open the files given in |file_paths| and return the opened files sizes via
|
||||
// |callback|. If any file fails to open, return an empty list.
|
||||
void OpenFiles(std::vector<FilePath> file_paths, OpenFilesCallback callback);
|
||||
|
||||
void DeleteFilesFromDisk(std::vector<FilePath> file_paths,
|
||||
DeleteFilesFromDiskCallback callback);
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/base/file_path.h"
|
||||
#include "internal/base/files.h"
|
||||
@@ -46,27 +45,6 @@ bool CreateFile(FilePath& file_path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST(NearbyFileHandler, OpenFiles) {
|
||||
MockSharingPlatform mock_platform;
|
||||
NearbyFileHandler nearby_file_handler(mock_platform);
|
||||
absl::Notification notification;
|
||||
std::vector<NearbyFileHandler::FileInfo> result;
|
||||
FilePath test_file = Files::GetTemporaryDirectory().append(
|
||||
FilePath("nearby_nfh_test_abc.jpg"));
|
||||
|
||||
ASSERT_TRUE(CreateFile(test_file));
|
||||
nearby_file_handler.OpenFiles(
|
||||
{test_file}, [&result, ¬ification](
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos) {
|
||||
result = file_infos;
|
||||
notification.Notify();
|
||||
});
|
||||
|
||||
notification.WaitForNotificationWithTimeout(absl::Seconds(1));
|
||||
EXPECT_EQ(result.size(), 1);
|
||||
ASSERT_TRUE(Files::RemoveFile(test_file));
|
||||
}
|
||||
|
||||
TEST(NearbyFileHandler, DeleteAFileFromDisk) {
|
||||
MockSharingPlatform mock_platform;
|
||||
FakeClock clock;
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
|
||||
#include "sharing/nearby_sharing_service_factory.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "internal/analytics/event_logger.h"
|
||||
#include "internal/platform/task_runner.h"
|
||||
#include "sharing/analytics/analytics_recorder.h"
|
||||
#include "sharing/contacts/nearby_share_contact_manager_impl.h"
|
||||
#include "sharing/internal/api/sharing_platform.h"
|
||||
#include "sharing/internal/public/context_impl.h"
|
||||
#include "sharing/nearby_connections_manager_factory.h"
|
||||
@@ -54,9 +54,19 @@ NearbySharingService* NearbySharingServiceFactory::CreateSharingService(
|
||||
service_thread.get(), context_.get(),
|
||||
sharing_platform.GetDeviceInfo(), event_logger);
|
||||
|
||||
auto nearby_share_client_factory =
|
||||
sharing_platform.CreateSharingRpcClientFactory(context_->GetClock(),
|
||||
analytics_recorder);
|
||||
auto nearby_share_contact_manager =
|
||||
std::make_unique<NearbyShareContactManagerImpl>(
|
||||
context_.get(), sharing_platform.GetAccountManager(),
|
||||
nearby_share_client_factory.get());
|
||||
|
||||
nearby_sharing_service_ = std::make_unique<NearbySharingServiceImpl>(
|
||||
std::move(service_thread), context_.get(), sharing_platform,
|
||||
std::move(nearby_connections_manager), analytics_recorder);
|
||||
std::move(nearby_share_client_factory),
|
||||
std::move(nearby_connections_manager),
|
||||
std::move(nearby_share_contact_manager), analytics_recorder);
|
||||
|
||||
return nearby_sharing_service_.get();
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
#include "sharing/common/nearby_share_prefs.h"
|
||||
#include "sharing/constants.h"
|
||||
#include "sharing/contacts/nearby_share_contact_manager.h"
|
||||
#include "sharing/contacts/nearby_share_contact_manager_impl.h"
|
||||
#include "sharing/fast_initiation/nearby_fast_initiation.h"
|
||||
#include "sharing/fast_initiation/nearby_fast_initiation_impl.h"
|
||||
#include "sharing/file_attachment.h"
|
||||
@@ -72,6 +71,7 @@
|
||||
#include "sharing/incoming_share_session.h"
|
||||
#include "sharing/internal/api/bluetooth_adapter.h"
|
||||
#include "sharing/internal/api/sharing_platform.h"
|
||||
#include "sharing/internal/api/sharing_rpc_client.h"
|
||||
#include "sharing/internal/base/encode.h"
|
||||
#include "sharing/internal/public/connectivity_manager.h"
|
||||
#include "sharing/internal/public/context.h"
|
||||
@@ -107,10 +107,12 @@ namespace nearby::sharing {
|
||||
namespace {
|
||||
|
||||
using BlockedVendorId = ::nearby::sharing::Advertisement::BlockedVendorId;
|
||||
using ::absl::Milliseconds;
|
||||
using ::location::nearby::proto::sharing::OSType;
|
||||
using ::location::nearby::proto::sharing::ResponseToIntroduction;
|
||||
using ::location::nearby::proto::sharing::SessionStatus;
|
||||
using ::nearby::sharing::api::SharingPlatform;
|
||||
using ::nearby::sharing::api::SharingRpcClientFactory;
|
||||
using ::nearby::sharing::proto::DataUsage;
|
||||
using ::nearby::sharing::proto::DeviceVisibility;
|
||||
using ::nearby::sharing::service::proto::ConnectionResponseFrame;
|
||||
@@ -127,10 +129,6 @@ constexpr absl::Duration kProcessShutdownPendingTimerDelay = // NOLINT
|
||||
absl::Seconds(15);
|
||||
constexpr absl::Duration kProcessNetworkChangeTimerDelay = absl::Seconds(1);
|
||||
|
||||
// Cooldown period after a successful incoming share before we allow the "Device
|
||||
// nearby is sharing" notification to appear again.
|
||||
constexpr absl::Duration kFastInitiationScannerCooldown = absl::Seconds(8);
|
||||
|
||||
// The maximum number of certificate downloads that can be performed during a
|
||||
// discovery session.
|
||||
// Assuming a 2min discovery session and 10s download interval.
|
||||
@@ -206,12 +204,38 @@ std::string GenerateDeviceId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
std::string ReceiveSurfaceStateToString(
|
||||
NearbySharingService::ReceiveSurfaceState state) {
|
||||
switch (state) {
|
||||
case NearbySharingService::ReceiveSurfaceState::kForeground:
|
||||
return "FOREGROUND";
|
||||
case NearbySharingService::ReceiveSurfaceState::kBackground:
|
||||
return "BACKGROUND";
|
||||
case NearbySharingService::ReceiveSurfaceState::kUnknown:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
std::string SendSurfaceStateToString(
|
||||
NearbySharingService::SendSurfaceState state) {
|
||||
switch (state) {
|
||||
case NearbySharingService::SendSurfaceState::kForeground:
|
||||
return "FOREGROUND";
|
||||
case NearbySharingService::SendSurfaceState::kBackground:
|
||||
return "BACKGROUND";
|
||||
case NearbySharingService::SendSurfaceState::kUnknown:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NearbySharingServiceImpl::NearbySharingServiceImpl(
|
||||
std::unique_ptr<TaskRunner> service_thread, Context* context,
|
||||
SharingPlatform& sharing_platform,
|
||||
std::unique_ptr<SharingRpcClientFactory> nearby_share_client_factory,
|
||||
std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager,
|
||||
std::unique_ptr<NearbyShareContactManager> contact_manager,
|
||||
analytics::AnalyticsRecorder* analytics_recorder)
|
||||
: service_thread_(std::move(service_thread)),
|
||||
context_(context),
|
||||
@@ -220,14 +244,11 @@ NearbySharingServiceImpl::NearbySharingServiceImpl(
|
||||
account_manager_(sharing_platform.GetAccountManager()),
|
||||
analytics_recorder_(*analytics_recorder),
|
||||
nearby_connections_manager_(std::move(nearby_connections_manager)),
|
||||
nearby_share_client_factory_(
|
||||
sharing_platform.CreateSharingRpcClientFactory(context_->GetClock(),
|
||||
&analytics_recorder_)),
|
||||
nearby_share_client_factory_(std::move(nearby_share_client_factory)),
|
||||
local_device_data_manager_(
|
||||
NearbyShareLocalDeviceDataManagerImpl::Factory::Create(
|
||||
preference_manager_, account_manager_, device_info_)),
|
||||
contact_manager_(NearbyShareContactManagerImpl::Factory::Create(
|
||||
context_, account_manager_, nearby_share_client_factory_.get())),
|
||||
contact_manager_(std::move(contact_manager)),
|
||||
nearby_fast_initiation_(
|
||||
NearbyFastInitiationImpl::Factory::Create(context_)),
|
||||
settings_(std::make_unique<NearbyShareSettings>(
|
||||
@@ -239,9 +260,13 @@ NearbySharingServiceImpl::NearbySharingServiceImpl(
|
||||
outgoing_targets_manager_(
|
||||
context->GetClock(), service_thread_.get(),
|
||||
nearby_connections_manager_.get(), &analytics_recorder_,
|
||||
absl::bind_front(
|
||||
&NearbySharingServiceImpl::NotifyShareTargetDiscovered, this),
|
||||
absl::bind_front(&NearbySharingServiceImpl::NotifyShareTargetUpdated,
|
||||
this),
|
||||
absl::bind_front(&NearbySharingServiceImpl::NotifyShareTargetLost,
|
||||
this),
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnOutgoingTransferUpdate,
|
||||
this)) {
|
||||
CHECK(nearby_connections_manager_);
|
||||
CHECK(analytics_recorder);
|
||||
@@ -255,11 +280,8 @@ NearbySharingServiceImpl::NearbySharingServiceImpl(
|
||||
profile_path, nearby_share_client_factory_.get()),
|
||||
|
||||
certificate_manager_->AddObserver(this);
|
||||
context_->GetConnectivityManager()->RegisterConnectionListener(
|
||||
kConnectionListenerName,
|
||||
[this](nearby::ConnectivityManager::ConnectionType type,
|
||||
bool is_lan_connected, bool is_internet_connected) {
|
||||
OnNetworkChanged(type);
|
||||
context_->GetConnectivityManager()->RegisterLanListener(
|
||||
kConnectionListenerName, [this](bool is_lan_connected) {
|
||||
OnLanConnectedChanged(is_lan_connected);
|
||||
});
|
||||
|
||||
@@ -299,7 +321,6 @@ void NearbySharingServiceImpl::Shutdown(
|
||||
service_observers_.Clear();
|
||||
|
||||
StopAdvertising();
|
||||
StopFastInitiationScanning();
|
||||
StopFastInitiationAdvertising();
|
||||
StopScanning();
|
||||
nearby_connections_manager_->Shutdown();
|
||||
@@ -308,7 +329,7 @@ void NearbySharingServiceImpl::Shutdown(
|
||||
|
||||
certificate_manager_->RemoveObserver(this);
|
||||
account_manager_.RemoveObserver(this);
|
||||
context_->GetConnectivityManager()->UnregisterConnectionListener(
|
||||
context_->GetConnectivityManager()->UnregisterLanListener(
|
||||
kConnectionListenerName);
|
||||
context_->GetBluetoothAdapter().RemoveObserver(this);
|
||||
nearby_fast_initiation_->RemoveObserver(this);
|
||||
@@ -482,7 +503,7 @@ void NearbySharingServiceImpl::RegisterSendSurface(
|
||||
// request comes from a surface with the blocked vendor ID.
|
||||
wrapped_callback.OnShareTargetDiscovered(share_target);
|
||||
transfer_callback->OnTransferUpdate(
|
||||
share_target, attachment_container, transfer_metadata);
|
||||
share_target, *attachment_container, transfer_metadata);
|
||||
}
|
||||
|
||||
// Sync down data from Nearby server when the sending flow starts,
|
||||
@@ -594,7 +615,7 @@ void NearbySharingServiceImpl::RegisterReceiveSurface(
|
||||
auto& [share_target, attachment_container, transfer_metadata] =
|
||||
*last_incoming_metadata_;
|
||||
transfer_callback->OnTransferUpdate(
|
||||
share_target, attachment_container, transfer_metadata);
|
||||
share_target, *attachment_container, transfer_metadata);
|
||||
}
|
||||
|
||||
GetReceiveCallbacksMapFromState(state).insert(
|
||||
@@ -716,7 +737,7 @@ void NearbySharingServiceImpl::SendAttachments(
|
||||
CreateEndpointInfo(DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS,
|
||||
local_device_data_manager_->GetDeviceName());
|
||||
if (!endpoint_info) {
|
||||
LOG(WARNING) << "Could not create local endpoint info.";
|
||||
LOG(WARNING) << "Could not create local endpoint info.";
|
||||
std::move(status_codes_callback)(StatusCodes::kError);
|
||||
return;
|
||||
}
|
||||
@@ -729,31 +750,30 @@ void NearbySharingServiceImpl::SendAttachments(
|
||||
return;
|
||||
}
|
||||
|
||||
session->InitiateSendAttachments(std::move(attachment_container));
|
||||
|
||||
app_info_->SetActiveFlag();
|
||||
|
||||
OnTransferStarted(/*is_incoming=*/false);
|
||||
is_connecting_ = true;
|
||||
InvalidateSendSurfaceState();
|
||||
|
||||
// Send process initialized successfully, from now on status updated
|
||||
// will be sent out via OnOutgoingTransferUpdate().
|
||||
session->UpdateTransferMetadata(
|
||||
TransferMetadataBuilder()
|
||||
.set_status(TransferMetadata::Status::kConnecting)
|
||||
.build());
|
||||
|
||||
CreatePayloads(
|
||||
*session, [this, endpoint_info = std::move(*endpoint_info)](
|
||||
OutgoingShareSession& session, bool success) {
|
||||
OnCreatePayloads(std::move(endpoint_info), session, success);
|
||||
});
|
||||
|
||||
if (session->InitiateSendAttachments(
|
||||
std::move(attachment_container))) {
|
||||
OutgoingSessionConnect(*session, std::move(*endpoint_info));
|
||||
}
|
||||
std::move(status_codes_callback)(StatusCodes::kOk);
|
||||
});
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OutgoingSessionConnect(
|
||||
OutgoingShareSession& session, std::vector<uint8_t> endpoint_info) {
|
||||
OnTransferStarted(/*is_incoming=*/false);
|
||||
is_connecting_ = true;
|
||||
InvalidateSendSurfaceState();
|
||||
|
||||
int64_t share_target_id = session.share_target().id;
|
||||
session.Connect(
|
||||
std::move(endpoint_info), settings_->GetDataUsage(),
|
||||
GetDisableWifiHotspotState(),
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnOutgoingConnection, this,
|
||||
share_target_id));
|
||||
}
|
||||
|
||||
bool NearbySharingServiceImpl::OutgoingSessionAccept(
|
||||
OutgoingShareSession& session) {
|
||||
return session.AcceptTransfer(
|
||||
@@ -1040,15 +1060,23 @@ NearbySharingServiceImpl::InternalUnregisterSendSurface(
|
||||
*last_outgoing_metadata_;
|
||||
for (auto& background_transfer_callback : background_send_surface_map_) {
|
||||
background_transfer_callback.first->OnTransferUpdate(
|
||||
share_target, attachment_container, transfer_metadata);
|
||||
share_target, *attachment_container, transfer_metadata);
|
||||
}
|
||||
}
|
||||
if (foreground_send_surface_map_.empty() &&
|
||||
background_send_surface_map_.empty()) {
|
||||
LOG(INFO) << __func__ << ": Last send surface has been unregistered";
|
||||
// Clear outgoing_share_targets, outgoing_share_sessions and
|
||||
// discovery_cache.
|
||||
outgoing_targets_manager_.Cleanup();
|
||||
if (foreground_send_surface_map_.empty()) {
|
||||
if (background_send_surface_map_.empty()) {
|
||||
LOG(INFO) << __func__ << ": Last send surface has been unregistered";
|
||||
// Clear outgoing_share_targets, outgoing_share_sessions and
|
||||
// discovery_cache.
|
||||
outgoing_targets_manager_.Cleanup();
|
||||
} else {
|
||||
LOG(INFO) << __func__
|
||||
<< ": All foreground send surface has been unregistered";
|
||||
outgoing_targets_manager_.AllTargetsLost(
|
||||
Milliseconds(NearbyFlags::GetInstance().GetInt64Flag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
kUnregisterTargetDiscoveryCacheLostExpiryMs)));
|
||||
}
|
||||
}
|
||||
|
||||
VLOG(1) << __func__ << ": A SendSurface has been unregistered: "
|
||||
@@ -1098,7 +1126,7 @@ NearbySharingServiceImpl::InternalUnregisterReceiveSurface(
|
||||
*last_incoming_metadata_;
|
||||
for (auto& background_callback : background_receive_callbacks_map_) {
|
||||
background_callback.first->OnTransferUpdate(
|
||||
share_target, attachment_container, transfer_metadata);
|
||||
share_target, *attachment_container, transfer_metadata);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1162,12 +1190,11 @@ std::string NearbySharingServiceImpl::Dump() const {
|
||||
preference_manager_,
|
||||
PrefNames::kSchedulerDownloadPublicCertificates)
|
||||
<< std::endl;
|
||||
sstream
|
||||
<< " Upload local device certificates: "
|
||||
<< ConvertToReadableSchedule(
|
||||
preference_manager_,
|
||||
PrefNames::kSchedulerUploadLocalDeviceCertificates)
|
||||
<< std::endl;
|
||||
sstream << " Upload local device certificates: "
|
||||
<< ConvertToReadableSchedule(
|
||||
preference_manager_,
|
||||
PrefNames::kSchedulerUploadLocalDeviceCertificates)
|
||||
<< std::endl;
|
||||
sstream << " Private certificates expiration: "
|
||||
<< ConvertToReadableSchedule(
|
||||
preference_manager_,
|
||||
@@ -1328,26 +1355,30 @@ void NearbySharingServiceImpl::OnLockStateChanged(bool locked) {
|
||||
|
||||
void NearbySharingServiceImpl::AdapterPresentChanged(
|
||||
sharing::api::BluetoothAdapter* adapter, bool present) {
|
||||
RunOnNearbySharingServiceThread(
|
||||
"bt_adapter_present_changed", [this, adapter, present]() {
|
||||
VLOG(1) << "Bluetooth adapter present state changed. (" << present
|
||||
<< ")";
|
||||
NearbySharingService::Observer::AdapterState state =
|
||||
MapAdapterState(present, adapter->IsPowered());
|
||||
service_observers_.NotifyBluetoothStatusChanged(state);
|
||||
InvalidateSurfaceState();
|
||||
});
|
||||
RunOnNearbySharingServiceThread("bt_adapter_present_changed", [this, adapter,
|
||||
present]() {
|
||||
VLOG(1) << "Bluetooth adapter present state changed. (" << present << ")";
|
||||
NearbySharingService::Observer::AdapterState state =
|
||||
MapAdapterState(present, adapter->IsPowered());
|
||||
service_observers_.NotifyBluetoothStatusChanged(state);
|
||||
});
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::AdapterPoweredChanged(
|
||||
sharing::api::BluetoothAdapter* adapter, bool powered) {
|
||||
RunOnNearbySharingServiceThread(
|
||||
"bt_adapter_power_changed", [this, adapter, powered]() {
|
||||
// When adpater is powered on, it takes some time for the RFCOMM service to
|
||||
// be ready. If we don't wait the RfCommServiceProvider::CreateAsync() call
|
||||
// fails with a "device is not ready for use" error.
|
||||
// Waiting 500ms seems to be enough to allow it to reliably work.
|
||||
// Should investigate if there is a better events to listen to.
|
||||
RunOnNearbySharingServiceThreadDelayed(
|
||||
"bt_adapter_power_changed", absl::Milliseconds(500),
|
||||
[this, adapter, powered]() {
|
||||
VLOG(1) << "Bluetooth adapter power state changed. (" << powered << ")";
|
||||
NearbySharingService::Observer::AdapterState state =
|
||||
MapAdapterState(adapter->IsPresent(), powered);
|
||||
service_observers_.NotifyBluetoothStatusChanged(state);
|
||||
InvalidateSurfaceState();
|
||||
StopAdvertisingAndInvalidateSurfaceState();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1608,10 +1639,11 @@ void NearbySharingServiceImpl::HandleEndpointLost(
|
||||
|
||||
discovered_advertisements_to_retry_map_.erase(endpoint_id);
|
||||
discovered_advertisements_retried_set_.erase(endpoint_id);
|
||||
outgoing_targets_manager_.MoveToDiscoveryCache(std::string(endpoint_id),
|
||||
NearbyFlags::GetInstance().GetInt64Flag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
kDiscoveryCacheLostExpiryMs));
|
||||
outgoing_targets_manager_.OnShareTargetLost(
|
||||
std::string(endpoint_id),
|
||||
Milliseconds(NearbyFlags::GetInstance().GetInt64Flag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
kDiscoveryCacheLostExpiryMs)));
|
||||
FinishEndpointDiscoveryEvent();
|
||||
}
|
||||
|
||||
@@ -1703,53 +1735,8 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate(
|
||||
return;
|
||||
}
|
||||
LogShareTargetDiscovered(*share_target);
|
||||
if (outgoing_targets_manager_.FindDuplicateInOutgoingShareTargets(
|
||||
endpoint_id, *share_target)) {
|
||||
outgoing_targets_manager_.DeduplicateInOutgoingShareTarget(
|
||||
*share_target, endpoint_id, std::move(certificate));
|
||||
FinishEndpointDiscoveryEvent();
|
||||
return;
|
||||
}
|
||||
bool in_discovery_cache =
|
||||
outgoing_targets_manager_.FindDuplicateInDiscoveryCache(endpoint_id,
|
||||
*share_target);
|
||||
VLOG(1) << __func__ << ": Adding (endpoint_id=" << endpoint_id
|
||||
<< ", share_target_id=" << share_target->id
|
||||
<< ") to outgoing share target map";
|
||||
outgoing_targets_manager_.CreateOutgoingShareSession(
|
||||
*share_target, endpoint_id, std::move(certificate),
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnOutgoingTransferUpdate,
|
||||
this));
|
||||
if (in_discovery_cache) {
|
||||
NotifyShareTargetUpdated(*share_target);
|
||||
|
||||
LOG(INFO)
|
||||
<< __func__
|
||||
<< ": [Dedupped] Reported NotifyShareTargetUpdated to all surfaces "
|
||||
"for share_target: "
|
||||
<< share_target->ToString();
|
||||
FinishEndpointDiscoveryEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the endpoint id for the share target.
|
||||
LOG(INFO) << __func__ << ": An endpoint: " << endpoint_id
|
||||
<< " has been discovered, with an advertisement "
|
||||
"containing a valid share target with id: "
|
||||
<< share_target->id;
|
||||
|
||||
// Notifies the user that we discovered a device.
|
||||
VLOG(1) << __func__ << ": There are "
|
||||
<< (foreground_send_surface_map_.size() +
|
||||
background_send_surface_map_.size())
|
||||
<< " discovery callbacks be called.";
|
||||
|
||||
NotifyShareTargetDiscovered(*share_target);
|
||||
|
||||
VLOG(1) << __func__ << ": NotifyShareTargetDiscovered: share_target: "
|
||||
<< share_target->ToString() << " endpoint_id=" << endpoint_id
|
||||
<< " to all send surfaces.";
|
||||
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(*share_target, endpoint_id,
|
||||
std::move(certificate));
|
||||
FinishEndpointDiscoveryEvent();
|
||||
}
|
||||
|
||||
@@ -1807,14 +1794,9 @@ bool NearbySharingServiceImpl::HasAvailableConnectionMediums() {
|
||||
bool is_wifi_lan_enabled = NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_sharing_feature::kEnableMediumWifiLan);
|
||||
|
||||
ConnectivityManager::ConnectionType connection_type =
|
||||
context_->GetConnectivityManager()->GetConnectionType();
|
||||
|
||||
bool hasNetworkConnection =
|
||||
connection_type == ConnectivityManager::ConnectionType::kWifi ||
|
||||
connection_type == ConnectivityManager::ConnectionType::kEthernet;
|
||||
|
||||
return IsBluetoothPowered() || (is_wifi_lan_enabled && hasNetworkConnection);
|
||||
return IsBluetoothPowered() ||
|
||||
(is_wifi_lan_enabled &&
|
||||
context_->GetConnectivityManager()->IsLanConnected());
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::InvalidateSurfaceState() {
|
||||
@@ -1905,7 +1887,6 @@ void NearbySharingServiceImpl::InvalidateFastInitiationAdvertising() {
|
||||
|
||||
void NearbySharingServiceImpl::InvalidateReceiveSurfaceState() {
|
||||
InvalidateAdvertisingState();
|
||||
InvalidateFastInitiationScanning();
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::InvalidateAdvertisingState() {
|
||||
@@ -2006,8 +1987,7 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() {
|
||||
*endpoint_info,
|
||||
/*listener=*/this, power_level, data_usage,
|
||||
visibility == DeviceVisibility::DEVICE_VISIBILITY_EVERYONE,
|
||||
force_new_endpoint_id_,
|
||||
[this, visibility, data_usage](Status status) {
|
||||
force_new_endpoint_id_, [this, visibility, data_usage](Status status) {
|
||||
// Log analytics event of advertising start.
|
||||
analytics_recorder_.NewAdvertiseDevicePresenceStart(
|
||||
advertising_session_id_, visibility,
|
||||
@@ -2070,7 +2050,10 @@ void NearbySharingServiceImpl::StartScanning() {
|
||||
is_scanning_ = true;
|
||||
InvalidateReceiveSurfaceState();
|
||||
|
||||
outgoing_targets_manager_.DisableAllOutgoingShareTargets();
|
||||
outgoing_targets_manager_.AllTargetsLost(
|
||||
Milliseconds(NearbyFlags::GetInstance().GetInt64Flag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
kUnregisterTargetDiscoveryCacheLostExpiryMs)));
|
||||
discovered_advertisements_to_retry_map_.clear();
|
||||
discovered_advertisements_retried_set_.clear();
|
||||
|
||||
@@ -2131,102 +2114,6 @@ void NearbySharingServiceImpl::StopAdvertisingAndInvalidateSurfaceState() {
|
||||
InvalidateSurfaceState();
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::InvalidateFastInitiationScanning() {
|
||||
bool is_hardware_offloading_supported =
|
||||
IsBluetoothPresent() && nearby_fast_initiation_->IsScanOffloadSupported();
|
||||
|
||||
// Hardware offloading support is computed when the bluetooth adapter becomes
|
||||
// available. We set the hardware supported state on |settings_| to notify the
|
||||
// UI of state changes. InvalidateFastInitiationScanning gets triggered on
|
||||
// adapter change events.
|
||||
settings_->SetIsFastInitiationHardwareSupported(
|
||||
is_hardware_offloading_supported);
|
||||
|
||||
if (fast_initiation_scanner_cooldown_timer_ &&
|
||||
fast_initiation_scanner_cooldown_timer_->IsRunning()) {
|
||||
VLOG(1) << __func__
|
||||
<< ": Stopping background scanning due to post-transfer "
|
||||
"cooldown period";
|
||||
StopFastInitiationScanning();
|
||||
return;
|
||||
}
|
||||
|
||||
// Screen is off. Do no work.
|
||||
if (is_screen_locked_) {
|
||||
VLOG(1) << __func__
|
||||
<< ": Stopping background scanning because the screen is locked.";
|
||||
StopFastInitiationScanning();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsBluetoothPowered()) {
|
||||
VLOG(1)
|
||||
<< __func__
|
||||
<< ": Stopping background scanning because bluetooth is powered down.";
|
||||
StopFastInitiationScanning();
|
||||
return;
|
||||
}
|
||||
|
||||
// We're scanning for other nearby devices. Don't background scan.
|
||||
if (is_scanning_) {
|
||||
VLOG(1) << __func__
|
||||
<< ": Stopping background scanning because we're scanning "
|
||||
"for other devices.";
|
||||
StopFastInitiationScanning();
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_transferring_) {
|
||||
VLOG(1) << __func__
|
||||
<< ": Stopping background scanning because we're currently "
|
||||
"in the midst of a transfer.";
|
||||
StopFastInitiationScanning();
|
||||
return;
|
||||
}
|
||||
|
||||
if (advertising_power_level_ == PowerLevel::kHighPower) {
|
||||
VLOG(1) << __func__
|
||||
<< ": Stopping background scanning because we're already "
|
||||
"in high visibility mode.";
|
||||
StopFastInitiationScanning();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_hardware_offloading_supported) {
|
||||
VLOG(1) << __func__
|
||||
<< ": Stopping background scanning because hardware "
|
||||
"support is not available or not ready.";
|
||||
StopFastInitiationScanning();
|
||||
return;
|
||||
}
|
||||
|
||||
StartFastInitiationScanning();
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::StartFastInitiationScanning() {
|
||||
VLOG(1) << __func__ << ": Starting background scanning.";
|
||||
|
||||
if (nearby_fast_initiation_->IsScanning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nearby_fast_initiation_->StartScanning(
|
||||
/*devices_discovered_callback=*/[]() {},
|
||||
/*devices_not_discovered_callback=*/[]() {},
|
||||
[this]() { StopFastInitiationScanning(); });
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::StopFastInitiationScanning() {
|
||||
VLOG(1) << __func__ << ": Stop fast initiation scanning.";
|
||||
if (!nearby_fast_initiation_->IsScanning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nearby_fast_initiation_->StopScanning(
|
||||
[]() { VLOG(1) << __func__ << ": Stopped fast initiation scanning."; });
|
||||
VLOG(1) << __func__ << ": Stopped background scanning.";
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::ScheduleRotateBackgroundAdvertisementTimer() {
|
||||
absl::BitGen bitgen;
|
||||
uint64_t delayMilliseconds = absl::Uniform(
|
||||
@@ -2308,70 +2195,6 @@ void NearbySharingServiceImpl::OnOutgoingConnection(
|
||||
}
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::CreatePayloads(
|
||||
OutgoingShareSession& session,
|
||||
std::function<void(OutgoingShareSession&, bool)> callback) {
|
||||
int64_t share_target_id = session.share_target().id;
|
||||
if (!session.file_payloads().empty() || !session.text_payloads().empty() ||
|
||||
!session.wifi_credentials_payloads().empty()) {
|
||||
// We may have already created the payloads in the case of retry, so we can
|
||||
// skip this step.
|
||||
std::move(callback)(session, /*success=*/false);
|
||||
return;
|
||||
}
|
||||
session.CreateTextPayloads();
|
||||
session.CreateWifiCredentialsPayloads();
|
||||
file_handler_.OpenFiles(
|
||||
session.GetFilePaths(),
|
||||
[this, share_target_id, callback = std::move(callback)](
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos) {
|
||||
RunOnNearbySharingServiceThread(
|
||||
"open_files",
|
||||
[this, share_target_id, callback = std::move(callback),
|
||||
file_infos = std::move(file_infos)]() {
|
||||
OutgoingShareSession* session =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(
|
||||
share_target_id);
|
||||
if (session == nullptr) {
|
||||
return;
|
||||
}
|
||||
bool result = session->CreateFilePayloads(file_infos);
|
||||
std::move(callback)(*session, result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnCreatePayloads(
|
||||
std::vector<uint8_t> endpoint_info, OutgoingShareSession& session,
|
||||
bool success) {
|
||||
bool has_payloads = !session.text_payloads().empty() ||
|
||||
!session.file_payloads().empty() ||
|
||||
!session.wifi_credentials_payloads().empty();
|
||||
if (!success || !has_payloads) {
|
||||
LOG(WARNING) << __func__
|
||||
<< ": Failed to send file to remote ShareTarget. Failed to "
|
||||
"create payloads.";
|
||||
session.UpdateTransferMetadata(
|
||||
TransferMetadataBuilder()
|
||||
.set_status(TransferMetadata::Status::kMediaUnavailable)
|
||||
.build());
|
||||
return;
|
||||
}
|
||||
// Log analytics event of describing attachments.
|
||||
analytics_recorder_.NewDescribeAttachments(session.attachment_container());
|
||||
|
||||
std::optional<std::vector<uint8_t>> bluetooth_mac_address =
|
||||
GetBluetoothMacAddressForShareTarget(session);
|
||||
|
||||
int64_t share_target_id = session.share_target().id;
|
||||
|
||||
session.Connect(
|
||||
std::move(endpoint_info), std::move(bluetooth_mac_address),
|
||||
settings_->GetDataUsage(), GetDisableWifiHotspotState(),
|
||||
absl::bind_front(&NearbySharingServiceImpl::OnOutgoingConnection, this,
|
||||
share_target_id));
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::Fail(IncomingShareSession& session,
|
||||
TransferMetadata::Status status) {
|
||||
RunOnNearbySharingServiceThreadDelayed(
|
||||
@@ -2432,11 +2255,16 @@ void NearbySharingServiceImpl::OnIncomingTransferUpdate(
|
||||
}
|
||||
if (metadata.status() != TransferMetadata::Status::kCancelled &&
|
||||
metadata.status() != TransferMetadata::Status::kRejected) {
|
||||
last_incoming_metadata_ =
|
||||
std::make_tuple(session.share_target(), session.attachment_container(),
|
||||
TransferMetadataBuilder::Clone(metadata)
|
||||
.set_is_original(false)
|
||||
.build());
|
||||
last_incoming_metadata_ = std::make_tuple(
|
||||
session.share_target(),
|
||||
AttachmentContainer::Builder(
|
||||
session.attachment_container().GetTextAttachments(),
|
||||
session.attachment_container().GetFileAttachments(),
|
||||
session.attachment_container().GetWifiCredentialsAttachments())
|
||||
.Build(),
|
||||
TransferMetadataBuilder::Clone(metadata)
|
||||
.set_is_original(false)
|
||||
.build());
|
||||
} else {
|
||||
last_incoming_metadata_ = std::nullopt;
|
||||
}
|
||||
@@ -2524,11 +2352,16 @@ void NearbySharingServiceImpl::OnOutgoingTransferUpdate(
|
||||
if (has_foreground_send_surface && metadata.is_final_status()) {
|
||||
last_outgoing_metadata_ = std::nullopt;
|
||||
} else {
|
||||
last_outgoing_metadata_ =
|
||||
std::make_tuple(session.share_target(), session.attachment_container(),
|
||||
TransferMetadataBuilder::Clone(metadata)
|
||||
.set_is_original(false)
|
||||
.build());
|
||||
last_outgoing_metadata_ = std::make_tuple(
|
||||
session.share_target(),
|
||||
AttachmentContainer::Builder(
|
||||
session.attachment_container().GetTextAttachments(),
|
||||
session.attachment_container().GetFileAttachments(),
|
||||
session.attachment_container().GetWifiCredentialsAttachments())
|
||||
.Build(),
|
||||
TransferMetadataBuilder::Clone(metadata)
|
||||
.set_is_original(false)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2646,20 +2479,12 @@ void NearbySharingServiceImpl::OnOutgoingConnectionKeyVerificationDone(
|
||||
return;
|
||||
}
|
||||
// Auto Accept if key verification is successful or skip sender confirmation.
|
||||
bool be_advanced_protection_enabled =
|
||||
bool protection_enabled =
|
||||
preference_manager_.GetBoolean(PrefNames::kAdvancedProtectionEnabled,
|
||||
/*default_value=*/false);
|
||||
bool mendel_advanced_protection_enabled =
|
||||
!NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
kSenderSkipsConfirmation);
|
||||
bool advanced_protection_mismatch =
|
||||
(be_advanced_protection_enabled != mendel_advanced_protection_enabled);
|
||||
// Continue to use mendel flag until we have confidence that the Nearby BE
|
||||
// flag has the same value.
|
||||
session->SetAdvancedProtectionStatus(mendel_advanced_protection_enabled,
|
||||
advanced_protection_mismatch);
|
||||
if (session->token().empty() || !mendel_advanced_protection_enabled) {
|
||||
session->SetAdvancedProtectionStatus(protection_enabled,
|
||||
/*advanced_protection_mismatch=*/false);
|
||||
if (session->token().empty() || !protection_enabled) {
|
||||
// Auto accept if no token or if advanced protection is disabled.
|
||||
OutgoingSessionAccept(*session);
|
||||
} else {
|
||||
@@ -2931,12 +2756,6 @@ void NearbySharingServiceImpl::OnIncomingFilesMetadataUpdated(
|
||||
// ShareTarget already disconnected.
|
||||
return;
|
||||
}
|
||||
fast_initiation_scanner_cooldown_timer_ = std::make_unique<ThreadTimer>(
|
||||
*service_thread_, "fast_initiation_scanner_cooldown_timer",
|
||||
kFastInitiationScannerCooldown, [this]() {
|
||||
fast_initiation_scanner_cooldown_timer_.reset();
|
||||
InvalidateFastInitiationScanning();
|
||||
});
|
||||
// Make sure to call this before calling Disconnect, or we risk losing
|
||||
// some transfer updates in the receive case due to the Disconnect call
|
||||
// cleaning up share targets.
|
||||
@@ -3054,20 +2873,6 @@ IncomingShareSession* NearbySharingServiceImpl::GetIncomingShareSession(
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
std::optional<std::vector<uint8_t>>
|
||||
NearbySharingServiceImpl::GetBluetoothMacAddressForShareTarget(
|
||||
OutgoingShareSession& session) {
|
||||
const std::optional<NearbyShareDecryptedPublicCertificate>& certificate =
|
||||
session.certificate();
|
||||
if (!certificate) {
|
||||
LOG(ERROR) << __func__ << ": No decrypted public certificate found for "
|
||||
<< "share target id: " << session.share_target().id;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return GetBluetoothMacAddressFromCertificate(*certificate);
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::UnregisterShareTarget(int64_t share_target_id) {
|
||||
LOG(INFO) << __func__ << ": Unregister share target " << share_target_id;
|
||||
|
||||
@@ -3093,21 +2898,20 @@ void NearbySharingServiceImpl::UnregisterShareTarget(int64_t share_target_id) {
|
||||
// Find the endpoint id that matches the given share target.
|
||||
OutgoingShareSession* session =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(share_target_id);
|
||||
absl::Duration cache_retention =
|
||||
Milliseconds(NearbyFlags::GetInstance().GetInt64Flag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
kUnregisterTargetDiscoveryCacheLostExpiryMs));
|
||||
if (session != nullptr) {
|
||||
LOG(INFO) << __func__ << ": [Dedupped] Move the endpoint "
|
||||
<< session->endpoint_id() << " to discovery_cache.";
|
||||
outgoing_targets_manager_.MoveToDiscoveryCache(
|
||||
session->endpoint_id(),
|
||||
NearbyFlags::GetInstance().GetInt64Flag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
kUnregisterTargetDiscoveryCacheLostExpiryMs));
|
||||
outgoing_targets_manager_.OnShareTargetLost(session->endpoint_id(),
|
||||
cache_retention);
|
||||
} else {
|
||||
// Be careful not to clear out the share session map if a new session
|
||||
// was started during the cancellation delay.
|
||||
if (!is_scanning_ && !is_transferring_) {
|
||||
LOG(INFO) << "Cannot find session for target " << share_target_id
|
||||
<< " clearing all outgoing sessions.";
|
||||
outgoing_targets_manager_.DisableAllOutgoingShareTargets();
|
||||
outgoing_targets_manager_.AllTargetsLost(cache_retention);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3179,15 +2983,11 @@ void NearbySharingServiceImpl::SetInHighVisibility(
|
||||
service_observers_.NotifyHighVisibilityChanged(in_high_visibility_);
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnNetworkChanged(
|
||||
nearby::ConnectivityManager::ConnectionType type) {
|
||||
void NearbySharingServiceImpl::OnLanConnectedChanged(bool connected) {
|
||||
on_network_changed_delay_timer_ = std::make_unique<ThreadTimer>(
|
||||
*service_thread_, "on_network_changed_delay_timer",
|
||||
kProcessNetworkChangeTimerDelay,
|
||||
[this]() { StopAdvertisingAndInvalidateSurfaceState(); });
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnLanConnectedChanged(bool connected) {
|
||||
RunOnNearbySharingServiceThread(
|
||||
"lan_connection_changed", [this, connected]() {
|
||||
VLOG(1) << __func__
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
#include "sharing/internal/api/preference_manager.h"
|
||||
#include "sharing/internal/api/sharing_platform.h"
|
||||
#include "sharing/internal/api/sharing_rpc_client.h"
|
||||
#include "sharing/internal/public/connectivity_manager.h"
|
||||
#include "sharing/internal/public/context.h"
|
||||
#include "sharing/local_device_data/nearby_share_local_device_data_manager.h"
|
||||
#include "sharing/nearby_connection.h"
|
||||
@@ -103,7 +102,10 @@ class NearbySharingServiceImpl
|
||||
NearbySharingServiceImpl(
|
||||
std::unique_ptr<nearby::TaskRunner> service_thread, Context* context,
|
||||
nearby::sharing::api::SharingPlatform& sharing_platform,
|
||||
std::unique_ptr<nearby::sharing::api::SharingRpcClientFactory>
|
||||
nearby_share_client_factory,
|
||||
std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager,
|
||||
std::unique_ptr<NearbyShareContactManager> contact_manager,
|
||||
analytics::AnalyticsRecorder* analytics_recorder);
|
||||
~NearbySharingServiceImpl() override;
|
||||
|
||||
@@ -275,11 +277,6 @@ class NearbySharingServiceImpl
|
||||
StatusCodes StopScanning();
|
||||
void StopAdvertisingAndInvalidateSurfaceState();
|
||||
|
||||
void InvalidateFastInitiationScanning();
|
||||
void StartFastInitiationScanning();
|
||||
void OnFastInitiationDevicesNotDetected();
|
||||
void StopFastInitiationScanning();
|
||||
|
||||
void ScheduleRotateBackgroundAdvertisementTimer();
|
||||
void OnRotateBackgroundAdvertisementTimerFired();
|
||||
|
||||
@@ -290,11 +287,8 @@ class NearbySharingServiceImpl
|
||||
absl::string_view endpoint_id,
|
||||
NearbyConnection* connection, Status status);
|
||||
|
||||
void CreatePayloads(
|
||||
OutgoingShareSession& session,
|
||||
std::function<void(OutgoingShareSession&, bool)> callback);
|
||||
void OnCreatePayloads(std::vector<uint8_t> endpoint_info,
|
||||
OutgoingShareSession& session, bool success);
|
||||
void OutgoingSessionConnect(OutgoingShareSession& session,
|
||||
std::vector<uint8_t> endpoint_info);
|
||||
|
||||
void Fail(IncomingShareSession& session, TransferMetadata::Status status);
|
||||
void OnIncomingAdvertisementDecoded(
|
||||
@@ -350,9 +344,6 @@ class NearbySharingServiceImpl
|
||||
ShareSession* GetShareSession(int64_t share_target_id);
|
||||
IncomingShareSession* GetIncomingShareSession(int64_t share_target_id);
|
||||
|
||||
std::optional<std::vector<uint8_t>> GetBluetoothMacAddressForShareTarget(
|
||||
OutgoingShareSession& session);
|
||||
|
||||
void UnregisterShareTarget(int64_t share_target_id);
|
||||
|
||||
void OnStartAdvertisingResult(bool used_device_name, Status status);
|
||||
@@ -369,7 +360,6 @@ class NearbySharingServiceImpl
|
||||
bool is_initiator_of_cancellation);
|
||||
|
||||
// Monitor connectivity changes.
|
||||
void OnNetworkChanged(nearby::ConnectivityManager::ConnectionType type);
|
||||
void OnLanConnectedChanged(bool connected);
|
||||
|
||||
// Resets all settings of the nearby sharing service.
|
||||
@@ -455,10 +445,12 @@ class NearbySharingServiceImpl
|
||||
// Registers the most recent TransferMetadata and ShareTarget used for
|
||||
// transitioning notifications between foreground surfaces and background
|
||||
// surfaces. Empty if no metadata is available.
|
||||
std::optional<std::tuple<ShareTarget, AttachmentContainer, TransferMetadata>>
|
||||
std::optional<std::tuple<ShareTarget, std::unique_ptr<AttachmentContainer>,
|
||||
TransferMetadata>>
|
||||
last_incoming_metadata_;
|
||||
// The most recent outgoing TransferMetadata and ShareTarget.
|
||||
std::optional<std::tuple<ShareTarget, AttachmentContainer, TransferMetadata>>
|
||||
std::optional<std::tuple<ShareTarget, std::unique_ptr<AttachmentContainer>,
|
||||
TransferMetadata>>
|
||||
last_outgoing_metadata_;
|
||||
// A map of ShareTarget id to IncomingShareSession. This lets us know which
|
||||
// Nearby Connections endpoint and public certificate are related to the
|
||||
@@ -498,10 +490,6 @@ class NearbySharingServiceImpl
|
||||
// Used to debounce OnNetworkChanged processing.
|
||||
std::unique_ptr<ThreadTimer> on_network_changed_delay_timer_;
|
||||
|
||||
// Used to prevent the "Device nearby is sharing" notification from appearing
|
||||
// immediately after a completed share.
|
||||
std::unique_ptr<ThreadTimer> fast_initiation_scanner_cooldown_timer_;
|
||||
|
||||
// A queue of endpoint-discovered and endpoint-lost events that ensures the
|
||||
// events are processed sequentially, in the order received from Nearby
|
||||
// Connections. An event is processed either immediately, if there are no
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/hash/hash.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/base/file_path.h"
|
||||
@@ -33,34 +34,9 @@
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/internal/base/encode.h"
|
||||
#include "sharing/internal/public/logging.h"
|
||||
#include "sharing/nearby_sharing_service.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
|
||||
std::string ReceiveSurfaceStateToString(
|
||||
NearbySharingService::ReceiveSurfaceState state) {
|
||||
switch (state) {
|
||||
case NearbySharingService::ReceiveSurfaceState::kForeground:
|
||||
return "FOREGROUND";
|
||||
case NearbySharingService::ReceiveSurfaceState::kBackground:
|
||||
return "BACKGROUND";
|
||||
case NearbySharingService::ReceiveSurfaceState::kUnknown:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
std::string SendSurfaceStateToString(
|
||||
NearbySharingService::SendSurfaceState state) {
|
||||
switch (state) {
|
||||
case NearbySharingService::SendSurfaceState::kForeground:
|
||||
return "FOREGROUND";
|
||||
case NearbySharingService::SendSurfaceState::kBackground:
|
||||
return "BACKGROUND";
|
||||
case NearbySharingService::SendSurfaceState::kUnknown:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
std::string PowerLevelToString(PowerLevel level) {
|
||||
switch (level) {
|
||||
case PowerLevel::kLowPower:
|
||||
@@ -131,7 +107,9 @@ std::string GetDeviceId(
|
||||
}
|
||||
|
||||
if (!certificate->id().empty()) {
|
||||
return std::string(certificate->id().begin(), certificate->id().end());
|
||||
return absl::BytesToHexString(absl::string_view(
|
||||
reinterpret_cast<const char*>(certificate->id().data()),
|
||||
certificate->id().size()));
|
||||
}
|
||||
|
||||
return std::string(endpoint_id);
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "sharing/advertisement.h"
|
||||
#include "sharing/certificates/nearby_share_decrypted_public_certificate.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/nearby_sharing_service.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
|
||||
@@ -48,12 +47,6 @@ std::optional<std::string> GetDeviceName(
|
||||
const Advertisement& advertisement,
|
||||
const std::optional<NearbyShareDecryptedPublicCertificate>& certificate);
|
||||
|
||||
std::string ReceiveSurfaceStateToString(
|
||||
NearbySharingService::ReceiveSurfaceState state);
|
||||
|
||||
std::string SendSurfaceStateToString(
|
||||
NearbySharingService::SendSurfaceState state);
|
||||
|
||||
std::string PowerLevelToString(PowerLevel level);
|
||||
|
||||
// Return the most stable device identifier with the following priority:
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright 2025 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/nearby_sharing_util.h"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "sharing/certificates/nearby_share_decrypted_public_certificate.h"
|
||||
#include "sharing/certificates/nearby_share_encrypted_metadata_key.h"
|
||||
#include "sharing/certificates/nearby_share_private_certificate.h"
|
||||
#include "sharing/proto/encrypted_metadata.pb.h"
|
||||
#include "sharing/proto/enums.pb.h"
|
||||
#include "sharing/proto/rpc_resources.pb.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
|
||||
TEST(GetDeviceIdTest, CertificateAvailable_NoMacAddress_HasCertificateId) {
|
||||
const std::string kEndpointId = "endpoint-123";
|
||||
|
||||
// Create metadata without Bluetooth MAC address
|
||||
nearby::sharing::proto::EncryptedMetadata metadata;
|
||||
metadata.set_device_name("TestDevice");
|
||||
|
||||
// Create private certificate
|
||||
NearbySharePrivateCertificate private_cert(
|
||||
nearby::sharing::proto::DeviceVisibility::DEVICE_VISIBILITY_SELF_SHARE,
|
||||
absl::Now(), metadata);
|
||||
|
||||
// Generate EncryptedMetadataKey
|
||||
std::optional<NearbyShareEncryptedMetadataKey> encrypted_metadata_key =
|
||||
private_cert.EncryptMetadataKey();
|
||||
ASSERT_TRUE(encrypted_metadata_key.has_value());
|
||||
|
||||
// Generate PublicCertificate
|
||||
std::optional<nearby::sharing::proto::PublicCertificate> public_cert =
|
||||
private_cert.ToPublicCertificate();
|
||||
ASSERT_TRUE(public_cert.has_value());
|
||||
|
||||
// Decrypt PublicCertificate
|
||||
std::optional<NearbyShareDecryptedPublicCertificate> certificate =
|
||||
NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
|
||||
*public_cert, *encrypted_metadata_key);
|
||||
|
||||
ASSERT_TRUE(certificate.has_value());
|
||||
|
||||
// Calculate expected Device ID from certificate ID
|
||||
std::string expected_device_id = absl::BytesToHexString(
|
||||
absl::string_view(reinterpret_cast<const char*>(certificate->id().data()),
|
||||
certificate->id().size()));
|
||||
|
||||
EXPECT_EQ(GetDeviceId(kEndpointId, certificate), expected_device_id);
|
||||
}
|
||||
|
||||
} // namespace nearby::sharing
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include "sharing/outgoing_share_session.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -28,6 +27,7 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/base/file_path.h"
|
||||
#include "internal/base/files.h"
|
||||
#include "internal/platform/clock.h"
|
||||
#include "internal/platform/task_runner.h"
|
||||
#include "sharing/analytics/analytics_recorder.h"
|
||||
@@ -39,7 +39,7 @@
|
||||
#include "sharing/nearby_connection.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
#include "sharing/nearby_file_handler.h"
|
||||
#include "sharing/nearby_sharing_util.h"
|
||||
#include "sharing/paired_key_verification_runner.h"
|
||||
#include "sharing/payload_tracker.h"
|
||||
#include "sharing/share_session.h"
|
||||
@@ -110,6 +110,19 @@ ConnectionLayerStatus ConvertToConnectionLayerStatus(Status status) {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::vector<uint8_t>> GetBluetoothMacAddressForShareTarget(
|
||||
OutgoingShareSession& session) {
|
||||
const std::optional<NearbyShareDecryptedPublicCertificate>& certificate =
|
||||
session.certificate();
|
||||
if (!certificate) {
|
||||
LOG(ERROR) << __func__ << ": No decrypted public certificate found for "
|
||||
<< "share target id: " << session.share_target().id;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return GetBluetoothMacAddressFromCertificate(*certificate);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OutgoingShareSession::OutgoingShareSession(
|
||||
@@ -129,12 +142,16 @@ OutgoingShareSession::~OutgoingShareSession() = default;
|
||||
|
||||
void OutgoingShareSession::InvokeTransferUpdateCallback(
|
||||
const TransferMetadata& metadata) {
|
||||
if (metadata.is_final_status()) {
|
||||
is_connecting_ = false;
|
||||
}
|
||||
transfer_update_callback_(*this, metadata);
|
||||
}
|
||||
|
||||
void OutgoingShareSession::InitiateSendAttachments(
|
||||
bool OutgoingShareSession::InitiateSendAttachments(
|
||||
std::unique_ptr<AttachmentContainer> attachment_container) {
|
||||
SetAttachmentContainer(std::move(*attachment_container));
|
||||
is_connecting_ = true;
|
||||
|
||||
// Set session ID.
|
||||
set_session_id(analytics_recorder().GenerateNextId());
|
||||
@@ -144,6 +161,31 @@ void OutgoingShareSession::InitiateSendAttachments(
|
||||
/*transfer_position=*/1,
|
||||
/*concurrent_connections=*/1,
|
||||
share_target());
|
||||
text_payloads_.clear();
|
||||
wifi_credentials_payloads_.clear();
|
||||
file_payloads_.clear();
|
||||
CreateTextPayloads();
|
||||
CreateWifiCredentialsPayloads();
|
||||
bool success = CreateFilePayloads();
|
||||
// Log analytics event of describing attachments.
|
||||
analytics_recorder().NewDescribeAttachments(this->attachment_container());
|
||||
if (success) {
|
||||
if (text_payloads_.empty() && wifi_credentials_payloads_.empty() &&
|
||||
file_payloads_.empty()) {
|
||||
// Fails in no payloads created.
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
LOG(WARNING) << __func__
|
||||
<< ": Failed to send file to remote ShareTarget. Failed to "
|
||||
"create payloads.";
|
||||
UpdateTransferMetadata(
|
||||
TransferMetadataBuilder()
|
||||
.set_status(TransferMetadata::Status::kMediaUnavailable)
|
||||
.build());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool OutgoingShareSession::ProcessKeyVerificationResult(
|
||||
@@ -160,25 +202,12 @@ void OutgoingShareSession::OnConnectionDisconnected() {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<FilePath> OutgoingShareSession::GetFilePaths() const {
|
||||
std::vector<FilePath> file_paths;
|
||||
file_paths.reserve(attachment_container().GetFileAttachments().size());
|
||||
for (const FileAttachment& file_attachment :
|
||||
attachment_container().GetFileAttachments()) {
|
||||
// All file attachments must have a file path.
|
||||
// That is verified in SendAttachments().
|
||||
file_paths.push_back(*file_attachment.file_path());
|
||||
}
|
||||
return file_paths;
|
||||
}
|
||||
|
||||
void OutgoingShareSession::CreateTextPayloads() {
|
||||
const std::vector<TextAttachment> attachments =
|
||||
const std::vector<TextAttachment>& attachments =
|
||||
attachment_container().GetTextAttachments();
|
||||
if (attachments.empty()) {
|
||||
return;
|
||||
}
|
||||
text_payloads_.clear();
|
||||
text_payloads_.reserve(attachments.size());
|
||||
for (const TextAttachment& attachment : attachments) {
|
||||
absl::string_view body = attachment.text_body();
|
||||
@@ -189,12 +218,11 @@ void OutgoingShareSession::CreateTextPayloads() {
|
||||
}
|
||||
|
||||
void OutgoingShareSession::CreateWifiCredentialsPayloads() {
|
||||
const std::vector<WifiCredentialsAttachment> attachments =
|
||||
const std::vector<WifiCredentialsAttachment>& attachments =
|
||||
attachment_container().GetWifiCredentialsAttachments();
|
||||
if (attachments.empty()) {
|
||||
return;
|
||||
}
|
||||
wifi_credentials_payloads_.clear();
|
||||
wifi_credentials_payloads_.reserve(attachments.size());
|
||||
for (const WifiCredentialsAttachment& attachment : attachments) {
|
||||
nearby::sharing::service::proto::WifiCredentials wifi_credentials;
|
||||
@@ -210,26 +238,26 @@ void OutgoingShareSession::CreateWifiCredentialsPayloads() {
|
||||
}
|
||||
}
|
||||
|
||||
bool OutgoingShareSession::CreateFilePayloads(
|
||||
const std::vector<NearbyFileHandler::FileInfo>& files) {
|
||||
AttachmentContainer& container = mutable_attachment_container();
|
||||
if (files.size() != container.GetFileAttachments().size()) {
|
||||
return false;
|
||||
}
|
||||
if (files.empty()) {
|
||||
bool OutgoingShareSession::CreateFilePayloads() {
|
||||
if (attachment_container().GetFileAttachments().empty()) {
|
||||
return true;
|
||||
}
|
||||
file_payloads_.clear();
|
||||
file_payloads_.reserve(files.size());
|
||||
AttachmentContainer& container = mutable_attachment_container();
|
||||
file_payloads_.reserve(container.GetFileAttachments().size());
|
||||
|
||||
for (size_t i = 0; i < files.size(); ++i) {
|
||||
const NearbyFileHandler::FileInfo& file_info = files[i];
|
||||
for (int i = 0; i < container.GetFileAttachments().size(); ++i) {
|
||||
FileAttachment& attachment = container.GetMutableFileAttachment(i);
|
||||
attachment.set_size(file_info.size);
|
||||
InputFile input_file;
|
||||
input_file.path = file_info.file_path;
|
||||
Payload payload(input_file, attachment.parent_folder());
|
||||
payload.content.file_payload.size = file_info.size;
|
||||
// All file attachments must have a file path.
|
||||
// That is verified in SendAttachments().
|
||||
FilePath file_path = *attachment.file_path();
|
||||
std::optional<uintmax_t> file_size = Files::GetFileSize(file_path);
|
||||
if (!file_size.has_value()) {
|
||||
LOG(WARNING) << "Failed to get file size for file: "
|
||||
<< file_path.ToString();
|
||||
return false;
|
||||
}
|
||||
attachment.set_size(*file_size);
|
||||
Payload payload(file_path, attachment.parent_folder());
|
||||
file_payloads_.push_back(std::move(payload));
|
||||
SetAttachmentPayloadId(attachment.id(), file_payloads_.back().id);
|
||||
}
|
||||
@@ -499,6 +527,8 @@ bool OutgoingShareSession::UpdateSessionForDedup(
|
||||
<< "Share target id cannot be changed during deduplication.";
|
||||
set_share_target(share_target);
|
||||
if (IsConnected()) {
|
||||
LOG(INFO) << __func__ << ": session for share_target.id=" << share_target.id
|
||||
<< " is connected, not updating.";
|
||||
return false;
|
||||
}
|
||||
set_endpoint_id(endpoint_id);
|
||||
@@ -512,15 +542,20 @@ bool OutgoingShareSession::UpdateSessionForDedup(
|
||||
|
||||
void OutgoingShareSession::Connect(
|
||||
std::vector<uint8_t> endpoint_info,
|
||||
std::optional<std::vector<uint8_t>> bluetooth_mac_address,
|
||||
DataUsage data_usage, bool disable_wifi_hotspot,
|
||||
std::function<void(absl::string_view endpoint_id,
|
||||
NearbyConnection* connection, Status status)>
|
||||
callback) {
|
||||
// Send process initialized successfully, from now on status updated
|
||||
// will be sent out via TransferUpdates.
|
||||
UpdateTransferMetadata(TransferMetadataBuilder()
|
||||
.set_status(TransferMetadata::Status::kConnecting)
|
||||
.build());
|
||||
connection_start_time_ = clock().Now();
|
||||
connections_manager().Connect(
|
||||
std::move(endpoint_info), endpoint_id(), std::move(bluetooth_mac_address),
|
||||
data_usage, GetTransportType(disable_wifi_hotspot), std::move(callback));
|
||||
std::move(endpoint_info), endpoint_id(),
|
||||
GetBluetoothMacAddressForShareTarget(*this), data_usage,
|
||||
GetTransportType(disable_wifi_hotspot), std::move(callback));
|
||||
}
|
||||
|
||||
bool OutgoingShareSession::OnConnectResult(NearbyConnection* connection,
|
||||
@@ -547,6 +582,7 @@ bool OutgoingShareSession::OnConnectResult(NearbyConnection* connection,
|
||||
}
|
||||
set_disconnect_status(TransferMetadata::Status::kFailed);
|
||||
SetConnection(connection);
|
||||
is_connecting_ = false;
|
||||
|
||||
// Log analytics event of establishing connection.
|
||||
analytics_recorder().NewEstablishConnection(
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/base/file_path.h"
|
||||
#include "internal/platform/clock.h"
|
||||
#include "internal/platform/task_runner.h"
|
||||
#include "sharing/analytics/analytics_recorder.h"
|
||||
@@ -35,7 +34,6 @@
|
||||
#include "sharing/nearby_connection.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
#include "sharing/nearby_file_handler.h"
|
||||
#include "sharing/paired_key_verification_runner.h"
|
||||
#include "sharing/proto/enums.pb.h"
|
||||
#include "sharing/share_session.h"
|
||||
@@ -69,32 +67,15 @@ class OutgoingShareSession : public ShareSession {
|
||||
obfuscated_gaia_id_ = std::move(obfuscated_gaia_id);
|
||||
}
|
||||
|
||||
const std::vector<Payload>& text_payloads() const { return text_payloads_; }
|
||||
|
||||
const std::vector<Payload>& wifi_credentials_payloads() const {
|
||||
return wifi_credentials_payloads_;
|
||||
}
|
||||
|
||||
const std::vector<Payload>& file_payloads() const { return file_payloads_; }
|
||||
|
||||
void InitiateSendAttachments(
|
||||
// Returns true if the attachments are valid and payloads are created
|
||||
// successfully.
|
||||
bool InitiateSendAttachments(
|
||||
std::unique_ptr<AttachmentContainer> attachment_container);
|
||||
|
||||
bool ProcessKeyVerificationResult(
|
||||
PairedKeyVerificationRunner::PairedKeyVerificationResult result,
|
||||
location::nearby::proto::sharing::OSType share_target_os_type);
|
||||
|
||||
std::vector<FilePath> GetFilePaths() const;
|
||||
|
||||
void CreateTextPayloads();
|
||||
void CreateWifiCredentialsPayloads();
|
||||
// Create file payloads and update the file size of all file attachments.
|
||||
// The list of file infos must be sorted in the same order as the file
|
||||
// attachments in the share target.
|
||||
// Returns true if all file payloads are created successfully.
|
||||
bool CreateFilePayloads(
|
||||
const std::vector<NearbyFileHandler::FileInfo>& files);
|
||||
|
||||
// Returns true if the introduction frame is written successfully.
|
||||
// `timeout_callback` is called if accept is not received from both sender and
|
||||
// receiver within the timeout.
|
||||
@@ -150,7 +131,6 @@ class OutgoingShareSession : public ShareSession {
|
||||
// Establish a connection to the remote device identified by `endpoint_info`.
|
||||
// `callback` is called when with the connection establishment status..
|
||||
void Connect(std::vector<uint8_t> endpoint_info,
|
||||
std::optional<std::vector<uint8_t>> bluetooth_mac_address,
|
||||
nearby::sharing::proto::DataUsage data_usage,
|
||||
bool disable_wifi_hotspot,
|
||||
std::function<void(absl::string_view endpoint_id,
|
||||
@@ -169,6 +149,19 @@ class OutgoingShareSession : public ShareSession {
|
||||
advanced_protection_mismatch_ = advanced_protection_mismatch;
|
||||
}
|
||||
|
||||
// Returns true if the session is connected or in the process of connecting.
|
||||
bool IsActive() const {
|
||||
return IsConnected() || is_connecting_;
|
||||
}
|
||||
|
||||
const std::vector<Payload>& text_payloads() const { return text_payloads_; }
|
||||
|
||||
const std::vector<Payload>& wifi_credentials_payloads() const {
|
||||
return wifi_credentials_payloads_;
|
||||
}
|
||||
|
||||
const std::vector<Payload>& file_payloads() const { return file_payloads_; }
|
||||
|
||||
protected:
|
||||
void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override;
|
||||
void OnConnectionDisconnected() override;
|
||||
@@ -181,6 +174,12 @@ class OutgoingShareSession : public ShareSession {
|
||||
bool FillIntroductionFrame(
|
||||
nearby::sharing::service::proto::IntroductionFrame* introduction) const;
|
||||
|
||||
void CreateTextPayloads();
|
||||
void CreateWifiCredentialsPayloads();
|
||||
// Create file payloads and update the file size of all file attachments.
|
||||
// Returns true if all file payloads are created successfully.
|
||||
bool CreateFilePayloads();
|
||||
|
||||
std::optional<std::string> obfuscated_gaia_id_;
|
||||
// All payloads are in the same order as the attachments in the share target.
|
||||
std::vector<Payload> text_payloads_;
|
||||
@@ -199,6 +198,7 @@ class OutgoingShareSession : public ShareSession {
|
||||
std::unique_ptr<ThreadTimer> disconnection_timeout_;
|
||||
bool advanced_protection_enabled_ = false;
|
||||
bool advanced_protection_mismatch_ = false;
|
||||
bool is_connecting_ = false;
|
||||
};
|
||||
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "sharing/outgoing_share_session.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -29,6 +30,7 @@
|
||||
#include "internal/analytics/mock_event_logger.h"
|
||||
#include "internal/analytics/sharing_log_matchers.h"
|
||||
#include "internal/base/file_path.h"
|
||||
#include "internal/base/files.h"
|
||||
#include "internal/network/url.h"
|
||||
#include "internal/test/fake_clock.h"
|
||||
#include "internal/test/fake_device_info.h"
|
||||
@@ -43,7 +45,6 @@
|
||||
#include "sharing/nearby_connection_impl.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
#include "sharing/nearby_file_handler.h"
|
||||
#include "sharing/paired_key_verification_runner.h"
|
||||
#include "sharing/proto/analytics/nearby_sharing_log.pb.h"
|
||||
#include "sharing/proto/analytics/nearby_sharing_log.proto.static_reflection.h"
|
||||
@@ -72,6 +73,7 @@ using ::nearby::sharing::service::proto::WifiCredentials;
|
||||
using ::testing::_;
|
||||
using ::testing::AllOf;
|
||||
using ::testing::Eq;
|
||||
using ::testing::InSequence;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::IsFalse;
|
||||
using ::testing::IsTrue;
|
||||
@@ -83,6 +85,16 @@ using ::testing::StrictMock;
|
||||
using ::testing::proto::ProtoField;
|
||||
|
||||
constexpr absl::string_view kEndpointId = "ABCD";
|
||||
constexpr absl::string_view kFile1Name = "someFileName.jpg";
|
||||
constexpr int kFile1Size = 1234;
|
||||
|
||||
void CreateTempFile(absl::string_view file_name, int file_size) {
|
||||
FilePath file_path =
|
||||
Files::GetTemporaryDirectory().append(FilePath(file_name));
|
||||
std::ofstream file_stream(file_path.GetPath());
|
||||
file_stream << std::string(file_size, 'a');
|
||||
file_stream.close();
|
||||
}
|
||||
|
||||
class OutgoingShareSessionTest : public ::testing::Test {
|
||||
public:
|
||||
@@ -94,29 +106,36 @@ class OutgoingShareSessionTest : public ::testing::Test {
|
||||
"A bit of text body", "Some text title", "text/html"),
|
||||
text2_(nearby::sharing::service::proto::TextMetadata::ADDRESS,
|
||||
"A bit of text body 2", "Some text title 2", "text/plain"),
|
||||
file1_(FilePath("/usr/local/tmp/someFileName.jpg"), /*mime_type=*/"",
|
||||
file1_(Files::GetTemporaryDirectory().append(FilePath(kFile1Name)),
|
||||
/*mime_type=*/"",
|
||||
/*parent_folder=*/"/usr/local/parent"),
|
||||
file2_(FilePath("/usr/local/tmp/someFileName2.jpg"), /*mime_type=*/"",
|
||||
/*parent_folder=*/"/usr/local/parent2"),
|
||||
wifi1_(
|
||||
"GoogleGuest",
|
||||
nearby::sharing::service::proto::WifiCredentialsMetadata::WPA_PSK,
|
||||
"somepassword", /*is_hidden=*/true) {}
|
||||
|
||||
std::unique_ptr<AttachmentContainer> CreateDefaultAttachmentContainer() {
|
||||
return std::make_unique<AttachmentContainer>(
|
||||
std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
std::vector<WifiCredentialsAttachment>{wifi1_});
|
||||
"somepassword", /*is_hidden=*/true) {
|
||||
CreateTempFile(kFile1Name, kFile1Size);
|
||||
}
|
||||
|
||||
void InitSendAttachments(
|
||||
std::unique_ptr<AttachmentContainer> CreateDefaultAttachmentContainer() {
|
||||
return AttachmentContainer::Builder(
|
||||
std::vector<TextAttachment>{text1_, text2_},
|
||||
std::vector<FileAttachment>{file1_},
|
||||
std::vector<WifiCredentialsAttachment>{wifi1_})
|
||||
.Build();
|
||||
}
|
||||
|
||||
bool InitSendAttachments(
|
||||
std::unique_ptr<AttachmentContainer> attachment_container) {
|
||||
InSequence seq;
|
||||
EXPECT_CALL(mock_event_logger_,
|
||||
Log(Matcher<const SharingLog&>(
|
||||
AllOf((HasCategory(EventCategory::SENDING_EVENT),
|
||||
HasEventType(EventType::SEND_START))))));
|
||||
session_.InitiateSendAttachments(std::move(attachment_container));
|
||||
EXPECT_CALL(mock_event_logger_,
|
||||
Log(Matcher<const SharingLog&>(
|
||||
AllOf((HasCategory(EventCategory::SENDING_EVENT),
|
||||
HasEventType(EventType::DESCRIBE_ATTACHMENTS))))));
|
||||
return session_.InitiateSendAttachments(std::move(attachment_container));
|
||||
}
|
||||
|
||||
void ConnectionSuccess(NearbyConnection* connection) {
|
||||
@@ -125,7 +144,10 @@ class OutgoingShareSessionTest : public ::testing::Test {
|
||||
AllOf((HasCategory(EventCategory::SENDING_EVENT),
|
||||
HasEventType(EventType::ESTABLISH_CONNECTION))))));
|
||||
connections_manager_.set_nearby_connection(connection);
|
||||
session_.Connect({}, {}, proto::DataUsage::ONLINE_DATA_USAGE,
|
||||
EXPECT_CALL(transfer_metadata_callback_,
|
||||
Call(_, AllOf(HasStatus(TransferMetadata::Status::kConnecting),
|
||||
Not(IsFinalStatus()))));
|
||||
session_.Connect(/*endpoint_info=*/{}, proto::DataUsage::ONLINE_DATA_USAGE,
|
||||
/*disable_wifi_hotspot=*/false,
|
||||
[](absl::string_view endpoint_id,
|
||||
NearbyConnection* connection, Status status) {});
|
||||
@@ -148,156 +170,108 @@ class OutgoingShareSessionTest : public ::testing::Test {
|
||||
TextAttachment text1_;
|
||||
TextAttachment text2_;
|
||||
FileAttachment file1_;
|
||||
FileAttachment file2_;
|
||||
WifiCredentialsAttachment wifi1_;
|
||||
};
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, GetFilePaths) {
|
||||
OutgoingShareSession session(
|
||||
&fake_clock_, fake_task_runner_, &connections_manager_,
|
||||
analytics_recorder_, std::string(kEndpointId), share_target_,
|
||||
[](OutgoingShareSession&, const TransferMetadata&) {});
|
||||
auto container = std::make_unique<AttachmentContainer>(
|
||||
std::vector<TextAttachment>{},
|
||||
std::vector<FileAttachment>{file1_, file2_},
|
||||
std::vector<WifiCredentialsAttachment>{});
|
||||
session.InitiateSendAttachments(std::move(container));
|
||||
TEST_F(OutgoingShareSessionTest, InitiateSendAttachmentsWithNoAttachments) {
|
||||
EXPECT_CALL(
|
||||
transfer_metadata_callback_,
|
||||
Call(_, AllOf(HasStatus(TransferMetadata::Status::kMediaUnavailable),
|
||||
IsFinalStatus())));
|
||||
|
||||
auto file_paths = session.GetFilePaths();
|
||||
EXPECT_THAT(
|
||||
InitSendAttachments(AttachmentContainer::Builder({}, {}, {}).Build()),
|
||||
IsFalse());
|
||||
|
||||
ASSERT_THAT(file_paths, SizeIs(2));
|
||||
EXPECT_THAT(file_paths[0], Eq(file1_.file_path()));
|
||||
EXPECT_THAT(file_paths[1], Eq(file2_.file_path()));
|
||||
EXPECT_THAT(session_.text_payloads(), IsEmpty());
|
||||
EXPECT_THAT(session_.wifi_credentials_payloads(), IsEmpty());
|
||||
EXPECT_THAT(session_.file_payloads(), IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, CreateTextPayloadsWithNoTextAttachments) {
|
||||
OutgoingShareSession session(
|
||||
&fake_clock_, fake_task_runner_, &connections_manager_,
|
||||
analytics_recorder_, std::string(kEndpointId), share_target_,
|
||||
[](OutgoingShareSession&, const TransferMetadata&) {});
|
||||
session.CreateTextPayloads();
|
||||
const std::vector<Payload>& payloads = session.text_payloads();
|
||||
TEST_F(OutgoingShareSessionTest, InitiateSendAttachmentsSuccess) {
|
||||
EXPECT_THAT(InitSendAttachments(CreateDefaultAttachmentContainer()),
|
||||
IsTrue());
|
||||
|
||||
EXPECT_THAT(payloads, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, CreateTextPayloads) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
session_.CreateTextPayloads();
|
||||
const std::vector<Payload>& payloads = session_.text_payloads();
|
||||
auto& attachment_payload_map = session_.attachment_payload_map();
|
||||
|
||||
ASSERT_THAT(payloads, SizeIs(2));
|
||||
EXPECT_THAT(payloads[0].content.type, Eq(PayloadContent::Type::kBytes));
|
||||
EXPECT_THAT(payloads[1].content.type, Eq(PayloadContent::Type::kBytes));
|
||||
EXPECT_THAT(payloads[0].content.bytes_payload.bytes,
|
||||
const std::vector<Payload>& text_payloads = session_.text_payloads();
|
||||
ASSERT_THAT(text_payloads, SizeIs(2));
|
||||
EXPECT_THAT(text_payloads[0].content.type, Eq(PayloadContent::Type::kBytes));
|
||||
EXPECT_THAT(text_payloads[1].content.type, Eq(PayloadContent::Type::kBytes));
|
||||
EXPECT_THAT(text_payloads[0].content.bytes_payload.bytes,
|
||||
Eq(std::vector<uint8_t>(text1_.text_body().begin(),
|
||||
text1_.text_body().end())));
|
||||
EXPECT_THAT(payloads[1].content.bytes_payload.bytes,
|
||||
EXPECT_THAT(text_payloads[1].content.bytes_payload.bytes,
|
||||
Eq(std::vector<uint8_t>(text2_.text_body().begin(),
|
||||
text2_.text_body().end())));
|
||||
|
||||
ASSERT_THAT(attachment_payload_map, SizeIs(2));
|
||||
ASSERT_THAT(attachment_payload_map.contains(text1_.id()), IsTrue());
|
||||
EXPECT_THAT(attachment_payload_map.at(text1_.id()), Eq(payloads[0].id));
|
||||
ASSERT_THAT(attachment_payload_map.contains(text2_.id()), IsTrue());
|
||||
EXPECT_THAT(attachment_payload_map.at(text2_.id()), Eq(payloads[1].id));
|
||||
}
|
||||
const std::vector<Payload>& wifi_payloads =
|
||||
session_.wifi_credentials_payloads();
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, CreateFilePayloadsWithNoFileAttachments) {
|
||||
OutgoingShareSession session(
|
||||
&fake_clock_, fake_task_runner_, &connections_manager_,
|
||||
analytics_recorder_, std::string(kEndpointId), share_target_,
|
||||
[](OutgoingShareSession&, const TransferMetadata&) {});
|
||||
|
||||
EXPECT_THAT(
|
||||
session.CreateFilePayloads(std::vector<NearbyFileHandler::FileInfo>()),
|
||||
IsTrue());
|
||||
const std::vector<Payload>& payloads = session.file_payloads();
|
||||
|
||||
EXPECT_THAT(payloads, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, CreateFilePayloadsWithWrongFileInfo) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
EXPECT_THAT(
|
||||
session_.CreateFilePayloads(std::vector<NearbyFileHandler::FileInfo>()),
|
||||
IsFalse());
|
||||
const std::vector<Payload>& payloads = session_.file_payloads();
|
||||
|
||||
EXPECT_THAT(payloads, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, CreateFilePayloads) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos;
|
||||
file_infos.push_back({
|
||||
.size = 12355L,
|
||||
.file_path = file1_.file_path().value(),
|
||||
});
|
||||
session_.CreateFilePayloads(file_infos);
|
||||
const std::vector<Payload>& payloads = session_.file_payloads();
|
||||
auto& attachment_payload_map = session_.attachment_payload_map();
|
||||
|
||||
ASSERT_THAT(payloads, SizeIs(1));
|
||||
EXPECT_THAT(payloads[0].content.type, Eq(PayloadContent::Type::kFile));
|
||||
EXPECT_THAT(payloads[0].content.file_payload.size, Eq(12355L));
|
||||
EXPECT_THAT(payloads[0].content.file_payload.parent_folder,
|
||||
Eq(file1_.parent_folder()));
|
||||
EXPECT_THAT(payloads[0].content.file_payload.file.path,
|
||||
Eq(file1_.file_path()));
|
||||
|
||||
EXPECT_THAT(attachment_payload_map, SizeIs(1));
|
||||
ASSERT_THAT(attachment_payload_map.contains(file1_.id()), IsTrue());
|
||||
EXPECT_THAT(attachment_payload_map.at(file1_.id()), Eq(payloads[0].id));
|
||||
|
||||
EXPECT_THAT(session_.attachment_container().GetFileAttachments()[0].size(),
|
||||
Eq(12355L));
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, CreateWifiPayloadsWithNoWifiAttachments) {
|
||||
OutgoingShareSession session(
|
||||
&fake_clock_, fake_task_runner_, &connections_manager_,
|
||||
analytics_recorder_, std::string(kEndpointId), share_target_,
|
||||
[](OutgoingShareSession&, const TransferMetadata&) {});
|
||||
session.CreateWifiCredentialsPayloads();
|
||||
const std::vector<Payload>& payloads = session.file_payloads();
|
||||
|
||||
EXPECT_THAT(payloads, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, CreateWifiCredentialsPayloads) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
session_.CreateWifiCredentialsPayloads();
|
||||
const std::vector<Payload>& payloads = session_.wifi_credentials_payloads();
|
||||
auto& attachment_payload_map = session_.attachment_payload_map();
|
||||
|
||||
ASSERT_THAT(payloads, SizeIs(1));
|
||||
EXPECT_THAT(payloads[0].content.type, Eq(PayloadContent::Type::kBytes));
|
||||
ASSERT_THAT(wifi_payloads, SizeIs(1));
|
||||
EXPECT_THAT(wifi_payloads[0].content.type, Eq(PayloadContent::Type::kBytes));
|
||||
WifiCredentials wifi_credentials;
|
||||
EXPECT_THAT(wifi_credentials.ParseFromArray(
|
||||
payloads[0].content.bytes_payload.bytes.data(),
|
||||
payloads[0].content.bytes_payload.bytes.size()),
|
||||
wifi_payloads[0].content.bytes_payload.bytes.data(),
|
||||
wifi_payloads[0].content.bytes_payload.bytes.size()),
|
||||
IsTrue());
|
||||
EXPECT_THAT(wifi_credentials.password(), Eq(wifi1_.password()));
|
||||
EXPECT_THAT(wifi_credentials.has_hidden_ssid(), Eq(wifi1_.is_hidden()));
|
||||
|
||||
ASSERT_THAT(attachment_payload_map, SizeIs(1));
|
||||
const std::vector<Payload>& file_payloads = session_.file_payloads();
|
||||
ASSERT_THAT(file_payloads, SizeIs(1));
|
||||
EXPECT_THAT(file_payloads[0].content.type, Eq(PayloadContent::Type::kFile));
|
||||
EXPECT_THAT(file_payloads[0].content.file_payload.parent_folder,
|
||||
Eq(file1_.parent_folder()));
|
||||
EXPECT_THAT(file_payloads[0].content.file_payload.file_path,
|
||||
Eq(file1_.file_path()));
|
||||
|
||||
|
||||
EXPECT_THAT(session_.attachment_container().GetFileAttachments()[0].size(),
|
||||
Eq(kFile1Size));
|
||||
|
||||
auto& attachment_payload_map = session_.attachment_payload_map();
|
||||
|
||||
ASSERT_THAT(attachment_payload_map, SizeIs(4));
|
||||
ASSERT_THAT(attachment_payload_map.contains(text1_.id()), IsTrue());
|
||||
EXPECT_THAT(attachment_payload_map.at(text1_.id()), Eq(text_payloads[0].id));
|
||||
ASSERT_THAT(attachment_payload_map.contains(text2_.id()), IsTrue());
|
||||
EXPECT_THAT(attachment_payload_map.at(text2_.id()), Eq(text_payloads[1].id));
|
||||
ASSERT_THAT(attachment_payload_map.contains(wifi1_.id()), IsTrue());
|
||||
EXPECT_THAT(attachment_payload_map.at(wifi1_.id()), Eq(payloads[0].id));
|
||||
EXPECT_THAT(attachment_payload_map.at(wifi1_.id()), Eq(wifi_payloads[0].id));
|
||||
ASSERT_THAT(attachment_payload_map.contains(file1_.id()), IsTrue());
|
||||
EXPECT_THAT(attachment_payload_map.at(file1_.id()), Eq(file_payloads[0].id));
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest,
|
||||
InitiateSendAttachmentsWithNonexistentFileAttachment) {
|
||||
// Remove attachment file1.
|
||||
Files::RemoveFile(
|
||||
Files::GetTemporaryDirectory().append(FilePath(kFile1Name)));
|
||||
EXPECT_CALL(
|
||||
transfer_metadata_callback_,
|
||||
Call(_, AllOf(HasStatus(TransferMetadata::Status::kMediaUnavailable),
|
||||
IsFinalStatus())));
|
||||
|
||||
EXPECT_THAT(InitSendAttachments(CreateDefaultAttachmentContainer()),
|
||||
IsFalse());
|
||||
const std::vector<Payload>& payloads = session_.file_payloads();
|
||||
|
||||
EXPECT_THAT(payloads, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, ConnectNoDisableWifiHotspot) {
|
||||
std::vector<uint8_t> endpoint_info = {1, 2, 3, 4};
|
||||
std::vector<uint8_t> bluetooth_mac_address = {5, 6, 7, 8};
|
||||
file1_.set_size(1000000); // 1MB
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
// Set file size to 1MB.
|
||||
CreateTempFile(kFile1Name, 1000000);
|
||||
EXPECT_THAT(InitSendAttachments(CreateDefaultAttachmentContainer()),
|
||||
IsTrue());
|
||||
NearbyConnectionImpl nearby_connection(device_info_);
|
||||
connections_manager_.set_nearby_connection(&nearby_connection);
|
||||
|
||||
EXPECT_CALL(transfer_metadata_callback_,
|
||||
Call(_, AllOf(HasStatus(TransferMetadata::Status::kConnecting),
|
||||
Not(IsFinalStatus()))));
|
||||
session_.Connect(
|
||||
endpoint_info, bluetooth_mac_address,
|
||||
nearby::sharing::proto::DataUsage::ONLINE_DATA_USAGE,
|
||||
endpoint_info, nearby::sharing::proto::DataUsage::ONLINE_DATA_USAGE,
|
||||
/*disable_wifi_hotspot=*/false,
|
||||
[&nearby_connection](absl::string_view endpoint_id,
|
||||
NearbyConnection* connection, Status status) {
|
||||
@@ -317,15 +291,18 @@ TEST_F(OutgoingShareSessionTest, ConnectNoDisableWifiHotspot) {
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, ConnectDisableWifiHotspot) {
|
||||
std::vector<uint8_t> endpoint_info = {1, 2, 3, 4};
|
||||
std::vector<uint8_t> bluetooth_mac_address = {5, 6, 7, 8};
|
||||
file1_.set_size(1000000); // 1MB
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
// Set file size to 1MB.
|
||||
CreateTempFile(kFile1Name, 1000000);
|
||||
EXPECT_THAT(InitSendAttachments(CreateDefaultAttachmentContainer()),
|
||||
IsTrue());
|
||||
NearbyConnectionImpl nearby_connection(device_info_);
|
||||
connections_manager_.set_nearby_connection(&nearby_connection);
|
||||
|
||||
EXPECT_CALL(transfer_metadata_callback_,
|
||||
Call(_, AllOf(HasStatus(TransferMetadata::Status::kConnecting),
|
||||
Not(IsFinalStatus()))));
|
||||
session_.Connect(
|
||||
endpoint_info, bluetooth_mac_address,
|
||||
nearby::sharing::proto::DataUsage::ONLINE_DATA_USAGE,
|
||||
endpoint_info, nearby::sharing::proto::DataUsage::ONLINE_DATA_USAGE,
|
||||
/*disable_wifi_hotspot=*/true,
|
||||
[&nearby_connection](absl::string_view endpoint_id,
|
||||
NearbyConnection* connection, Status status) {
|
||||
@@ -344,15 +321,17 @@ TEST_F(OutgoingShareSessionTest, ConnectDisableWifiHotspot) {
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, OnConnectResultSuccessLogsSessionDuration) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
EXPECT_THAT(InitSendAttachments(CreateDefaultAttachmentContainer()),
|
||||
IsTrue());
|
||||
session_.set_session_id(1234);
|
||||
std::vector<uint8_t> endpoint_info = {1, 2, 3, 4};
|
||||
std::vector<uint8_t> bluetooth_mac_address = {5, 6, 7, 8};
|
||||
NearbyConnectionImpl nearby_connection(device_info_);
|
||||
connections_manager_.set_nearby_connection(&nearby_connection);
|
||||
EXPECT_CALL(transfer_metadata_callback_,
|
||||
Call(_, AllOf(HasStatus(TransferMetadata::Status::kConnecting),
|
||||
Not(IsFinalStatus()))));
|
||||
session_.Connect(
|
||||
endpoint_info, bluetooth_mac_address,
|
||||
nearby::sharing::proto::DataUsage::ONLINE_DATA_USAGE,
|
||||
endpoint_info, nearby::sharing::proto::DataUsage::ONLINE_DATA_USAGE,
|
||||
/*disable_wifi_hotspot=*/false,
|
||||
[&nearby_connection](absl::string_view endpoint_id,
|
||||
NearbyConnection* connection, Status status) {
|
||||
@@ -375,11 +354,14 @@ TEST_F(OutgoingShareSessionTest, OnConnectResultSuccessLogsSessionDuration) {
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, OnConnectResultFailureLogsSessionDuration) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
EXPECT_THAT(InitSendAttachments(CreateDefaultAttachmentContainer()),
|
||||
IsTrue());
|
||||
session_.set_session_id(1234);
|
||||
std::vector<uint8_t> endpoint_info = {1, 2, 3, 4};
|
||||
std::vector<uint8_t> bluetooth_mac_address = {5, 6, 7, 8};
|
||||
session_.Connect(endpoint_info, bluetooth_mac_address,
|
||||
EXPECT_CALL(transfer_metadata_callback_,
|
||||
Call(_, AllOf(HasStatus(TransferMetadata::Status::kConnecting),
|
||||
Not(IsFinalStatus()))));
|
||||
session_.Connect(endpoint_info,
|
||||
nearby::sharing::proto::DataUsage::ONLINE_DATA_USAGE,
|
||||
/*disable_wifi_hotspot=*/false,
|
||||
[](absl::string_view endpoint_id,
|
||||
@@ -403,24 +385,12 @@ TEST_F(OutgoingShareSessionTest, OnConnectResultFailureLogsSessionDuration) {
|
||||
IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, SendIntroductionWithoutPayloads) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
EXPECT_THAT(session_.SendIntroduction([]() {}), IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, SendIntroductionSuccess) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
EXPECT_THAT(InitSendAttachments(CreateDefaultAttachmentContainer()),
|
||||
IsTrue());
|
||||
session_.set_session_id(1234);
|
||||
NearbyConnectionImpl connection(device_info_);
|
||||
ConnectionSuccess(&connection);
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos;
|
||||
file_infos.push_back({
|
||||
.size = 12355L,
|
||||
.file_path = file1_.file_path().value(),
|
||||
});
|
||||
session_.CreateFilePayloads(file_infos);
|
||||
session_.CreateTextPayloads();
|
||||
session_.CreateWifiCredentialsPayloads();
|
||||
EXPECT_CALL(mock_event_logger_,
|
||||
Log(Matcher<const SharingLog&>(AllOf(
|
||||
(HasCategory(EventCategory::SENDING_EVENT),
|
||||
@@ -465,7 +435,7 @@ TEST_F(OutgoingShareSessionTest, SendIntroductionSuccess) {
|
||||
ASSERT_THAT(intro_frame.file_metadata_size(), Eq(1));
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).id(), Eq(file1_.id()));
|
||||
// File attachment size has been updated by CreateFilePayloads().
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).size(), Eq(file_infos[0].size));
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).size(), Eq(kFile1Size));
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).name(), Eq(file1_.file_name()));
|
||||
EXPECT_THAT(intro_frame.file_metadata(0).payload_id(),
|
||||
Eq(file_payloads[0].id));
|
||||
@@ -485,14 +455,15 @@ TEST_F(OutgoingShareSessionTest, SendIntroductionSuccess) {
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, SendIntroductionTimeout) {
|
||||
auto container = std::make_unique<AttachmentContainer>(
|
||||
std::vector<TextAttachment>{text1_}, std::vector<FileAttachment>{},
|
||||
std::vector<WifiCredentialsAttachment>{});
|
||||
InitSendAttachments(std::move(container));
|
||||
auto container =
|
||||
AttachmentContainer::Builder(std::vector<TextAttachment>{text1_},
|
||||
std::vector<FileAttachment>{},
|
||||
std::vector<WifiCredentialsAttachment>{})
|
||||
.Build();
|
||||
EXPECT_THAT(InitSendAttachments(std::move(container)), IsTrue());
|
||||
session_.set_session_id(1234);
|
||||
NearbyConnectionImpl connection(device_info_);
|
||||
ConnectionSuccess(&connection);
|
||||
session_.CreateTextPayloads();
|
||||
EXPECT_CALL(mock_event_logger_,
|
||||
Log(Matcher<const SharingLog&>(AllOf(
|
||||
(HasCategory(EventCategory::SENDING_EVENT),
|
||||
@@ -511,14 +482,15 @@ TEST_F(OutgoingShareSessionTest, SendIntroductionTimeout) {
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, SendIntroductionTimeoutCancelled) {
|
||||
auto container = std::make_unique<AttachmentContainer>(
|
||||
std::vector<TextAttachment>{text1_}, std::vector<FileAttachment>{},
|
||||
std::vector<WifiCredentialsAttachment>{});
|
||||
InitSendAttachments(std::move(container));
|
||||
auto container =
|
||||
AttachmentContainer::Builder(std::vector<TextAttachment>{text1_},
|
||||
std::vector<FileAttachment>{},
|
||||
std::vector<WifiCredentialsAttachment>{})
|
||||
.Build();
|
||||
EXPECT_THAT(InitSendAttachments(std::move(container)), IsTrue());
|
||||
session_.set_session_id(1234);
|
||||
NearbyConnectionImpl connection(device_info_);
|
||||
ConnectionSuccess(&connection);
|
||||
session_.CreateTextPayloads();
|
||||
EXPECT_CALL(mock_event_logger_,
|
||||
Log(Matcher<const SharingLog&>(AllOf(
|
||||
(HasCategory(EventCategory::SENDING_EVENT),
|
||||
@@ -561,14 +533,15 @@ TEST_F(OutgoingShareSessionTest, AcceptTransferNotReady) {
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, AcceptTransferSuccess) {
|
||||
auto container = std::make_unique<AttachmentContainer>(
|
||||
std::vector<TextAttachment>{text1_}, std::vector<FileAttachment>{},
|
||||
std::vector<WifiCredentialsAttachment>{});
|
||||
InitSendAttachments(std::move(container));
|
||||
auto container =
|
||||
AttachmentContainer::Builder(std::vector<TextAttachment>{text1_},
|
||||
std::vector<FileAttachment>{},
|
||||
std::vector<WifiCredentialsAttachment>{})
|
||||
.Build();
|
||||
EXPECT_THAT(InitSendAttachments(std::move(container)), IsTrue());
|
||||
session_.set_session_id(1234);
|
||||
NearbyConnectionImpl connection(device_info_);
|
||||
ConnectionSuccess(&connection);
|
||||
session_.CreateTextPayloads();
|
||||
EXPECT_CALL(mock_event_logger_,
|
||||
Log(Matcher<const SharingLog&>(AllOf(
|
||||
(HasCategory(EventCategory::SENDING_EVENT),
|
||||
@@ -669,16 +642,9 @@ TEST_F(OutgoingShareSessionTest, HandleConnectionResponseAcceptResponse) {
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, SendPayloads) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
EXPECT_THAT(InitSendAttachments(CreateDefaultAttachmentContainer()),
|
||||
IsTrue());
|
||||
session_.set_session_id(1234);
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos;
|
||||
file_infos.push_back({
|
||||
.size = 12355L,
|
||||
.file_path = file1_.file_path().value(),
|
||||
});
|
||||
session_.CreateFilePayloads(file_infos);
|
||||
session_.CreateTextPayloads();
|
||||
session_.CreateWifiCredentialsPayloads();
|
||||
MockFunction<void()> payload_transder_update_callback;
|
||||
StrictMock<MockFunction<void(
|
||||
std::unique_ptr<Payload>,
|
||||
@@ -715,16 +681,9 @@ TEST_F(OutgoingShareSessionTest, SendPayloads) {
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, SendPayloadsSetsAdvancedProtectionFlags) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
EXPECT_THAT(InitSendAttachments(CreateDefaultAttachmentContainer()),
|
||||
IsTrue());
|
||||
session_.set_session_id(1234);
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos;
|
||||
file_infos.push_back({
|
||||
.size = 12355L,
|
||||
.file_path = file1_.file_path().value(),
|
||||
});
|
||||
session_.CreateFilePayloads(file_infos);
|
||||
session_.CreateTextPayloads();
|
||||
session_.CreateWifiCredentialsPayloads();
|
||||
MockFunction<void()> payload_transder_update_callback;
|
||||
StrictMock<MockFunction<void(
|
||||
std::unique_ptr<Payload>,
|
||||
@@ -763,16 +722,9 @@ TEST_F(OutgoingShareSessionTest, SendPayloadsSetsAdvancedProtectionFlags) {
|
||||
}
|
||||
|
||||
TEST_F(OutgoingShareSessionTest, SendNextPayload) {
|
||||
InitSendAttachments(CreateDefaultAttachmentContainer());
|
||||
EXPECT_THAT(InitSendAttachments(CreateDefaultAttachmentContainer()),
|
||||
IsTrue());
|
||||
session_.set_session_id(1234);
|
||||
std::vector<NearbyFileHandler::FileInfo> file_infos;
|
||||
file_infos.push_back({
|
||||
.size = 12355L,
|
||||
.file_path = file1_.file_path().value(),
|
||||
});
|
||||
session_.CreateFilePayloads(file_infos);
|
||||
session_.CreateTextPayloads();
|
||||
session_.CreateWifiCredentialsPayloads();
|
||||
MockFunction<void()> payload_transder_update_callback;
|
||||
StrictMock<MockFunction<void(
|
||||
std::unique_ptr<Payload>,
|
||||
@@ -895,8 +847,10 @@ TEST_F(OutgoingShareSessionTest, DelayCompleteDisconnectTimeout) {
|
||||
NearbyConnectionImpl connection(device_info_);
|
||||
session_.set_session_id(1234);
|
||||
std::vector<uint8_t> endpoint_info = {1, 2, 3, 4};
|
||||
std::vector<uint8_t> bluetooth_mac_address = {5, 6, 7, 8};
|
||||
session_.Connect(endpoint_info, bluetooth_mac_address,
|
||||
EXPECT_CALL(transfer_metadata_callback_,
|
||||
Call(_, AllOf(HasStatus(TransferMetadata::Status::kConnecting),
|
||||
Not(IsFinalStatus()))));
|
||||
session_.Connect(endpoint_info,
|
||||
nearby::sharing::proto::DataUsage::ONLINE_DATA_USAGE,
|
||||
/*disable_wifi_hotspot=*/false,
|
||||
[&](absl::string_view endpoint_id,
|
||||
|
||||
+206
-162
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022-2023 Google LLC
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -16,22 +16,24 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/clock.h"
|
||||
#include "internal/platform/task_runner.h"
|
||||
#include "proto/sharing_enums.pb.h"
|
||||
#include "sharing/analytics/analytics_recorder.h"
|
||||
#include "sharing/certificates/nearby_share_decrypted_public_certificate.h"
|
||||
#include "sharing/flags/generated/nearby_sharing_feature_flags.h"
|
||||
#include "sharing/internal/public/logging.h"
|
||||
#include "sharing/nearby_connections_manager.h"
|
||||
#include "sharing/outgoing_share_session.h"
|
||||
@@ -45,157 +47,188 @@
|
||||
namespace nearby::sharing {
|
||||
|
||||
OutgoingTargetsManager::OutgoingTargetsManager(
|
||||
Clock* clock, TaskRunner* service_thread,
|
||||
NearbyConnectionsManager* connections_manager,
|
||||
Clock* absl_nonnull clock, TaskRunner* absl_nonnull service_thread,
|
||||
NearbyConnectionsManager* absl_nonnull connections_manager,
|
||||
analytics::AnalyticsRecorder* analytics_recorder,
|
||||
absl::AnyInvocable<void(const ShareTarget&)>
|
||||
share_target_discovered_callback,
|
||||
absl::AnyInvocable<void(const ShareTarget&)> share_target_updated_callback,
|
||||
absl::AnyInvocable<void(const ShareTarget&)> share_target_lost_callback)
|
||||
absl::AnyInvocable<void(const ShareTarget&)> share_target_lost_callback,
|
||||
std::function<void(OutgoingShareSession& session,
|
||||
const TransferMetadata& metadata)>
|
||||
transfer_update_callback)
|
||||
: clock_(*clock),
|
||||
service_thread_(*service_thread),
|
||||
connections_manager_(*connections_manager),
|
||||
analytics_recorder_(*analytics_recorder),
|
||||
share_target_discovered_callback_(
|
||||
std::move(share_target_discovered_callback)),
|
||||
share_target_updated_callback_(std::move(share_target_updated_callback)),
|
||||
share_target_lost_callback_(std::move(share_target_lost_callback)) {}
|
||||
share_target_lost_callback_(std::move(share_target_lost_callback)),
|
||||
transfer_update_callback_(std::move(transfer_update_callback)) {}
|
||||
|
||||
|
||||
void OutgoingTargetsManager::DeduplicateInOutgoingShareTarget(
|
||||
const ShareTarget& share_target, absl::string_view endpoint_id,
|
||||
void OutgoingTargetsManager::OnShareTargetDiscovered(
|
||||
ShareTarget share_target, absl::string_view endpoint_id,
|
||||
std::optional<NearbyShareDecryptedPublicCertificate> certificate) {
|
||||
// TODO(b/343764269): may need to update last_outgoing_metadata_ if the
|
||||
// deduped target id matches the one in last_outgoing_metadata_.
|
||||
// But since we do not modify the share target of a connected session, it may
|
||||
// not happen.
|
||||
|
||||
auto session_it = outgoing_share_session_map_.find(share_target.id);
|
||||
if (session_it == outgoing_share_session_map_.end()) {
|
||||
LOG(WARNING) << __func__ << ": share_target.id=" << share_target.id
|
||||
<< " not found in outgoing share session map.";
|
||||
std::optional<int64_t> old_id =
|
||||
FindExistingTargetId(endpoint_id, share_target);
|
||||
if (old_id.has_value()) {
|
||||
// If the duplicate is found, share_target.id needs to be updated to the old
|
||||
// "discovered" share_target_id so ShareTarget updates matches a target
|
||||
// that was discovered before.
|
||||
share_target.id = *old_id;
|
||||
LOG(INFO) << __func__
|
||||
<< ": ShareTarget updated, endpoint_id: " << endpoint_id
|
||||
<< ", share_target: " << share_target.ToString();
|
||||
auto session_it = outgoing_share_session_map_.find(*old_id);
|
||||
if (session_it != outgoing_share_session_map_.end()) {
|
||||
OutgoingShareSession& session = session_it->second;
|
||||
std::string old_endpoint_id = session.endpoint_id();
|
||||
if (session.UpdateSessionForDedup(share_target, std::move(certificate),
|
||||
endpoint_id) &&
|
||||
old_endpoint_id != endpoint_id) {
|
||||
// Session updated and endpoint_id changed. Need to update endpoint id
|
||||
// to share target id mapping.
|
||||
outgoing_target_id_map_.erase(old_endpoint_id);
|
||||
outgoing_target_id_map_.insert(
|
||||
{std::string(endpoint_id), share_target.id});
|
||||
}
|
||||
}
|
||||
share_target_updated_callback_(share_target);
|
||||
return;
|
||||
}
|
||||
if (session_it->second.IsConnected()) {
|
||||
LOG(INFO) << __func__ << ": share_target.id=" << share_target.id
|
||||
<< " is connected, not updating outgoing_share_session_map_.";
|
||||
return;
|
||||
old_id = FindInDiscoveryCache(endpoint_id, share_target);
|
||||
bool in_discovery_cache = old_id.has_value();
|
||||
if (in_discovery_cache) {
|
||||
share_target.id = *old_id;
|
||||
}
|
||||
session_it->second.UpdateSessionForDedup(share_target, std::move(certificate),
|
||||
endpoint_id);
|
||||
|
||||
share_target_updated_callback_(share_target);
|
||||
|
||||
LOG(INFO) << __func__
|
||||
<< ": [Dedupped] NotifyShareTargetUpdated to all surfaces "
|
||||
"for share_target: "
|
||||
<< share_target.ToString();
|
||||
<< (in_discovery_cache ? ": Recovered from discovery cache"
|
||||
: ": Discovered new target")
|
||||
<< ": endpoint_id=" << endpoint_id
|
||||
<< ", share_target=" << share_target.ToString();
|
||||
AddTarget(share_target, endpoint_id, std::move(certificate));
|
||||
if (in_discovery_cache) {
|
||||
share_target_updated_callback_(share_target);
|
||||
} else {
|
||||
share_target_discovered_callback_(share_target);
|
||||
}
|
||||
}
|
||||
|
||||
bool OutgoingTargetsManager::FindDuplicateInDiscoveryCache(
|
||||
absl::string_view endpoint_id, ShareTarget& share_target) {
|
||||
std::optional<int64_t> OutgoingTargetsManager::FindInDiscoveryCache(
|
||||
absl::string_view endpoint_id, const ShareTarget& share_target) {
|
||||
auto it = discovery_cache_.find(endpoint_id);
|
||||
if (it != discovery_cache_.end()) {
|
||||
int64_t old_id = it->second.share_target.id;
|
||||
// If endpoint info changes for an endpoint ID, NC will send a rediscovery
|
||||
// event for the same endpoint id.
|
||||
LOG(INFO) << __func__
|
||||
<< ": [Dedupped] Found duplicate endpoint_id: " << endpoint_id
|
||||
<< ", share_target.id changed from: " << share_target.id << " to "
|
||||
<< it->second.share_target.id;
|
||||
share_target.id = it->second.share_target.id;
|
||||
LOG(INFO) << __func__ << ": Found existing endpoint_id: " << endpoint_id
|
||||
<< ", mapping share_target.id: " << share_target.id
|
||||
<< " to: " << it->second.share_target.id;
|
||||
discovery_cache_.erase(it);
|
||||
return true;
|
||||
return old_id;
|
||||
}
|
||||
|
||||
for (auto it = discovery_cache_.begin(); it != discovery_cache_.end(); ++it) {
|
||||
if (it->second.share_target.device_id == share_target.device_id) {
|
||||
LOG(INFO) << __func__
|
||||
<< ": [Dedupped] Found duplicate device_id, share_target.id "
|
||||
"changed from: "
|
||||
<< share_target.id << " to " << it->second.share_target.id
|
||||
<< ". New endpoint_id: " << endpoint_id;
|
||||
// Share targets in discovery cache have receive_disabled set to true.
|
||||
// Copy only the id field from cache entry,
|
||||
share_target.id = it->second.share_target.id;
|
||||
discovery_cache_.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OutgoingTargetsManager::FindDuplicateInOutgoingShareTargets(
|
||||
absl::string_view endpoint_id, ShareTarget& share_target) {
|
||||
// If the duplicate is found, share_target.id needs to be updated to the old
|
||||
// "discovered" share_target_id so NotifyShareTargetUpdated matches a target
|
||||
// that was discovered before.
|
||||
|
||||
auto it = outgoing_share_target_map_.find(endpoint_id);
|
||||
if (it != outgoing_share_target_map_.end()) {
|
||||
// If endpoint info changes for an endpoint ID, NC will send a rediscovery
|
||||
// event for the same endpoint id.
|
||||
LOG(INFO) << __func__
|
||||
<< ": [Dedupped] Found duplicate endpoint_id: " << endpoint_id
|
||||
<< " in outgoing_share_target_map, share_target.id changed from: "
|
||||
<< share_target.id << " to " << it->second.id;
|
||||
share_target.id = it->second.id;
|
||||
it->second = share_target;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto it = outgoing_share_target_map_.begin();
|
||||
it != outgoing_share_target_map_.end(); ++it) {
|
||||
if (it->second.device_id == share_target.device_id) {
|
||||
LOG(INFO)
|
||||
<< __func__
|
||||
<< ": [Dedupped] Found duplicate device_id, endpoint ID "
|
||||
"changed from: "
|
||||
<< it->first << " to " << endpoint_id
|
||||
<< " in outgoing_share_target_map, share_target.id changed from: "
|
||||
<< share_target.id << " to " << it->second.id;
|
||||
share_target.id = it->second.id;
|
||||
outgoing_share_target_map_.erase(it);
|
||||
outgoing_share_target_map_.insert_or_assign(endpoint_id, share_target);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<ShareTarget>
|
||||
OutgoingTargetsManager::RemoveOutgoingShareTargetWithEndpointId(
|
||||
absl::string_view endpoint_id) {
|
||||
VLOG(1) << __func__ << ":Outgoing connection to " << endpoint_id
|
||||
<< " disconnected";
|
||||
auto target_node = outgoing_share_target_map_.extract(endpoint_id);
|
||||
if (target_node.empty()) {
|
||||
LOG(WARNING) << __func__ << ": endpoint_id=" << endpoint_id
|
||||
<< " not found in outgoing share target map.";
|
||||
if (share_target.device_id.empty()) {
|
||||
// Do not match empty device_id.
|
||||
return std::nullopt;
|
||||
}
|
||||
ShareTarget& share_target = target_node.mapped();
|
||||
VLOG(1) << __func__ << ": Removing (endpoint_id=" << endpoint_id
|
||||
<< ", share_target.id=" << target_node.mapped().id
|
||||
<< ") from outgoing share target map";
|
||||
auto device_id_it = std::find_if(
|
||||
discovery_cache_.begin(), discovery_cache_.end(),
|
||||
[&share_target](const auto& pair) {
|
||||
return pair.second.share_target.device_id == share_target.device_id;
|
||||
});
|
||||
if (device_id_it != discovery_cache_.end()) {
|
||||
int64_t old_id = device_id_it->second.share_target.id;
|
||||
LOG(INFO) << __func__
|
||||
<< ": Found existing device_id, updating endpoint ID: "
|
||||
<< device_id_it->first << " to: " << endpoint_id
|
||||
<< " , mapping share_target.id: " << share_target.id
|
||||
<< " to: " << old_id;
|
||||
discovery_cache_.erase(device_id_it);
|
||||
return old_id;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<int64_t> OutgoingTargetsManager::FindExistingTargetId(
|
||||
absl::string_view endpoint_id,
|
||||
const ShareTarget& share_target) {
|
||||
auto it = outgoing_target_id_map_.find(endpoint_id);
|
||||
if (it != outgoing_target_id_map_.end()) {
|
||||
int64_t old_share_target_id = it->second;
|
||||
// If endpoint info changes for an endpoint ID, NC will send a rediscovery
|
||||
// event for the same endpoint id.
|
||||
LOG(INFO) << __func__ << ": Found existing endpoint_id: " << endpoint_id
|
||||
<< ", mapping share_target.id: " << share_target.id
|
||||
<< " to: " << old_share_target_id;
|
||||
return old_share_target_id;
|
||||
}
|
||||
|
||||
if (share_target.device_id.empty()) {
|
||||
// Do not match empty device_id.
|
||||
return std::nullopt;
|
||||
}
|
||||
auto device_id_it = std::find_if(
|
||||
outgoing_share_session_map_.begin(), outgoing_share_session_map_.end(),
|
||||
[&share_target](const auto& pair) {
|
||||
return pair.second.share_target().device_id == share_target.device_id;
|
||||
});
|
||||
if (device_id_it != outgoing_share_session_map_.end()) {
|
||||
int64_t old_share_target_id = device_id_it->second.share_target().id;
|
||||
LOG(INFO) << __func__
|
||||
<< ": Found existing device_id, updating endpoint ID: "
|
||||
<< device_id_it->first << " to: " << endpoint_id
|
||||
<< " , mapping share_target.id: " << share_target.id
|
||||
<< " to: " << old_share_target_id;
|
||||
return old_share_target_id;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<ShareTarget> OutgoingTargetsManager::RemoveTarget(
|
||||
absl::string_view endpoint_id, bool close_connected) {
|
||||
VLOG(1) << __func__ << ":Removing endpoint_id " << endpoint_id;
|
||||
auto it = outgoing_target_id_map_.find(endpoint_id);
|
||||
if (it == outgoing_target_id_map_.end()) {
|
||||
LOG(WARNING) << __func__ << ": endpoint_id=" << endpoint_id
|
||||
<< " not found.";
|
||||
return std::nullopt;
|
||||
}
|
||||
int64_t share_target_id = it->second;
|
||||
auto session_it = outgoing_share_session_map_.find(share_target_id);
|
||||
if (session_it == outgoing_share_session_map_.end()) {
|
||||
LOG(ERROR) << __func__ << ": share_target.id=" << share_target_id
|
||||
<< " not found in outgoing share session map.";
|
||||
outgoing_target_id_map_.erase(it);
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!close_connected && session_it->second.IsActive()) {
|
||||
LOG(INFO) << __func__ << ": share_target.id=" << share_target_id
|
||||
<< " is active, not removing.";
|
||||
return std::nullopt;
|
||||
}
|
||||
VLOG(1) << __func__
|
||||
<< ": Removing share_target.id=" << share_target_id
|
||||
<< " from outgoing share target map";
|
||||
outgoing_target_id_map_.erase(it);
|
||||
// Do not destroy the session until it has been removed from the map.
|
||||
// Session destruction can trigger callbacks that traverses the map and it
|
||||
// cannot access the map while it is being modified.
|
||||
auto session_node =
|
||||
outgoing_share_session_map_.extract(target_node.mapped().id);
|
||||
if (!session_node.empty()) {
|
||||
session_node.mapped().OnDisconnect();
|
||||
} else {
|
||||
LOG(WARNING) << __func__ << ": share_target.id=" << target_node.mapped().id
|
||||
<< " not found in outgoing share session map.";
|
||||
}
|
||||
return share_target;
|
||||
auto session_node = outgoing_share_session_map_.extract(session_it);
|
||||
ShareTarget removed_target = session_node.mapped().share_target();
|
||||
session_node.mapped().OnDisconnect();
|
||||
return std::move(removed_target);
|
||||
}
|
||||
|
||||
// Pass endpoint_id by value here since we remove entries from the
|
||||
// outgoing_share_target_map_ in this function, and some callers like
|
||||
// DisableAllOutgoingShareTargets pass the map item key as the endpoint_id.
|
||||
// outgoing_target_id_map_ in this function, and some callers like
|
||||
// AllTargetsLost pass the map item key as the endpoint_id.
|
||||
// This prevents the endpoint_id from being invalidated in this function.
|
||||
void OutgoingTargetsManager::MoveToDiscoveryCache(std::string endpoint_id,
|
||||
uint64_t expiry_ms) {
|
||||
void OutgoingTargetsManager::OnShareTargetLost(std::string endpoint_id,
|
||||
absl::Duration retention) {
|
||||
std::optional<ShareTarget> share_target_opt =
|
||||
RemoveOutgoingShareTargetWithEndpointId(endpoint_id);
|
||||
RemoveTarget(endpoint_id, /*close_connected=*/false);
|
||||
if (!share_target_opt.has_value()) {
|
||||
return;
|
||||
}
|
||||
@@ -205,8 +238,7 @@ void OutgoingTargetsManager::MoveToDiscoveryCache(std::string endpoint_id,
|
||||
cache_entry.share_target.receive_disabled = true;
|
||||
cache_entry.expiry_timer = std::make_unique<ThreadTimer>(
|
||||
service_thread_, absl::StrCat("discovery_cache_timeout_", endpoint_id),
|
||||
absl::Milliseconds(expiry_ms),
|
||||
[this, expiry_ms, endpoint_id = std::string(endpoint_id)]() {
|
||||
retention, [this, retention, endpoint_id]() {
|
||||
auto cache_node = discovery_cache_.extract(endpoint_id);
|
||||
if (cache_node.empty()) {
|
||||
LOG(WARNING) << "Trying to remove endpoint_id: " << endpoint_id
|
||||
@@ -214,46 +246,54 @@ void OutgoingTargetsManager::MoveToDiscoveryCache(std::string endpoint_id,
|
||||
return;
|
||||
}
|
||||
ShareTarget& share_target = cache_node.mapped().share_target;
|
||||
LOG(INFO) << ": Removing (endpoint_id=" << endpoint_id
|
||||
<< ", share_target.id=" << share_target.id
|
||||
<< ") from discovery_cache after " << expiry_ms << "ms";
|
||||
|
||||
LOG(INFO) << ": ShareTarget lost after retention: " << retention
|
||||
<< ", endpoint_id=" << endpoint_id
|
||||
<< ", share_target=" << share_target.ToString();
|
||||
share_target_lost_callback_(share_target);
|
||||
|
||||
VLOG(1) << "discovery_cache entry: " << endpoint_id << " timeout after "
|
||||
<< expiry_ms << "ms"
|
||||
<< ": [Dedupped] NotifyShareTargetLost to all surfaces for "
|
||||
<< "share_target: " << share_target.ToString();
|
||||
});
|
||||
// Send ShareTarget update to set receive disabled to true.
|
||||
LOG(INFO) << __func__
|
||||
<< ": ShareTarget disabled, endpoint_id: " << endpoint_id << ", "
|
||||
<< cache_entry.share_target.ToString();
|
||||
share_target_updated_callback_(cache_entry.share_target);
|
||||
auto [it, inserted] =
|
||||
discovery_cache_.insert_or_assign(endpoint_id, std::move(cache_entry));
|
||||
LOG(INFO) << "[Dedupped] added to discovery_cache: " << endpoint_id << " by "
|
||||
<< (inserted ? "insert" : "assign");
|
||||
discovery_cache_.insert_or_assign(endpoint_id, std::move(cache_entry));
|
||||
}
|
||||
|
||||
void OutgoingTargetsManager::CreateOutgoingShareSession(
|
||||
void OutgoingTargetsManager::AddTarget(
|
||||
const ShareTarget& share_target, absl::string_view endpoint_id,
|
||||
std::optional<NearbyShareDecryptedPublicCertificate> certificate,
|
||||
absl::AnyInvocable<void(OutgoingShareSession& session,
|
||||
const TransferMetadata& metadata)>
|
||||
transfer_update_callback) {
|
||||
outgoing_share_target_map_.insert_or_assign(endpoint_id, share_target);
|
||||
auto [it_out, inserted] = outgoing_share_session_map_.try_emplace(
|
||||
std::optional<NearbyShareDecryptedPublicCertificate> certificate) {
|
||||
auto [target_it, target_inserted] = outgoing_target_id_map_.insert(
|
||||
{std::string(endpoint_id), share_target.id});
|
||||
if (!target_inserted) {
|
||||
if (target_it->second != share_target.id) {
|
||||
LOG(ERROR) << __func__ << ": endpoint_id=" << endpoint_id
|
||||
<< " already associated with share_target id="
|
||||
<< target_it->second
|
||||
<< ", cannot replace with share_target id=" << share_target.id;
|
||||
return;
|
||||
}
|
||||
LOG(WARNING) << __func__ << ": endpoint_id=" << endpoint_id
|
||||
<< " already exists, share target not updated.";
|
||||
}
|
||||
auto [session_it, session_inserted] = outgoing_share_session_map_.try_emplace(
|
||||
share_target.id, &clock_, service_thread_, &connections_manager_,
|
||||
analytics_recorder_, std::string(endpoint_id), share_target,
|
||||
std::move(transfer_update_callback));
|
||||
if (!inserted) {
|
||||
transfer_update_callback_);
|
||||
if (!session_inserted) {
|
||||
LOG(WARNING) << __func__ << ": share_target.id=" << share_target.id
|
||||
<< " already exists in outgoing share session map. This "
|
||||
"should NOT happen";
|
||||
} else {
|
||||
auto& session = it_out->second;
|
||||
if (certificate.has_value()) {
|
||||
session.set_certificate(std::move(*certificate));
|
||||
if (session_it->second.IsConnected()) {
|
||||
LOG(WARNING) << __func__
|
||||
<< ": session for share_target.id=" << share_target.id
|
||||
<< " is connected, certificate not updated.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto& session = session_it->second;
|
||||
if (certificate.has_value()) {
|
||||
session.set_certificate(std::move(*certificate));
|
||||
}
|
||||
}
|
||||
|
||||
OutgoingShareSession* OutgoingTargetsManager::GetOutgoingShareSession(
|
||||
@@ -266,22 +306,26 @@ OutgoingShareSession* OutgoingTargetsManager::GetOutgoingShareSession(
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
void OutgoingTargetsManager::DisableAllOutgoingShareTargets() {
|
||||
void OutgoingTargetsManager::AllTargetsLost(absl::Duration retention) {
|
||||
VLOG(1) << "Move all outgoing share targets to discovery cache.";
|
||||
while (!outgoing_share_target_map_.empty()) {
|
||||
MoveToDiscoveryCache(outgoing_share_target_map_.begin()->first,
|
||||
NearbyFlags::GetInstance().GetInt64Flag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
kUnregisterTargetDiscoveryCacheLostExpiryMs));
|
||||
std::vector<std::string> endpoint_ids_to_remove;
|
||||
endpoint_ids_to_remove.reserve(outgoing_target_id_map_.size());
|
||||
for (const auto& [endpoint_id, share_target_id] : outgoing_target_id_map_) {
|
||||
endpoint_ids_to_remove.push_back(endpoint_id);
|
||||
}
|
||||
for (const auto& endpoint_id : endpoint_ids_to_remove) {
|
||||
OnShareTargetLost(endpoint_id, retention);
|
||||
}
|
||||
DCHECK(outgoing_share_target_map_.empty());
|
||||
DCHECK(outgoing_share_session_map_.empty());
|
||||
}
|
||||
|
||||
void OutgoingTargetsManager::Cleanup() {
|
||||
while (!outgoing_share_target_map_.empty()) {
|
||||
RemoveOutgoingShareTargetWithEndpointId(
|
||||
outgoing_share_target_map_.begin()->first);
|
||||
std::vector<std::string> endpoint_ids_to_remove;
|
||||
endpoint_ids_to_remove.reserve(outgoing_target_id_map_.size());
|
||||
for (const auto& [endpoint_id, share_target_id] : outgoing_target_id_map_) {
|
||||
endpoint_ids_to_remove.push_back(endpoint_id);
|
||||
}
|
||||
for (const auto& endpoint_id : endpoint_ids_to_remove) {
|
||||
RemoveTarget(endpoint_id, /*close_connected=*/true);
|
||||
}
|
||||
discovery_cache_.clear();
|
||||
}
|
||||
@@ -293,8 +337,8 @@ void OutgoingTargetsManager::ForEachShareTarget(
|
||||
for (const auto& [endpoint_id, discovery_cache_entry] : discovery_cache_) {
|
||||
callback(discovery_cache_entry.share_target);
|
||||
}
|
||||
for (const auto& [endpoint_id, share_target] : outgoing_share_target_map_) {
|
||||
callback(share_target);
|
||||
for (const auto& [target_id, session] : outgoing_share_session_map_) {
|
||||
callback(session.share_target());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022-2023 Google LLC
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -18,13 +18,16 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/clock.h"
|
||||
#include "internal/platform/task_runner.h"
|
||||
#include "proto/sharing_enums.pb.h"
|
||||
@@ -39,67 +42,81 @@
|
||||
#include "sharing/transfer_metadata.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
class NearbyShareContactManager;
|
||||
|
||||
namespace NearbySharingServiceUnitTests {
|
||||
class NearbySharingServiceImplTest_CreateShareTarget_Test;
|
||||
class NearbySharingServiceImplTest_RemoveIncomingPayloads_Test;
|
||||
}; // namespace NearbySharingServiceUnitTests
|
||||
|
||||
// Manages outgoing share targets and outgoing share sessions.
|
||||
//
|
||||
// This class is thread-compatible. All methods must be called on the service
|
||||
// thread.
|
||||
//
|
||||
// Each discovered share target has a corresponding outgoing share session.
|
||||
// When the share target is lost, the share target is moved to the
|
||||
// discovery cache and the share session is destroyed. The lost share target
|
||||
// is reported as receive_disabled. After a retention period, the share target
|
||||
// is removed from the discovery cache.
|
||||
// Newly discovered share targets that match share targets in the discovery
|
||||
// cache are merged with the discovery cache entry and a new share session is
|
||||
// created. The share target is then removed from the discovery cache and
|
||||
// reported as receive_enabled.
|
||||
class OutgoingTargetsManager {
|
||||
public:
|
||||
OutgoingTargetsManager(
|
||||
Clock* clock, TaskRunner* service_thread,
|
||||
NearbyConnectionsManager* connections_manager,
|
||||
analytics::AnalyticsRecorder* analytics_recorder,
|
||||
Clock* absl_nonnull clock, TaskRunner* absl_nonnull service_thread,
|
||||
NearbyConnectionsManager* absl_nonnull connections_manager,
|
||||
analytics::AnalyticsRecorder* absl_nonnull analytics_recorder,
|
||||
absl::AnyInvocable<void(const ShareTarget&)>
|
||||
share_target_discovered_callback,
|
||||
absl::AnyInvocable<void(const ShareTarget&)>
|
||||
share_target_updated_callback,
|
||||
absl::AnyInvocable<void(const ShareTarget&)> share_target_lost_callback);
|
||||
absl::AnyInvocable<void(const ShareTarget&)> share_target_lost_callback,
|
||||
std::function<void(OutgoingShareSession& session,
|
||||
const TransferMetadata& metadata)>
|
||||
transfer_update_callback);
|
||||
|
||||
// Remove all outgoing share targets and outgoing share sessions.
|
||||
// Share targets callbacks will not be called.
|
||||
// Any connected sessions will be disconnected.
|
||||
void Cleanup();
|
||||
|
||||
OutgoingShareSession* GetOutgoingShareSession(int64_t share_target_id);
|
||||
|
||||
// Update the entry in outgoing_share_session_map_ with the new share target
|
||||
// and OnShareTargetUpdated is called.
|
||||
void DeduplicateInOutgoingShareTarget(
|
||||
const ShareTarget& share_target, absl::string_view endpoint_id,
|
||||
void OnShareTargetDiscovered(
|
||||
ShareTarget share_target, absl::string_view endpoint_id,
|
||||
std::optional<NearbyShareDecryptedPublicCertificate> certificate);
|
||||
|
||||
// Looks for a duplicate of the share target in the discovery cache.
|
||||
// If found, the share target is removed from the discovery cache and its
|
||||
// id is copied into `share_target`.
|
||||
// Returns true if the duplicate is found.
|
||||
bool FindDuplicateInDiscoveryCache(absl::string_view endpoint_id,
|
||||
ShareTarget& share_target);
|
||||
// Move the endpoint to the discovery cache and report the share target as
|
||||
// receive_disabled.
|
||||
// `retention` is the time to keep the share target in the discovery cache.
|
||||
void OnShareTargetLost(std::string endpoint_id, absl::Duration retention);
|
||||
|
||||
// Looks for a duplicate of the share target in the outgoing share
|
||||
// target map. The share target's id is changed to match an existing target if
|
||||
// available. Returns true if the duplicate is found.
|
||||
bool FindDuplicateInOutgoingShareTargets(absl::string_view endpoint_id,
|
||||
ShareTarget& share_target);
|
||||
|
||||
// Move the endpoint to the discovery cache with the given expiry time.
|
||||
void MoveToDiscoveryCache(std::string endpoint_id, uint64_t expiry_ms);
|
||||
|
||||
// Move all outgoing share targets to the discovery cache so that they will be
|
||||
// reported as receive_disabled.
|
||||
void DisableAllOutgoingShareTargets();
|
||||
|
||||
void CreateOutgoingShareSession(
|
||||
const ShareTarget& share_target, absl::string_view endpoint_id,
|
||||
std::optional<NearbyShareDecryptedPublicCertificate> certificate,
|
||||
absl::AnyInvocable<void(OutgoingShareSession& session,
|
||||
const TransferMetadata& metadata)>
|
||||
transfer_update_callback);
|
||||
// Call OnShareTargetLost() on all known share targets.
|
||||
void AllTargetsLost(absl::Duration retention);
|
||||
|
||||
void ForEachShareTarget(
|
||||
absl::AnyInvocable<void(const ShareTarget&)> callback);
|
||||
|
||||
private:
|
||||
// If an existing target matching either endpoint_id or share_target.device_id
|
||||
// is found, the existing share target id is returned.
|
||||
// Otherwise, std::nullopt is returned.
|
||||
std::optional<int64_t> FindExistingTargetId(
|
||||
absl::string_view endpoint_id,
|
||||
const ShareTarget& share_target);
|
||||
|
||||
// Looks for existing share target in the discovery cache.
|
||||
// If found, the share target is removed from the discovery cache and its
|
||||
// id is returned.
|
||||
// Otherwise, std::nullopt is returned.
|
||||
std::optional<int64_t> FindInDiscoveryCache(absl::string_view endpoint_id,
|
||||
const ShareTarget& share_target);
|
||||
|
||||
void AddTarget(
|
||||
const ShareTarget& share_target, absl::string_view endpoint_id,
|
||||
std::optional<NearbyShareDecryptedPublicCertificate> certificate);
|
||||
|
||||
// Returns the share target if it has been removed, std::nullopt otherwise.
|
||||
std::optional<ShareTarget> RemoveOutgoingShareTargetWithEndpointId(
|
||||
absl::string_view endpoint_id);
|
||||
// If `close_connected` is false, connected session will not be closed.
|
||||
std::optional<ShareTarget> RemoveTarget(absl::string_view endpoint_id,
|
||||
bool close_connected);
|
||||
|
||||
// Cache a recently lost share target to be re-discovered.
|
||||
// Purged after expiry_timer.
|
||||
@@ -113,13 +130,16 @@ class OutgoingTargetsManager {
|
||||
TaskRunner& service_thread_;
|
||||
NearbyConnectionsManager& connections_manager_;
|
||||
analytics::AnalyticsRecorder& analytics_recorder_;
|
||||
absl::AnyInvocable<void(const ShareTarget&)>
|
||||
share_target_discovered_callback_;
|
||||
absl::AnyInvocable<void(const ShareTarget&)> share_target_updated_callback_;
|
||||
absl::AnyInvocable<void(const ShareTarget&)> share_target_lost_callback_;
|
||||
|
||||
// A map of endpoint id to ShareTarget, where each ShareTarget entry
|
||||
// directly corresponds to a OutgoingShareSession entry in
|
||||
// outgoing_share_target_info_map_;
|
||||
absl::flat_hash_map<std::string, ShareTarget> outgoing_share_target_map_;
|
||||
std::function<void(OutgoingShareSession& session,
|
||||
const TransferMetadata& metadata)>
|
||||
transfer_update_callback_;
|
||||
// A map of endpoint id to ShareTarget id, where each ShareTarget id refers to
|
||||
// an OutgoingShareSession entry in outgoing_share_target_info_map_;
|
||||
absl::flat_hash_map<std::string, int64_t> outgoing_target_id_map_;
|
||||
// A map of ShareTarget id to OutgoingShareSession. This lets us know which
|
||||
// endpoint and public certificate are related to the outgoing share target.
|
||||
absl::flat_hash_map<int64_t, OutgoingShareSession>
|
||||
|
||||
@@ -0,0 +1,785 @@
|
||||
// Copyright 2025 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/outgoing_targets_manager.h"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/test/fake_clock.h"
|
||||
#include "internal/test/fake_device_info.h"
|
||||
#include "internal/test/fake_task_runner.h"
|
||||
#include "sharing/analytics/analytics_recorder.h"
|
||||
#include "sharing/attachment_container.h"
|
||||
#include "sharing/fake_nearby_connections_manager.h"
|
||||
#include "sharing/nearby_connection_impl.h"
|
||||
#include "sharing/nearby_connections_types.h"
|
||||
#include "sharing/outgoing_share_session.h"
|
||||
#include "sharing/share_target.h"
|
||||
#include "sharing/text_attachment.h"
|
||||
#include "sharing/transfer_metadata.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
namespace {
|
||||
using ::absl::Seconds;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::InSequence;
|
||||
using ::testing::SizeIs;
|
||||
|
||||
class OutgoingTargetsManagerTest : public ::testing::Test {
|
||||
protected:
|
||||
OutgoingTargetsManagerTest()
|
||||
: service_thread_(&clock_, /*count=*/1),
|
||||
analytics_recorder_(/*vendor_id=*/0,
|
||||
/*event_logger=*/nullptr),
|
||||
outgoing_targets_manager_(
|
||||
&clock_, &service_thread_, &connections_manager_,
|
||||
&analytics_recorder_,
|
||||
share_target_discovered_callback_.AsStdFunction(),
|
||||
share_target_updated_callback_.AsStdFunction(),
|
||||
share_target_lost_callback_.AsStdFunction(),
|
||||
transfer_update_callback_.AsStdFunction()) {}
|
||||
|
||||
FakeClock clock_;
|
||||
FakeTaskRunner service_thread_;
|
||||
FakeNearbyConnectionsManager connections_manager_;
|
||||
analytics::AnalyticsRecorder analytics_recorder_;
|
||||
testing::MockFunction<void(const ShareTarget&)>
|
||||
share_target_discovered_callback_;
|
||||
testing::MockFunction<void(const ShareTarget&)>
|
||||
share_target_updated_callback_;
|
||||
testing::MockFunction<void(const ShareTarget&)> share_target_lost_callback_;
|
||||
testing::MockFunction<void(OutgoingShareSession&, const TransferMetadata&)>
|
||||
transfer_update_callback_;
|
||||
FakeDeviceInfo device_info_;
|
||||
OutgoingTargetsManager outgoing_targets_manager_;
|
||||
};
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, onShareTargetDiscoveredNewTarget) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr absl::string_view kEndpointId = "endpoint_id";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call).Times(0);
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId, /*certificate=*/std::nullopt);
|
||||
|
||||
OutgoingShareSession* session =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
EXPECT_NE(session, nullptr);
|
||||
EXPECT_EQ(session->share_target(), target);
|
||||
EXPECT_EQ(session->endpoint_id(), kEndpointId);
|
||||
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, onShareTargetLost) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr absl::string_view kEndpointId = "endpoint_id";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
ShareTarget disabled_target = target;
|
||||
disabled_target.receive_disabled = true;
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, disabled_target);
|
||||
});
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(1);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId, /*certificate=*/std::nullopt);
|
||||
EXPECT_NE(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
|
||||
outgoing_targets_manager_.OnShareTargetLost(std::string(kEndpointId),
|
||||
Seconds(10));
|
||||
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, disabled_target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
|
||||
// Retention timer expired.
|
||||
clock_.FastForward(Seconds(10));
|
||||
service_thread_.Sync();
|
||||
|
||||
has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) { has_targets = true; });
|
||||
EXPECT_FALSE(has_targets);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, onShareTargetLostConnectedNotClosed) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr absl::string_view kEndpointId = "endpoint_id";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call).Times(0);
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId, /*certificate=*/std::nullopt);
|
||||
OutgoingShareSession* session =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
ASSERT_NE(session, nullptr);
|
||||
NearbyConnectionImpl connection(device_info_);
|
||||
session->OnConnectResult(&connection, Status::kSuccess);
|
||||
ASSERT_TRUE(session->IsConnected());
|
||||
|
||||
outgoing_targets_manager_.OnShareTargetLost(std::string(kEndpointId),
|
||||
Seconds(10));
|
||||
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
session = outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
ASSERT_NE(session, nullptr);
|
||||
EXPECT_TRUE(session->IsConnected());
|
||||
|
||||
// Retention timer expired.
|
||||
clock_.FastForward(Seconds(10));
|
||||
service_thread_.Sync();
|
||||
|
||||
has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
session = outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
ASSERT_NE(session, nullptr);
|
||||
EXPECT_TRUE(session->IsConnected());
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, onShareTargetLostConnectingNotClosed) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr absl::string_view kEndpointId = "endpoint_id";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call).Times(0);
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId, /*certificate=*/std::nullopt);
|
||||
OutgoingShareSession* session =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
ASSERT_NE(session, nullptr);
|
||||
// InitiateSendAttachments is called when session starts connecting.
|
||||
session->InitiateSendAttachments(
|
||||
AttachmentContainer::Builder()
|
||||
.AddTextAttachment(TextAttachment(
|
||||
nearby::sharing::service::proto::TextMetadata::ADDRESS,
|
||||
"A bit of text body 2", "Some text title 2", "text/plain"))
|
||||
.Build());
|
||||
|
||||
outgoing_targets_manager_.OnShareTargetLost(std::string(kEndpointId),
|
||||
Seconds(10));
|
||||
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
session = outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
ASSERT_NE(session, nullptr);
|
||||
|
||||
// Retention timer expired.
|
||||
clock_.FastForward(Seconds(10));
|
||||
service_thread_.Sync();
|
||||
|
||||
has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
session = outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
ASSERT_NE(session, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, onShareTargeDedupByEndpointIdNoLoss) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr int kShareTargetId2 = kShareTargetId + 100;
|
||||
constexpr absl::string_view kEndpointId = "endpoint_id";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
target.device_name = "device_name";
|
||||
ShareTarget target2 = target;
|
||||
target2.id = kShareTargetId2;
|
||||
target2.device_name = "device_name_2";
|
||||
ShareTarget merged_target = target;
|
||||
merged_target.device_name = "device_name_2";
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId, /*certificate=*/std::nullopt);
|
||||
EXPECT_NE(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target2, kEndpointId, /*certificate=*/std::nullopt);
|
||||
|
||||
// Make sure share session is not created for new target id.
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId2),
|
||||
nullptr);
|
||||
// Make sure share session is created for original target id.
|
||||
OutgoingShareSession* session2 =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
EXPECT_NE(session2, nullptr);
|
||||
EXPECT_EQ(session2->share_target(), merged_target);
|
||||
EXPECT_EQ(session2->endpoint_id(), kEndpointId);
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest,
|
||||
onShareTargeDedupByEndpointIdNoLossConnected) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr int kShareTargetId2 = kShareTargetId + 100;
|
||||
constexpr absl::string_view kEndpointId = "endpoint_id";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
target.device_name = "device_name";
|
||||
ShareTarget target2 = target;
|
||||
target2.id = kShareTargetId2;
|
||||
target2.device_name = "device_name_2";
|
||||
ShareTarget merged_target = target;
|
||||
merged_target.device_name = "device_name_2";
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId, /*certificate=*/std::nullopt);
|
||||
OutgoingShareSession* session =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
ASSERT_NE(session, nullptr);
|
||||
NearbyConnectionImpl connection(device_info_);
|
||||
session->OnConnectResult(&connection, Status::kSuccess);
|
||||
ASSERT_TRUE(session->IsConnected());
|
||||
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target2, kEndpointId, /*certificate=*/std::nullopt);
|
||||
|
||||
// Make sure share session is not created for new target id.
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId2),
|
||||
nullptr);
|
||||
// Make sure share session is created for original target id.
|
||||
OutgoingShareSession* session2 =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
EXPECT_NE(session2, nullptr);
|
||||
EXPECT_EQ(session2->share_target(), merged_target);
|
||||
// Make sure endpoint id is not updated since session is already connected.
|
||||
EXPECT_EQ(session2->endpoint_id(), kEndpointId);
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, onShareTargeDedupByDeviceIdNoLossConnected) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr int kShareTargetId2 = kShareTargetId + 100;
|
||||
constexpr absl::string_view kEndpointId1 = "endpoint_id";
|
||||
constexpr absl::string_view kEndpointId2 = "endpoint_id_2";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
target.device_id = "device_id";
|
||||
target.device_name = "device_name";
|
||||
ShareTarget target2 = target;
|
||||
target2.id = kShareTargetId2;
|
||||
target2.device_name = "device_name_2";
|
||||
ShareTarget merged_target = target;
|
||||
merged_target.device_name = "device_name_2";
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId1, /*certificate=*/std::nullopt);
|
||||
OutgoingShareSession* session =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
ASSERT_NE(session, nullptr);
|
||||
NearbyConnectionImpl connection(device_info_);
|
||||
session->OnConnectResult(&connection, Status::kSuccess);
|
||||
ASSERT_TRUE(session->IsConnected());
|
||||
|
||||
// Discover a new target with the same device id, but different endpoint id.
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target2, kEndpointId2, /*certificate=*/std::nullopt);
|
||||
|
||||
// Make sure share session is not created for new target id.
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId2),
|
||||
nullptr);
|
||||
// Make sure share session is created for original target id.
|
||||
OutgoingShareSession* session2 =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
EXPECT_NE(session2, nullptr);
|
||||
EXPECT_EQ(session2->share_target(), merged_target);
|
||||
// Make sure endpoint id is not updated since session is already connected.
|
||||
EXPECT_EQ(session2->endpoint_id(), kEndpointId1);
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, onShareTargeDedupByDeviceIdNoLoss) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr int kShareTargetId2 = kShareTargetId + 100;
|
||||
constexpr absl::string_view kEndpointId1 = "endpoint_id";
|
||||
constexpr absl::string_view kEndpointId2 = "endpoint_id_2";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
target.device_id = "device_id";
|
||||
target.device_name = "device_name";
|
||||
ShareTarget target2 = target;
|
||||
target2.id = kShareTargetId2;
|
||||
target2.device_name = "device_name_2";
|
||||
ShareTarget merged_target = target;
|
||||
merged_target.device_name = "device_name_2";
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId1, /*certificate=*/std::nullopt);
|
||||
EXPECT_NE(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
|
||||
// Discover a new target with the same device id, but different endpoint id.
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target2, kEndpointId2, /*certificate=*/std::nullopt);
|
||||
|
||||
// Make sure share session is not created for new target id.
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId2),
|
||||
nullptr);
|
||||
// Make sure share session is created for original target id.
|
||||
OutgoingShareSession* session2 =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
EXPECT_NE(session2, nullptr);
|
||||
EXPECT_EQ(session2->share_target(), merged_target);
|
||||
EXPECT_EQ(session2->endpoint_id(), kEndpointId2);
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, onShareTargeDedupByEndpointId) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr int kShareTargetId2 = kShareTargetId + 100;
|
||||
constexpr absl::string_view kEndpointId = "endpoint_id";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
target.device_name = "device_name";
|
||||
ShareTarget disabled_target = target;
|
||||
disabled_target.receive_disabled = true;
|
||||
ShareTarget target2 = target;
|
||||
target2.id = kShareTargetId2;
|
||||
target2.device_name = "device_name_2";
|
||||
ShareTarget merged_target = target;
|
||||
merged_target.device_name = "device_name_2";
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, disabled_target);
|
||||
})
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId, /*certificate=*/std::nullopt);
|
||||
EXPECT_NE(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
outgoing_targets_manager_.OnShareTargetLost(std::string(kEndpointId),
|
||||
Seconds(10));
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target2, kEndpointId, /*certificate=*/std::nullopt);
|
||||
|
||||
// Make sure share session is not created for new target id.
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId2),
|
||||
nullptr);
|
||||
// Make sure share session is created for original target id.
|
||||
OutgoingShareSession* session2 =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
EXPECT_NE(session2, nullptr);
|
||||
EXPECT_EQ(session2->share_target(), merged_target);
|
||||
EXPECT_EQ(session2->endpoint_id(), kEndpointId);
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
|
||||
// Retention timer expired.
|
||||
clock_.FastForward(Seconds(10));
|
||||
service_thread_.Sync();
|
||||
|
||||
// Make sure share session is not removed after retention timer expired.
|
||||
session2 = outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
EXPECT_NE(session2, nullptr);
|
||||
EXPECT_EQ(session2->share_target(), merged_target);
|
||||
EXPECT_EQ(session2->endpoint_id(), kEndpointId);
|
||||
has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, onShareTargeDedupByDeviceId) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr int kShareTargetId2 = kShareTargetId + 100;
|
||||
constexpr absl::string_view kEndpointId1 = "endpoint_id";
|
||||
constexpr absl::string_view kEndpointId2 = "endpoint_id_2";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
target.device_id = "device_id";
|
||||
target.device_name = "device_name";
|
||||
ShareTarget disabled_target = target;
|
||||
disabled_target.receive_disabled = true;
|
||||
ShareTarget target2 = target;
|
||||
target2.id = kShareTargetId2;
|
||||
target2.device_name = "device_name_2";
|
||||
ShareTarget merged_target = target;
|
||||
merged_target.device_name = "device_name_2";
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, disabled_target);
|
||||
})
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId1, /*certificate=*/std::nullopt);
|
||||
EXPECT_NE(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
outgoing_targets_manager_.OnShareTargetLost(std::string(kEndpointId1),
|
||||
Seconds(10));
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
|
||||
// Discover a new target with the same device id, but different endpoint id.
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target2, kEndpointId2, /*certificate=*/std::nullopt);
|
||||
|
||||
// Make sure share session is not created for new target id.
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId2),
|
||||
nullptr);
|
||||
// Make sure share session is created for original target id.
|
||||
OutgoingShareSession* session2 =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
EXPECT_NE(session2, nullptr);
|
||||
EXPECT_EQ(session2->share_target(), merged_target);
|
||||
EXPECT_EQ(session2->endpoint_id(), kEndpointId2);
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
|
||||
// Retention timer expired.
|
||||
clock_.FastForward(Seconds(10));
|
||||
service_thread_.Sync();
|
||||
|
||||
// Make sure share session is not removed after retention timer expired.
|
||||
session2 = outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
EXPECT_NE(session2, nullptr);
|
||||
EXPECT_EQ(session2->share_target(), merged_target);
|
||||
EXPECT_EQ(session2->endpoint_id(), kEndpointId2);
|
||||
has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, merged_target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, onShareTargeNoDedupOnEmptyDeviceId) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr int kShareTargetId2 = kShareTargetId + 100;
|
||||
constexpr absl::string_view kEndpointId1 = "endpoint_id";
|
||||
constexpr absl::string_view kEndpointId2 = "endpoint_id_2";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
target.device_id = "device_id";
|
||||
target.device_name = "device_name";
|
||||
ShareTarget disabled_target = target;
|
||||
disabled_target.receive_disabled = true;
|
||||
ShareTarget target2 = target;
|
||||
target2.id = kShareTargetId2;
|
||||
target2.device_name = "device_name_2";
|
||||
target2.device_id = "";
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, target);
|
||||
});
|
||||
EXPECT_CALL(share_target_updated_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, disabled_target);
|
||||
});
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, target2);
|
||||
});
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId1, /*certificate=*/std::nullopt);
|
||||
EXPECT_NE(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
outgoing_targets_manager_.OnShareTargetLost(std::string(kEndpointId1),
|
||||
Seconds(10));
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
|
||||
// Discover a new target with the same device id, but different endpoint id.
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target2, kEndpointId2, /*certificate=*/std::nullopt);
|
||||
|
||||
// Make sure share session is not created for new target id.
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
// Make sure share session is created for original target id.
|
||||
OutgoingShareSession* session2 =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId2);
|
||||
EXPECT_NE(session2, nullptr);
|
||||
EXPECT_EQ(session2->share_target(), target2);
|
||||
EXPECT_EQ(session2->endpoint_id(), kEndpointId2);
|
||||
std::vector<ShareTarget> share_targets;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
share_targets.push_back(share_target);
|
||||
});
|
||||
EXPECT_THAT(share_targets, SizeIs(2));
|
||||
EXPECT_THAT(share_targets, ElementsAre(disabled_target, target2));
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, CleanupClosesConnectedSessions) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr absl::string_view kEndpointId = "endpoint_id";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
ShareTarget disabled_target = target;
|
||||
disabled_target.receive_disabled = true;
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call).Times(0);
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call)
|
||||
.WillOnce([&](OutgoingShareSession& session,
|
||||
const TransferMetadata& metadata) {
|
||||
EXPECT_EQ(session.endpoint_id(), kEndpointId);
|
||||
EXPECT_EQ(session.share_target(), target);
|
||||
EXPECT_EQ(metadata.status(), TransferMetadata::Status::kFailed);
|
||||
});
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId, /*certificate=*/std::nullopt);
|
||||
OutgoingShareSession* session =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
ASSERT_NE(session, nullptr);
|
||||
NearbyConnectionImpl connection(device_info_);
|
||||
session->OnConnectResult(&connection, Status::kSuccess);
|
||||
ASSERT_TRUE(session->IsConnected());
|
||||
|
||||
outgoing_targets_manager_.Cleanup();
|
||||
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
});
|
||||
EXPECT_FALSE(has_targets);
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, AllTargetsLostClosesConnectedSessions) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr absl::string_view kEndpointId = "endpoint_id";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
ShareTarget disabled_target = target;
|
||||
disabled_target.receive_disabled = true;
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call)
|
||||
.WillOnce([&](const ShareTarget& share_target) {
|
||||
EXPECT_EQ(share_target, disabled_target);
|
||||
});
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId, /*certificate=*/std::nullopt);
|
||||
EXPECT_NE(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
|
||||
outgoing_targets_manager_.AllTargetsLost(Seconds(10));
|
||||
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, disabled_target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
EXPECT_EQ(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
TEST_F(OutgoingTargetsManagerTest, AllTargetsLostConnectedSessionsNotClosed) {
|
||||
constexpr int kShareTargetId = 1234;
|
||||
constexpr absl::string_view kEndpointId = "endpoint_id";
|
||||
ShareTarget target;
|
||||
target.id = kShareTargetId;
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(share_target_discovered_callback_, Call).Times(1);
|
||||
EXPECT_CALL(share_target_updated_callback_, Call).Times(0);
|
||||
EXPECT_CALL(share_target_lost_callback_, Call).Times(0);
|
||||
EXPECT_CALL(transfer_update_callback_, Call).Times(0);
|
||||
}
|
||||
outgoing_targets_manager_.OnShareTargetDiscovered(
|
||||
target, kEndpointId, /*certificate=*/std::nullopt);
|
||||
OutgoingShareSession* session =
|
||||
outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId);
|
||||
ASSERT_NE(session, nullptr);
|
||||
NearbyConnectionImpl connection(device_info_);
|
||||
session->OnConnectResult(&connection, Status::kSuccess);
|
||||
ASSERT_TRUE(session->IsConnected());
|
||||
|
||||
outgoing_targets_manager_.AllTargetsLost(Seconds(10));
|
||||
|
||||
bool has_targets = false;
|
||||
outgoing_targets_manager_.ForEachShareTarget(
|
||||
[&](const ShareTarget& share_target) {
|
||||
has_targets = true;
|
||||
EXPECT_EQ(share_target, target);
|
||||
});
|
||||
EXPECT_TRUE(has_targets);
|
||||
EXPECT_NE(outgoing_targets_manager_.GetOutgoingShareSession(kShareTargetId),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby::sharing
|
||||
@@ -33,8 +33,7 @@
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
#include "sharing/transfer_metadata.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
namespace nearby::sharing {
|
||||
namespace {
|
||||
|
||||
constexpr int64_t kShareTargetId = 123456789L;
|
||||
@@ -46,16 +45,19 @@ constexpr absl::string_view kMimeType = "image/jpg";
|
||||
class PayloadTrackerTest : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
container_.AddFileAttachment(FileAttachment(
|
||||
kFileId, kFileSize, std::string(kFileName), std::string(kMimeType),
|
||||
service::proto::FileMetadata::IMAGE));
|
||||
container_ =
|
||||
AttachmentContainer::Builder()
|
||||
.AddFileAttachment(FileAttachment(
|
||||
kFileId, kFileSize, std::string(kFileName),
|
||||
std::string(kMimeType), service::proto::FileMetadata::IMAGE))
|
||||
.Build();
|
||||
attachment_payload_map_.clear();
|
||||
attachment_payload_map_.emplace(container_.GetFileAttachments()[0].id(),
|
||||
attachment_payload_map_.emplace(container_->GetFileAttachments()[0].id(),
|
||||
kFileId);
|
||||
auto payload_updates_queue =
|
||||
std::make_unique<PayloadTracker::PayloadUpdateQueue>(&task_runner_);
|
||||
payload_tracker_ = std::make_unique<PayloadTracker>(
|
||||
&fake_clock_, kShareTargetId, container_, attachment_payload_map_,
|
||||
&fake_clock_, kShareTargetId, *container_, attachment_payload_map_,
|
||||
std::move(payload_updates_queue));
|
||||
}
|
||||
|
||||
@@ -74,7 +76,7 @@ class PayloadTrackerTest : public ::testing::Test {
|
||||
FakeClock fake_clock_;
|
||||
FakeTaskRunner task_runner_{&fake_clock_, 1};
|
||||
std::unique_ptr<PayloadTracker> payload_tracker_ = nullptr;
|
||||
AttachmentContainer container_;
|
||||
std::unique_ptr<AttachmentContainer> container_;
|
||||
absl::flat_hash_map<int64_t, int64_t> attachment_payload_map_;
|
||||
};
|
||||
|
||||
@@ -102,5 +104,4 @@ TEST_F(PayloadTrackerTest, StatusUpdateWithTimeUpdate) {
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -30,7 +30,7 @@ option objc_class_prefix = "GNCP";
|
||||
|
||||
// Top-level log proto for all NearbySharing logging.
|
||||
// Each log contains a key (event_type), value (a verb-noun event) pair.
|
||||
// Next Tag: 87
|
||||
// Next Tag: 90
|
||||
// LINT.IfChange
|
||||
message SharingLog {
|
||||
/* justification = {
|
||||
@@ -235,6 +235,13 @@ message SharingLog {
|
||||
|
||||
optional CloudUploadEnd cloud_upload_end = 86;
|
||||
|
||||
optional CloudDownloadStart cloud_download_start = 87;
|
||||
|
||||
optional CloudDownloadEnd cloud_download_end = 88;
|
||||
|
||||
// Cloud sharing RPC call event.
|
||||
optional CloudSharingRpcResult cloud_sharing_rpc_result = 89;
|
||||
|
||||
// Used only for Nearby Share Windows app now.
|
||||
message AppInfo {
|
||||
// e.g. "1.0.408"
|
||||
@@ -483,6 +490,9 @@ message SharingLog {
|
||||
// provider is not external.
|
||||
optional string external_provider_id = 11
|
||||
/* type = ST_SESSION_ID */;
|
||||
// Is this file transfer from a direct share target. This is only available
|
||||
// for the sender log.
|
||||
optional bool is_direct_share = 12;
|
||||
}
|
||||
|
||||
// TODO(fdi): may consider adding a field about decipherability later.
|
||||
@@ -615,6 +625,9 @@ message SharingLog {
|
||||
optional int32 connection_medium = 14;
|
||||
// The data usage of the user settings.
|
||||
optional location.nearby.proto.sharing.DataUsage data_usage = 15;
|
||||
|
||||
// True if the sender and receiver are mutual contacts.
|
||||
optional bool is_mutual_contact = 16;
|
||||
}
|
||||
|
||||
// EventType: RECEIVE_ATTACHMENTS_START
|
||||
@@ -914,6 +927,7 @@ message SharingLog {
|
||||
ANDROID_APP = 3;
|
||||
AUDIO = 4;
|
||||
DOCUMENT = 5;
|
||||
CONTACT_CARD = 6;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,20 +1060,66 @@ message SharingLog {
|
||||
// EventType: CLOUD_CREATE_SHARING_REQUEST
|
||||
message CloudCreateSharingRequest {
|
||||
optional AttachmentsInfo attachments_info = 1;
|
||||
optional location.nearby.proto.sharing.CloudCreateSharingResult result = 2;
|
||||
// Time taken to download attachments from the Intent in milliseconds.
|
||||
optional int64 attachment_download_latency_millis = 3;
|
||||
// Time taken to generate and encrypt the preview thumbnail in milliseconds.
|
||||
optional int64 preview_thumbnail_latency_millis = 4;
|
||||
// Time taken to make the CreateSharing RPC call in milliseconds.
|
||||
optional int64 rpc_latency_millis = 5;
|
||||
}
|
||||
|
||||
// EventType: CLOUD_REGISTER_RECEIVER used by QR code cloud web receiver
|
||||
message CloudRegisterReceiver {}
|
||||
message CloudRegisterReceiver {
|
||||
optional location.nearby.proto.sharing.CloudRegisterReceiverResult result =
|
||||
1;
|
||||
}
|
||||
|
||||
// EventType: CLOUD_UPLOAD_START used by QR code cloud web sender
|
||||
// The cloud_sharing_id and flow_id are logged in the event metadata.
|
||||
message CloudUploadStart {
|
||||
optional AttachmentsInfo attachments_info = 1;
|
||||
optional location.nearby.proto.sharing.CloudActionType action_type = 2;
|
||||
}
|
||||
|
||||
// EventType: CLOUD_UPLOAD_END used by QR code cloud web sender
|
||||
// The cloud_sharing_id and flow_id are logged in the event metadata.
|
||||
message CloudUploadEnd {
|
||||
repeated CloudAttachmentInfo upload_infos = 1;
|
||||
optional location.nearby.proto.sharing.CloudActionType action_type = 2;
|
||||
}
|
||||
|
||||
// EventType: CLOUD_DOWNLOAD_START used by QR code cloud web receiver
|
||||
// The cloud_sharing_id and cloud_receiver_session_id are logged in the
|
||||
// event_metadata into the anonymous logs.
|
||||
message CloudDownloadStart {
|
||||
optional AttachmentsInfo attachments_info = 1;
|
||||
optional location.nearby.proto.sharing.CloudActionType action_type = 2;
|
||||
}
|
||||
|
||||
// EventType: CLOUD_DOWNLOAD_END used by QR code cloud web receiver
|
||||
// The cloud_sharing_id and cloud_receiver_session_id are logged in the
|
||||
// event_metadata into the anonymous logs.
|
||||
message CloudDownloadEnd {
|
||||
repeated CloudAttachmentInfo download_infos = 1;
|
||||
optional location.nearby.proto.sharing.CloudActionType action_type = 2;
|
||||
}
|
||||
|
||||
// EventType: CLOUD_SHARING_RPC_RESULT
|
||||
// Event logging the result of a Cloud Sharing RPC call. This event captures
|
||||
// the type of RPC, its outcome, and performance metrics.
|
||||
message CloudSharingRpcResult {
|
||||
// The specific RPC method that was called.
|
||||
optional string rpc_name = 1;
|
||||
// The canonical gRPC status code (io.grpc.Status.Code) resulting from the
|
||||
// call.
|
||||
optional int32 status_code = 2;
|
||||
// The total time taken for the RPC call to complete, in milliseconds.
|
||||
optional int64 latency_millis = 3;
|
||||
// The unique identifier for the cloud sharing session, if available at the
|
||||
// time of the call. This helps correlate RPC events to a specific sharing
|
||||
// session.
|
||||
optional string cloud_sharing_id = 4;
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(//depot/google3/logs/proto/location/nearby/nearby_client_log.proto)
|
||||
|
||||
@@ -78,10 +78,8 @@ NearbyShareSchedulerBase::NearbyShareSchedulerBase(
|
||||
}
|
||||
|
||||
if (require_connectivity_) {
|
||||
connectivity_manager_->RegisterConnectionListener(
|
||||
connection_listener_name_,
|
||||
[this](nearby::ConnectivityManager::ConnectionType connection_type,
|
||||
bool is_lan_connected, bool is_internet_connected) {
|
||||
connectivity_manager_->RegisterInternetListener(
|
||||
connection_listener_name_, [this](bool is_internet_connected) {
|
||||
OnInternetConnectivityChanged(is_internet_connected);
|
||||
});
|
||||
}
|
||||
@@ -89,7 +87,7 @@ NearbyShareSchedulerBase::NearbyShareSchedulerBase(
|
||||
|
||||
NearbyShareSchedulerBase::~NearbyShareSchedulerBase() {
|
||||
if (require_connectivity_) {
|
||||
connectivity_manager_->UnregisterConnectionListener(
|
||||
connectivity_manager_->UnregisterInternetListener(
|
||||
connection_listener_name_);
|
||||
}
|
||||
}
|
||||
@@ -154,8 +152,7 @@ absl::Duration NearbyShareSchedulerBase::GetTimeUntilNextRequest() const {
|
||||
|
||||
// Recover from failures using exponential backoff strategy if necessary.
|
||||
absl::Duration time_until_retry = TimeUntilRetry(now);
|
||||
if (time_until_retry != absl::InfiniteDuration())
|
||||
return time_until_retry;
|
||||
if (time_until_retry != absl::InfiniteDuration()) return time_until_retry;
|
||||
|
||||
// Schedule the periodic request if applicable.
|
||||
return TimeUntilRecurringRequest(now);
|
||||
@@ -184,9 +181,7 @@ size_t NearbyShareSchedulerBase::GetNumConsecutiveFailures() const {
|
||||
return pref_value.value();
|
||||
}
|
||||
|
||||
void NearbyShareSchedulerBase::OnStart() {
|
||||
Reschedule();
|
||||
}
|
||||
void NearbyShareSchedulerBase::OnStart() { Reschedule(); }
|
||||
|
||||
void NearbyShareSchedulerBase::OnStop() { timer_->Stop(); }
|
||||
|
||||
|
||||
+18
-12
@@ -72,31 +72,37 @@ std::string TokenToFourDigitString(const std::vector<uint8_t>& bytes) {
|
||||
} // namespace
|
||||
|
||||
/* static */
|
||||
// Only used for final statuses.
|
||||
AttachmentTransmissionStatus ShareSession::ConvertToTransmissionStatus(
|
||||
TransferMetadata::Status status) {
|
||||
switch (status) {
|
||||
case TransferMetadata::Status::kComplete:
|
||||
return AttachmentTransmissionStatus::
|
||||
COMPLETE_ATTACHMENT_TRANSMISSION_STATUS;
|
||||
case TransferMetadata::Status::kCancelled:
|
||||
return AttachmentTransmissionStatus::
|
||||
CANCELED_ATTACHMENT_TRANSMISSION_STATUS;
|
||||
case TransferMetadata::Status::kFailed:
|
||||
return AttachmentTransmissionStatus::
|
||||
FAILED_ATTACHMENT_TRANSMISSION_STATUS;
|
||||
case TransferMetadata::Status::kIncompletePayloads:
|
||||
return AttachmentTransmissionStatus::FAILED_NO_PAYLOAD;
|
||||
case TransferMetadata::Status::kRejected:
|
||||
return AttachmentTransmissionStatus::
|
||||
REJECTED_ATTACHMENT_TRANSMISSION_STATUS;
|
||||
case TransferMetadata::Status::kCancelled:
|
||||
return AttachmentTransmissionStatus::
|
||||
CANCELED_ATTACHMENT_TRANSMISSION_STATUS;
|
||||
case TransferMetadata::Status::kTimedOut:
|
||||
return AttachmentTransmissionStatus::
|
||||
TIMED_OUT_ATTACHMENT_TRANSMISSION_STATUS;
|
||||
case TransferMetadata::Status::kMediaUnavailable:
|
||||
return AttachmentTransmissionStatus::MEDIA_UNAVAILABLE_ATTACHMENT;
|
||||
case TransferMetadata::Status::kDeviceAuthenticationFailed:
|
||||
return AttachmentTransmissionStatus::FAILED_PAIRED_KEYHANDSHAKE;
|
||||
case TransferMetadata::Status::kRejected:
|
||||
return AttachmentTransmissionStatus::REJECTED_ATTACHMENT;
|
||||
case TransferMetadata::Status::kTimedOut:
|
||||
return AttachmentTransmissionStatus::TIMED_OUT_ATTACHMENT;
|
||||
case TransferMetadata::Status::kNotEnoughSpace:
|
||||
return AttachmentTransmissionStatus::
|
||||
NOT_ENOUGH_SPACE_ATTACHMENT_TRANSMISSION_STATUS;
|
||||
case TransferMetadata::Status::kUnsupportedAttachmentType:
|
||||
return AttachmentTransmissionStatus::
|
||||
UNSUPPORTED_ATTACHMENT_TYPE_ATTACHMENT;
|
||||
UNSUPPORTED_ATTACHMENT_TYPE_ATTACHMENT_TRANSMISSION_STATUS;
|
||||
case TransferMetadata::Status::kDeviceAuthenticationFailed:
|
||||
return AttachmentTransmissionStatus::FAILED_PAIRED_KEYHANDSHAKE;
|
||||
case TransferMetadata::Status::kIncompletePayloads:
|
||||
return AttachmentTransmissionStatus::FAILED_NO_PAYLOAD;
|
||||
default:
|
||||
return AttachmentTransmissionStatus::
|
||||
UNKNOWN_ATTACHMENT_TRANSMISSION_STATUS;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/str_join.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/network/url.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
|
||||
@@ -41,14 +42,14 @@ ShareTarget::ShareTarget() { id = ++kLastGeneratedId; }
|
||||
ShareTarget::ShareTarget(
|
||||
std::string device_name, Url image_url, ShareTargetType type,
|
||||
bool is_incoming, std::optional<std::string> full_name, bool is_known,
|
||||
std::optional<std::string> device_id, bool for_self_share)
|
||||
absl::string_view device_id, bool for_self_share)
|
||||
: device_name(std::move(device_name)),
|
||||
image_url(std::move(image_url)),
|
||||
type(type),
|
||||
is_incoming(is_incoming),
|
||||
full_name(std::move(full_name)),
|
||||
is_known(is_known),
|
||||
device_id(std::move(device_id)),
|
||||
device_id(device_id),
|
||||
for_self_share(for_self_share) {
|
||||
id = ++kLastGeneratedId;
|
||||
}
|
||||
@@ -75,9 +76,7 @@ std::string ShareTarget::ToString() const {
|
||||
if (image_url) {
|
||||
fmt.push_back(absl::StrFormat("image_url: %s", image_url->GetUrlPath()));
|
||||
}
|
||||
if (device_id) {
|
||||
fmt.push_back(absl::StrFormat("device_id: %s", *device_id));
|
||||
}
|
||||
fmt.push_back(absl::StrFormat("device_id: %s", device_id));
|
||||
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));
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/network/url.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
|
||||
@@ -33,7 +34,7 @@ struct ShareTarget {
|
||||
std::string device_name, ::nearby::network::Url image_url,
|
||||
ShareTargetType type,
|
||||
bool is_incoming, std::optional<std::string> full_name, bool is_known,
|
||||
std::optional<std::string> device_id, bool for_self_share);
|
||||
absl::string_view device_id, bool for_self_share);
|
||||
ShareTarget(const ShareTarget&);
|
||||
ShareTarget(ShareTarget&&);
|
||||
ShareTarget& operator=(const ShareTarget&);
|
||||
@@ -54,7 +55,7 @@ struct ShareTarget {
|
||||
// True if the local device has the PublicCertificate this target is
|
||||
// advertising.
|
||||
bool is_known = false;
|
||||
std::optional<std::string> device_id;
|
||||
std::string device_id;
|
||||
// True if the remote device is also owned by the current user.
|
||||
bool for_self_share = false;
|
||||
// Vendor ID of the target. This can change over the lifetime of the target.
|
||||
|
||||
@@ -47,8 +47,8 @@ std::vector<ShareTargetToStringTestData> GetTestData() {
|
||||
kShareTargetToStringTestData =
|
||||
new std::vector<ShareTargetToStringTestData>({
|
||||
{share_target1,
|
||||
"ShareTarget<id: 1, type: 0, device_name: , is_known: 0, "
|
||||
"is_incoming: 0, for_self_share: 0, vendor_id: 0, "
|
||||
"ShareTarget<id: 1, type: 0, device_name: , device_id: , "
|
||||
"is_known: 0, is_incoming: 0, for_self_share: 0, vendor_id: 0, "
|
||||
"receive_disabled: 0>"},
|
||||
{share_target2,
|
||||
"ShareTarget<id: 2, type: 1, device_name: test_name, full_name: "
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
namespace nearby::sharing {
|
||||
namespace {
|
||||
|
||||
using ::location::nearby::proto::sharing::AttachmentSourceType;
|
||||
@@ -128,8 +127,8 @@ TextAttachment::TextAttachment(Type type, std::string text_body,
|
||||
text_title_(text_title.has_value() && !text_title->empty()
|
||||
? *text_title
|
||||
: GetTextTitle(text_body, type)),
|
||||
text_body_(std::move(text_body)),
|
||||
mime_type_(mime_type ? *mime_type : std::string()) {}
|
||||
mime_type_(mime_type.value_or("")),
|
||||
text_body_(std::move(text_body)) {}
|
||||
|
||||
TextAttachment::TextAttachment(int64_t id, Type type, std::string text_title,
|
||||
int64_t size, int32_t batch_id,
|
||||
@@ -145,8 +144,8 @@ TextAttachment::TextAttachment(int64_t id, Type type, std::string text_body,
|
||||
: Attachment(id, Attachment::Family::kText, size, batch_id, source_type),
|
||||
type_(type),
|
||||
text_title_(std::move(text_title)),
|
||||
text_body_(std::move(text_body)),
|
||||
mime_type_(std::move(mime_type)) {}
|
||||
mime_type_(std::move(mime_type)),
|
||||
text_body_(std::move(text_body)) {}
|
||||
|
||||
absl::string_view TextAttachment::GetDescription() const { return text_title_; }
|
||||
|
||||
@@ -176,5 +175,4 @@ void TextAttachment::set_text_body(std::string text_body) {
|
||||
text_title_ = GetTextTitle(text_body_, type_);
|
||||
}
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
namespace nearby::sharing {
|
||||
|
||||
// Represents a text attachment.
|
||||
class TextAttachment : public Attachment {
|
||||
@@ -49,8 +48,7 @@ class TextAttachment : public Attachment {
|
||||
location::nearby::proto::sharing::AttachmentSourceType source_type);
|
||||
TextAttachment(const TextAttachment&) = default;
|
||||
TextAttachment(TextAttachment&&) = default;
|
||||
TextAttachment& operator=(const TextAttachment&) = default;
|
||||
TextAttachment& operator=(TextAttachment&&) = default;
|
||||
TextAttachment& operator=(TextAttachment&&) = delete;
|
||||
~TextAttachment() override = default;
|
||||
|
||||
absl::string_view text_body() const { return text_body_; }
|
||||
@@ -66,13 +64,12 @@ class TextAttachment : public Attachment {
|
||||
std::string mime_type() const { return mime_type_; }
|
||||
|
||||
private:
|
||||
Type type_ = service::proto::TextMetadata::UNKNOWN;
|
||||
const Type type_;
|
||||
std::string text_title_;
|
||||
const std::string mime_type_;
|
||||
std::string text_body_;
|
||||
std::string mime_type_;
|
||||
};
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
} // namespace nearby::sharing
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_SHARING_TEXT_ATTACHMENT_H_
|
||||
|
||||
+10
-10
@@ -35,16 +35,16 @@ class TransferMetadata {
|
||||
kAwaitingLocalConfirmation,
|
||||
kAwaitingRemoteAcceptance,
|
||||
kInProgress,
|
||||
kComplete,
|
||||
kFailed,
|
||||
kRejected,
|
||||
kCancelled,
|
||||
kTimedOut,
|
||||
kMediaUnavailable,
|
||||
kNotEnoughSpace,
|
||||
kUnsupportedAttachmentType,
|
||||
kDeviceAuthenticationFailed,
|
||||
kIncompletePayloads,
|
||||
kComplete, // final
|
||||
kFailed, // final
|
||||
kRejected, // final
|
||||
kCancelled, // final
|
||||
kTimedOut, // final
|
||||
kMediaUnavailable, // final
|
||||
kNotEnoughSpace, // final
|
||||
kUnsupportedAttachmentType, // final
|
||||
kDeviceAuthenticationFailed, // final
|
||||
kIncompletePayloads, // final
|
||||
kMaxValue = kIncompletePayloads
|
||||
};
|
||||
// LINT.ThenChange(//depot/google3/location/nearby/cpp/sharing/clients/dart/platform/lib/types/transfer_status.dart)
|
||||
|
||||
@@ -23,20 +23,16 @@
|
||||
#include "sharing/attachment.h"
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
namespace nearby::sharing {
|
||||
|
||||
using ::location::nearby::proto::sharing::AttachmentSourceType;
|
||||
|
||||
WifiCredentialsAttachment::WifiCredentialsAttachment(
|
||||
std::string ssid, SecurityType security_type, std::string password,
|
||||
bool is_hidden, int32_t batch_id, AttachmentSourceType source_type)
|
||||
: Attachment(Attachment::Family::kWifiCredentials, ssid.size(), batch_id,
|
||||
source_type),
|
||||
ssid_(ssid),
|
||||
security_type_(security_type),
|
||||
password_(std::move(password)),
|
||||
is_hidden_(is_hidden) {}
|
||||
: WifiCredentialsAttachment(/*id=*/0, ssid, security_type,
|
||||
std::move(password), is_hidden, batch_id,
|
||||
source_type) {}
|
||||
|
||||
WifiCredentialsAttachment::WifiCredentialsAttachment(
|
||||
int64_t id, std::string ssid, SecurityType security_type,
|
||||
@@ -65,5 +61,4 @@ void WifiCredentialsAttachment::set_is_hidden(bool is_hidden) {
|
||||
is_hidden_ = is_hidden;
|
||||
}
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
} // namespace nearby::sharing
|
||||
|
||||
@@ -24,9 +24,8 @@
|
||||
#include "sharing/common/nearby_share_enums.h"
|
||||
#include "sharing/proto/wire_format.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
namespace nearby::sharing {
|
||||
\
|
||||
// Represents a WiFi credentials attachment.
|
||||
class WifiCredentialsAttachment : public Attachment {
|
||||
public:
|
||||
@@ -45,9 +44,7 @@ class WifiCredentialsAttachment : public Attachment {
|
||||
location::nearby::proto::sharing::ATTACHMENT_SOURCE_UNKNOWN);
|
||||
WifiCredentialsAttachment(const WifiCredentialsAttachment&) = default;
|
||||
WifiCredentialsAttachment(WifiCredentialsAttachment&&) = default;
|
||||
WifiCredentialsAttachment& operator=(const WifiCredentialsAttachment&) =
|
||||
default;
|
||||
WifiCredentialsAttachment& operator=(WifiCredentialsAttachment&&) = default;
|
||||
WifiCredentialsAttachment& operator=(WifiCredentialsAttachment&&) = delete;
|
||||
~WifiCredentialsAttachment() override = default;
|
||||
|
||||
absl::string_view ssid() const { return ssid_; }
|
||||
@@ -63,13 +60,12 @@ class WifiCredentialsAttachment : public Attachment {
|
||||
void set_is_hidden(bool is_hidden);
|
||||
|
||||
private:
|
||||
std::string ssid_;
|
||||
SecurityType security_type_;
|
||||
const std::string ssid_;
|
||||
const SecurityType security_type_;
|
||||
std::string password_;
|
||||
bool is_hidden_;
|
||||
};
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
} // namespace nearby::sharing
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_SHARING_WIFI_CREDENTIALS_ATTACHMENT_H_
|
||||
|
||||
@@ -58,7 +58,7 @@ class WorkerQueue {
|
||||
}
|
||||
callback_ = std::move(callback);
|
||||
{
|
||||
absl::MutexLock lock(&mutex_);
|
||||
absl::MutexLock lock(mutex_);
|
||||
if (!queue_.empty()) {
|
||||
ScheduleCallback();
|
||||
}
|
||||
@@ -78,7 +78,7 @@ class WorkerQueue {
|
||||
// Queues an item to be processed by the callback.
|
||||
// Callback are edge triggered.
|
||||
void Queue(T item) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
absl::MutexLock lock(mutex_);
|
||||
queue_.push(std::move(item));
|
||||
ScheduleCallback();
|
||||
}
|
||||
@@ -88,7 +88,7 @@ class WorkerQueue {
|
||||
// scheduled when new items are queued.
|
||||
std::queue<T> ReadAll() {
|
||||
is_scheduled_ = false;
|
||||
absl::MutexLock lock(&mutex_);
|
||||
absl::MutexLock lock(mutex_);
|
||||
std::queue<T> queue;
|
||||
queue.swap(queue_);
|
||||
return queue;
|
||||
|
||||
Reference in New Issue
Block a user