diff --git a/adb/client/incremental_utils.cpp b/adb/client/incremental_utils.cpp index caadb26f6..fa501e49d 100644 --- a/adb/client/incremental_utils.cpp +++ b/adb/client/incremental_utils.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,8 @@ #include "adb_trace.h" #include "sysdeps.h" +using namespace std::literals; + static constexpr int kBlockSize = 4096; static constexpr inline int32_t offsetToBlockIndex(int64_t offset) { @@ -217,16 +220,24 @@ static std::pair> o return {zip, std::move(mapping)}; } -// TODO(b/151676293): avoid using libziparchive as it reads local file headers -// which causes additional performance cost. Instead, only read from central directory. static std::vector InstallationPriorityBlocks(int fd, int64_t fileSize) { + static constexpr std::array additional_matches = { + "resources.arsc"sv, "AndroidManifest.xml"sv, "classes.dex"sv}; auto [zip, _] = openZipArchive(fd, fileSize); if (!zip) { return {}; } + auto matcher = [](std::string_view entry_name) { + if (entry_name.starts_with("lib/"sv) && entry_name.ends_with(".so"sv)) { + return true; + } + return std::any_of(additional_matches.begin(), additional_matches.end(), + [entry_name](std::string_view i) { return i == entry_name; }); + }; + void* cookie = nullptr; - if (StartIteration(zip, &cookie) != 0) { + if (StartIteration(zip, &cookie, std::move(matcher)) != 0) { D("%s failed at StartIteration: %d", __func__, errno); return {}; } @@ -235,8 +246,12 @@ static std::vector InstallationPriorityBlocks(int fd, int64_t fileSize) ZipEntry entry; std::string_view entryName; while (Next(cookie, &entry, &entryName) == 0) { - if (entryName == "resources.arsc" || entryName == "AndroidManifest.xml" || - entryName.starts_with("lib/")) { + if (entryName == "classes.dex"sv) { + // Only the head is needed for installation + int32_t startBlockIndex = offsetToBlockIndex(entry.offset); + appendBlocks(startBlockIndex, 1, &installationPriorityBlocks); + D("\tadding to priority blocks: '%.*s' 1", (int)entryName.size(), entryName.data()); + } else { // Full entries are needed for installation off64_t entryStartOffset = entry.offset; off64_t entryEndOffset = @@ -248,11 +263,8 @@ static std::vector InstallationPriorityBlocks(int fd, int64_t fileSize) int32_t endBlockIndex = offsetToBlockIndex(entryEndOffset); int32_t numNewBlocks = endBlockIndex - startBlockIndex + 1; appendBlocks(startBlockIndex, numNewBlocks, &installationPriorityBlocks); - D("\tadding to priority blocks: '%.*s'", (int)entryName.size(), entryName.data()); - } else if (entryName == "classes.dex") { - // Only the head is needed for installation - int32_t startBlockIndex = offsetToBlockIndex(entry.offset); - appendBlocks(startBlockIndex, 1, &installationPriorityBlocks); + D("\tadding to priority blocks: '%.*s' (%d)", (int)entryName.size(), entryName.data(), + numNewBlocks); } }