summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--services/core/java/com/android/server/om/IdmapDaemon.java2
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java6
6 files changed, 66 insertions, 21 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");
}
diff --git a/services/core/java/com/android/server/om/IdmapDaemon.java b/services/core/java/com/android/server/om/IdmapDaemon.java
index 7df8fc7e34ed..910ed44df0f8 100644
--- a/services/core/java/com/android/server/om/IdmapDaemon.java
+++ b/services/core/java/com/android/server/om/IdmapDaemon.java
@@ -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";
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 84e43fcc9056..6a8e465529d7 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -1120,7 +1120,11 @@ public final class OverlayManagerService extends SystemService {
@Override
public List<PackageInfo> getOverlayPackages(final int userId) {
- return mPackageManagerInternal.getOverlayPackages(userId);
+ final List<PackageInfo> overlays = mPackageManagerInternal.getOverlayPackages(userId);
+ for (final PackageInfo info : overlays) {
+ cachePackageInfo(info.packageName, userId, info);
+ }
+ return overlays;
}
@Nullable