From c9686fdb0fc16f84e4097740607062349bb66adf Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 28 Jan 2025 10:18:18 -0800 Subject: [PATCH] Add APK support PiperOrigin-RevId: 720620879 --- sharing/attachment.cc | 2 +- sharing/incoming_share_session.cc | 38 +++++++++ sharing/incoming_share_session_test.cc | 112 ++++++++++++++++++------- 3 files changed, 123 insertions(+), 29 deletions(-) diff --git a/sharing/attachment.cc b/sharing/attachment.cc index 5dff5abf..5709e5a7 100644 --- a/sharing/attachment.cc +++ b/sharing/attachment.cc @@ -41,7 +41,7 @@ Attachment::Attachment(Attachment::Family family, int64_t size, Attachment::Attachment(int64_t id, Attachment::Family family, int64_t size, int32_t batch_id, SourceType source_type) - : id_(id), + : id_(id == 0 ? CreateRandomId() : id), family_(family), size_(size), batch_id_(batch_id), diff --git a/sharing/incoming_share_session.cc b/sharing/incoming_share_session.cc index 5b14489b..5c19ef79 100644 --- a/sharing/incoming_share_session.cc +++ b/sharing/incoming_share_session.cc @@ -54,6 +54,7 @@ namespace { using ::location::nearby::proto::sharing::OSType; using ::location::nearby::proto::sharing::ResponseToIntroduction; +using ::nearby::sharing::service::proto::AppMetadata; using ::nearby::sharing::service::proto::ConnectionResponseFrame; using ::nearby::sharing::service::proto::IntroductionFrame; using ::nearby::sharing::service::proto::V1Frame; @@ -111,6 +112,43 @@ IncomingShareSession::ProcessIntroduction( file_size_sum += file.size(); } + for (const AppMetadata& apk : introduction_frame.app_metadata()) { + if (apk.size() <= 0) { + NL_LOG(WARNING) + << __func__ + << ": Ignore introduction, due to invalid attachment size"; + return TransferMetadata::Status::kUnsupportedAttachmentType; + } + + VLOG(1) << __func__ << ": Found app attachment: id=" << apk.id() + << ", app_name=" << apk.app_name() + << ", package_name=" << apk.package_name() + << ", size=" << apk.size(); + if (std::numeric_limits::max() - apk.size() < file_size_sum) { + NL_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. + for (int index = 0; index < apk.file_name_size(); ++index) { + // Locally generate an attachment id for each apk file, and map it to the + // payload id. + FileAttachment apk_file( + /*id=*/0, apk.file_size(index), apk.file_name(index), + /*mime_type=*/"", service::proto::FileMetadata::ANDROID_APP); + int64_t apk_file_id = apk_file.id(); + VLOG(1) << __func__ << ": Found app file name: " << apk.file_name(index) + << ", attachment id=" << apk_file_id + << ", file size=" << apk.file_size(index) + << ", payload_id=" << apk.payload_id(index); + container.AddFileAttachment(std::move(apk_file)); + SetAttachmentPayloadId(apk_file_id, apk.payload_id(index)); + } + file_size_sum += apk.size(); + } + for (const auto& text : introduction_frame.text_metadata()) { if (text.size() <= 0) { LOG(WARNING) << "Ignore introduction, due to invalid attachment size"; diff --git a/sharing/incoming_share_session_test.cc b/sharing/incoming_share_session_test.cc index 68826e6e..faab88c9 100644 --- a/sharing/incoming_share_session_test.cc +++ b/sharing/incoming_share_session_test.cc @@ -14,6 +14,7 @@ #include "sharing/incoming_share_session.h" +#include #include #include // NOLINT #include @@ -297,6 +298,65 @@ TEST_F(IncomingShareSessionTest, ProcessIntroductionSuccess) { Eq(wifimeta2.payload_id())); } +TEST_F(IncomingShareSessionTest, ProcessIntroductionWithApkSuccess) { + IntroductionFrame introduction_frame; + CHECK(proto2::TextFormat::ParseFromString(R"pb( + app_metadata { + app_name: "MyApp" + size: 300 + payload_id: 9876 + payload_id: 9877 + payload_id: 9878 + id: 1234 + file_name: "MyApp.apk" + file_name: "MyApp1.apk" + file_name: "MyApp2.apk" + file_size: 100 + file_size: 100 + file_size: 100 + package_name: "com.example.myapp" + } + )pb", + &introduction_frame)); + service::proto::AppMetadata app_metadata = introduction_frame.app_metadata(0); + int64_t payload_id1 = app_metadata.payload_id(0); + int64_t payload_id2 = app_metadata.payload_id(1); + int64_t payload_id3 = app_metadata.payload_id(2); + session_.OnConnected(&connection_); + + EXPECT_THAT(session_.ProcessIntroduction(introduction_frame), + Eq(std::nullopt)); + EXPECT_THAT(session_.attachment_container().HasAttachments(), IsTrue()); + // Find generated file attachments ids. + auto it = std::find_if(std::begin(session_.attachment_payload_map()), + std::end(session_.attachment_payload_map()), + [&](auto&& p) { return p.second == payload_id1; }); + ASSERT_NE(it, std::end(session_.attachment_payload_map())); + int64_t file_id1 = it->first; + it = std::find_if(std::begin(session_.attachment_payload_map()), + std::end(session_.attachment_payload_map()), + [&](auto&& p) { return p.second == payload_id2; }); + ASSERT_NE(it, std::end(session_.attachment_payload_map())); + int64_t file_id2 = it->first; + it = std::find_if(std::begin(session_.attachment_payload_map()), + std::end(session_.attachment_payload_map()), + [&](auto&& p) { return p.second == payload_id3; }); + ASSERT_NE(it, std::end(session_.attachment_payload_map())); + int64_t file_id3 = it->first; + FileAttachment file1( + file_id1, app_metadata.file_size(0), app_metadata.file_name(0), + /*mime_type=*/"", service::proto::FileMetadata::ANDROID_APP); + FileAttachment file2( + file_id2, app_metadata.file_size(1), app_metadata.file_name(1), + /*mime_type=*/"", service::proto::FileMetadata::ANDROID_APP); + FileAttachment file3( + file_id3, app_metadata.file_size(2), app_metadata.file_name(2), + /*mime_type=*/"", service::proto::FileMetadata::ANDROID_APP); + + EXPECT_THAT(session_.attachment_container().GetFileAttachments(), + UnorderedElementsAre(file1, file2, file3)); +} + TEST_F(IncomingShareSessionTest, PayloadTransferUpdateCompleteWithWrongPayloadType) { connections_manager_.AcceptConnection( @@ -1103,8 +1163,7 @@ TEST_F(IncomingShareSessionTest, ReadyForTransferTimeoutCancelled) { } TEST_F(IncomingShareSessionTest, AcceptTransferNotConnected) { - EXPECT_THAT(session_.AcceptTransfer([]() {}), - IsFalse()); + EXPECT_THAT(session_.AcceptTransfer([]() {}), IsFalse()); } TEST_F(IncomingShareSessionTest, AcceptTransferNotReady) { @@ -1112,8 +1171,7 @@ TEST_F(IncomingShareSessionTest, AcceptTransferNotReady) { EXPECT_THAT(session_.ProcessIntroduction(introduction_frame_), Eq(std::nullopt)); - EXPECT_THAT(session_.AcceptTransfer([]() {}), - IsFalse()); + EXPECT_THAT(session_.AcceptTransfer([]() {}), IsFalse()); } TEST_F(IncomingShareSessionTest, AcceptTransferSuccess) { @@ -1150,8 +1208,7 @@ TEST_F(IncomingShareSessionTest, AcceptTransferSuccess) { frames_data.push(std::move(payload->content.bytes_payload.bytes)); }); - EXPECT_THAT(session_.AcceptTransfer([]() {}), - IsTrue()); + EXPECT_THAT(session_.AcceptTransfer([]() {}), IsTrue()); for (auto it : session_.attachment_payload_map()) { EXPECT_THAT( @@ -1310,28 +1367,27 @@ TEST_F(IncomingShareSessionTest, TryUpgradeBandwidthNotNeeded) { TEST_F(IncomingShareSessionTest, TryUpgradeBandwidthNeeded) { IntroductionFrame introduction_frame; - CHECK( - proto2::TextFormat::ParseFromString(R"pb( - file_metadata { - id: 1234 - size: 1000000 - name: "file_name1" - mime_type: "application/pdf" - type: DOCUMENT - parent_folder: "parent_folder1" - payload_id: 9876 - } - file_metadata { - id: 1235 - size: 200 - name: "file_name2" - mime_type: "image/jpeg" - type: IMAGE - parent_folder: "parent_folder2" - payload_id: 9875 - } - )pb", - &introduction_frame)); + CHECK(proto2::TextFormat::ParseFromString(R"pb( + file_metadata { + id: 1234 + size: 1000000 + name: "file_name1" + mime_type: "application/pdf" + type: DOCUMENT + parent_folder: "parent_folder1" + payload_id: 9876 + } + file_metadata { + id: 1235 + size: 200 + name: "file_name2" + mime_type: "image/jpeg" + type: IMAGE + parent_folder: "parent_folder2" + payload_id: 9875 + } + )pb", + &introduction_frame)); session_.OnConnected(&connection_); EXPECT_THAT(session_.ProcessIntroduction(introduction_frame), Eq(std::nullopt));