Loading cmds/idmap2/idmap2d/Idmap2Service.cpp +30 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); } Loading Loading @@ -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(); Loading cmds/idmap2/idmap2d/Idmap2Service.h +4 −0 Original line number Diff line number Diff line Loading @@ -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 Loading cmds/idmap2/include/idmap2/Idmap.h +5 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" #include "idmap2/ResourceMapping.h" #include "idmap2/ZipFile.h" namespace android::idmap2 { Loading @@ -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); Loading Loading @@ -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; Loading cmds/idmap2/libidmap2/Idmap.cpp +21 −17 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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()); Loading @@ -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_); Loading @@ -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"); } Loading Loading @@ -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"); } Loading services/core/java/com/android/server/om/IdmapDaemon.java +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ class IdmapDaemon { // The amount of time in milliseconds to wait when attempting to connect to idmap service. private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000; private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 200; private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 5; private static final String IDMAP_DAEMON = "idmap2d"; Loading Loading
cmds/idmap2/idmap2d/Idmap2Service.cpp +30 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); } Loading Loading @@ -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(); Loading
cmds/idmap2/idmap2d/Idmap2Service.h +4 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
cmds/idmap2/include/idmap2/Idmap.h +5 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" #include "idmap2/ResourceMapping.h" #include "idmap2/ZipFile.h" namespace android::idmap2 { Loading @@ -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); Loading Loading @@ -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; Loading
cmds/idmap2/libidmap2/Idmap.cpp +21 −17 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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()); Loading @@ -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_); Loading @@ -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"); } Loading Loading @@ -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"); } Loading
services/core/java/com/android/server/om/IdmapDaemon.java +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ class IdmapDaemon { // The amount of time in milliseconds to wait when attempting to connect to idmap service. private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000; private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 200; private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 5; private static final String IDMAP_DAEMON = "idmap2d"; Loading