diff options
author | Ryan Mitchell <rtmitchell@google.com> | 2020-04-28 23:47:58 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-04-28 23:47:58 +0000 |
commit | 04fa9c9f5708e56f3ef1caf8439493774f829209 (patch) | |
tree | a016e87f1334ee96b4ad5fb456ab0258c18e9949 /cmds/idmap2 | |
parent | 3a11530c5dba4f11279f20e1ec798a693e06673b (diff) | |
parent | 84a84ac62ab7972a082055b7eec60c561f1f13c8 (diff) |
Merge "Reduce OMS start time" into rvc-dev am: 84a84ac62a
Change-Id: I9a419e6be7cc950693e39c5d474e3c60161c4b69
Diffstat (limited to 'cmds/idmap2')
-rw-r--r-- | cmds/idmap2/idmap2d/Idmap2Service.cpp | 32 | ||||
-rw-r--r-- | cmds/idmap2/idmap2d/Idmap2Service.h | 4 | ||||
-rw-r--r-- | cmds/idmap2/include/idmap2/Idmap.h | 5 | ||||
-rw-r--r-- | cmds/idmap2/libidmap2/Idmap.cpp | 38 |
4 files changed, 60 insertions, 19 deletions
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index b8f1a1c0ee72..afe754f2f35b 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -34,11 +34,13 @@ #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" #include "idmap2/SysTrace.h" +#include "idmap2/ZipFile.h" #include "utils/String8.h" using android::IPCThreadState; using android::binder::Status; using android::idmap2::BinaryStreamVisitor; +using android::idmap2::GetPackageCrc; using android::idmap2::Idmap; using android::idmap2::IdmapHeader; using android::idmap2::utils::kIdmapCacheDir; @@ -49,6 +51,8 @@ using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask namespace { +constexpr const char* kFrameworkPath = "/system/framework/framework-res.apk"; + Status ok() { return Status::ok(); } @@ -109,8 +113,32 @@ Status Idmap2Service::verifyIdmap(const std::string& target_apk_path, return error("failed to parse idmap header"); } - *_aidl_return = - strcmp(header->GetTargetPath().data(), target_apk_path.data()) == 0 && header->IsUpToDate(); + if (strcmp(header->GetTargetPath().data(), target_apk_path.data()) != 0) { + *_aidl_return = false; + return ok(); + } + + if (target_apk_path != kFrameworkPath) { + *_aidl_return = (bool) header->IsUpToDate(); + } else { + if (!android_crc_) { + // Loading the framework zip can take several milliseconds. Cache the crc of the framework + // resource APK to reduce repeated work during boot. + const auto target_zip = idmap2::ZipFile::Open(target_apk_path); + if (!target_zip) { + return error(base::StringPrintf("failed to open target %s", target_apk_path.c_str())); + } + + const auto target_crc = GetPackageCrc(*target_zip); + if (!target_crc) { + return error(target_crc.GetErrorMessage()); + } + + android_crc_ = *target_crc; + } + + *_aidl_return = (bool) header->IsUpToDate(android_crc_.value()); + } // TODO(b/119328308): Check that the set of fulfilled policies of the overlay has not changed return ok(); diff --git a/cmds/idmap2/idmap2d/Idmap2Service.h b/cmds/idmap2/idmap2d/Idmap2Service.h index 0ed55a1bb6a4..55fb5ad07781 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.h +++ b/cmds/idmap2/idmap2d/Idmap2Service.h @@ -46,6 +46,10 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 { const std::string& overlay_apk_path, int32_t fulfilled_policies, bool enforce_overlayable, int32_t user_id, aidl::nullable<std::string>* _aidl_return) override; + + private: + // Cache the crc of the android framework package since the crc cannot change without a reboot. + std::optional<uint32_t> android_crc_; }; } // namespace android::os diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h index 2e4836e297ec..77a7b30a230e 100644 --- a/cmds/idmap2/include/idmap2/Idmap.h +++ b/cmds/idmap2/include/idmap2/Idmap.h @@ -74,6 +74,7 @@ #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" #include "idmap2/ResourceMapping.h" +#include "idmap2/ZipFile.h" namespace android::idmap2 { @@ -93,6 +94,9 @@ static constexpr const uint32_t kIdmapCurrentVersion = android::kIdmapCurrentVer // terminating null) static constexpr const size_t kIdmapStringLength = 256; +// Retrieves a crc generated using all of the files within the zip that can affect idmap generation. +Result<uint32_t> GetPackageCrc(const ZipFile& zip_info); + class IdmapHeader { public: static std::unique_ptr<const IdmapHeader> FromBinaryStream(std::istream& stream); @@ -129,6 +133,7 @@ class IdmapHeader { // field *must* be incremented. Because of this, we know that if the idmap // header is up-to-date the entire file is up-to-date. Result<Unit> IsUpToDate() const; + Result<Unit> IsUpToDate(uint32_t target_crc_) const; void accept(Visitor* v) const; diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp index 7f2cd9596c95..706b842b3b47 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -100,7 +100,9 @@ Result<std::string> ReadString(std::istream& stream) { return buf; } -Result<uint32_t> GetCrc(const ZipFile& zip) { +} // namespace + +Result<uint32_t> GetPackageCrc(const ZipFile& zip) { const Result<uint32_t> a = zip.Crc("resources.arsc"); const Result<uint32_t> b = zip.Crc("AndroidManifest.xml"); return a && b @@ -108,8 +110,6 @@ Result<uint32_t> GetCrc(const ZipFile& zip) { : Error("failed to get CRC for \"%s\"", a ? "AndroidManifest.xml" : "resources.arsc"); } -} // namespace - std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) { std::unique_ptr<IdmapHeader> idmap_header(new IdmapHeader()); @@ -130,27 +130,31 @@ std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& s } Result<Unit> IdmapHeader::IsUpToDate() const { - if (magic_ != kIdmapMagic) { - return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic); - } - - if (version_ != kIdmapCurrentVersion) { - return Error("bad version: actual 0x%08x, expected 0x%08x", version_, kIdmapCurrentVersion); - } - const std::unique_ptr<const ZipFile> target_zip = ZipFile::Open(target_path_); if (!target_zip) { return Error("failed to open target %s", GetTargetPath().to_string().c_str()); } - Result<uint32_t> target_crc = GetCrc(*target_zip); + Result<uint32_t> target_crc = GetPackageCrc(*target_zip); if (!target_crc) { return Error("failed to get target crc"); } - if (target_crc_ != *target_crc) { + return IsUpToDate(*target_crc); +} + +Result<Unit> IdmapHeader::IsUpToDate(uint32_t target_crc) const { + if (magic_ != kIdmapMagic) { + return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic); + } + + if (version_ != kIdmapCurrentVersion) { + return Error("bad version: actual 0x%08x, expected 0x%08x", version_, kIdmapCurrentVersion); + } + + if (target_crc_ != target_crc) { return Error("bad target crc: idmap version 0x%08x, file system version 0x%08x", target_crc_, - *target_crc); + target_crc); } const std::unique_ptr<const ZipFile> overlay_zip = ZipFile::Open(overlay_path_); @@ -158,7 +162,7 @@ Result<Unit> IdmapHeader::IsUpToDate() const { return Error("failed to open overlay %s", GetOverlayPath().to_string().c_str()); } - Result<uint32_t> overlay_crc = GetCrc(*overlay_zip); + Result<uint32_t> overlay_crc = GetPackageCrc(*overlay_zip); if (!overlay_crc) { return Error("failed to get overlay crc"); } @@ -304,13 +308,13 @@ Result<std::unique_ptr<const Idmap>> Idmap::FromApkAssets(const ApkAssets& targe header->magic_ = kIdmapMagic; header->version_ = kIdmapCurrentVersion; - Result<uint32_t> crc = GetCrc(*target_zip); + Result<uint32_t> crc = GetPackageCrc(*target_zip); if (!crc) { return Error(crc.GetError(), "failed to get zip CRC for target"); } header->target_crc_ = *crc; - crc = GetCrc(*overlay_zip); + crc = GetPackageCrc(*overlay_zip); if (!crc) { return Error(crc.GetError(), "failed to get zip CRC for overlay"); } |