Merge "[adb] use zip iteration with functor" am: 26a8ed983c
am: d9ec4fc3f3
Change-Id: Id89e24dc5e57cf58c9dd069c31001297b428d279
This commit is contained in:
commit
f25ffde2dd
1 changed files with 22 additions and 10 deletions
|
@ -23,6 +23,7 @@
|
|||
#include <ziparchive/zip_archive.h>
|
||||
#include <ziparchive/zip_writer.h>
|
||||
|
||||
#include <array>
|
||||
#include <cinttypes>
|
||||
#include <numeric>
|
||||
#include <unordered_set>
|
||||
|
@ -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<ZipArchiveHandle, std::unique_ptr<android::base::MappedFile>> 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<int32_t> InstallationPriorityBlocks(int fd, int64_t fileSize) {
|
||||
static constexpr std::array<std::string_view, 3> 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<int32_t> 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<int32_t> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue