summaryrefslogtreecommitdiff
path: root/cmds/idmap2
diff options
context:
space:
mode:
authorRyan Mitchell <rtmitchell@google.com>2020-04-28 23:44:03 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-04-28 23:44:03 +0000
commit84a84ac62ab7972a082055b7eec60c561f1f13c8 (patch)
tree013b4570e14a4060eda70c2ba6c364faa3ca67f6 /cmds/idmap2
parent1109f9a0fb10d84deaf07cd7fb0aacff1d69d6e5 (diff)
parent7d53f19089829409075d8ad3dbf3447e80f0f2ac (diff)
Merge "Reduce OMS start time" into rvc-dev
Diffstat (limited to 'cmds/idmap2')
-rw-r--r--cmds/idmap2/idmap2d/Idmap2Service.cpp32
-rw-r--r--cmds/idmap2/idmap2d/Idmap2Service.h4
-rw-r--r--cmds/idmap2/include/idmap2/Idmap.h5
-rw-r--r--cmds/idmap2/libidmap2/Idmap.cpp38
4 files changed, 60 insertions, 19 deletions
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp
index 75fc7f714ce3..a93184ff4787 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");
}