summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yurii Zubrytskyi <zyy@google.com> 2023-05-02 10:53:14 -0700
committer Yurii Zubrytskyi <zyy@google.com> 2023-05-23 21:27:38 +0000
commit75663392c67aa78850f047dabf4648e53c22f48a (patch)
treeb147c44969021761bc7fc117ecd202523d9300bc
parent06560ed48f936e3b228f7b67895f6d9085d1f3c9 (diff)
[res] Overlayable only mode of loading ApkAssets
OverlayManagerService only needs to know the overlayable declarations of the apk, and as of now the only way to get those is to completely load and parse the whole resources file. This CL adds a flag to only parse the overlayable declarations, speeding up loading by ~2x Test: build + boot + UTs + user switching Bug: 271904589 Change-Id: I1ec4b9b57dd1aee1769cc2d4dd9641e5e68639f8
-rw-r--r--core/java/android/content/res/ApkAssets.java5
-rw-r--r--libs/androidfw/LoadedArsc.cpp21
-rw-r--r--libs/androidfw/include/androidfw/LoadedArsc.h3
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java3
4 files changed, 30 insertions, 2 deletions
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
index 143c00dd4d81..653e243f5e06 100644
--- a/core/java/android/content/res/ApkAssets.java
+++ b/core/java/android/content/res/ApkAssets.java
@@ -78,6 +78,11 @@ public final class ApkAssets {
*/
public static final int PROPERTY_DISABLE_INCREMENTAL_HARDENING = 1 << 4;
+ /**
+ * The apk assets only contain the overlayable declarations information.
+ */
+ public static final int PROPERTY_ONLY_OVERLAYABLES = 1 << 5;
+
/** Flags that change the behavior of loaded apk assets. */
@IntDef(prefix = { "PROPERTY_" }, value = {
PROPERTY_SYSTEM,
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index fbfae5e2bcbe..c9d5e074271b 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -494,6 +494,8 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
util::ReadUtf16StringFromDevice(header->name, arraysize(header->name),
&loaded_package->package_name_);
+ const bool only_overlayable = (property_flags & PROPERTY_ONLY_OVERLAYABLES) != 0;
+
// A map of TypeSpec builders, each associated with an type index.
// We use these to accumulate the set of Types available for a TypeSpec, and later build a single,
// contiguous block of memory that holds all the Types together with the TypeSpec.
@@ -502,6 +504,9 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
ChunkIterator iter(chunk.data_ptr(), chunk.data_size());
while (iter.HasNext()) {
const Chunk child_chunk = iter.Next();
+ if (only_overlayable && child_chunk.type() != RES_TABLE_OVERLAYABLE_TYPE) {
+ continue;
+ }
switch (child_chunk.type()) {
case RES_STRING_POOL_TYPE: {
const auto pool_address = child_chunk.header<ResChunk_header>();
@@ -655,6 +660,9 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
<< name_to_actor_it->first << "'.";
return {};
}
+ if (only_overlayable) {
+ break;
+ }
// Iterate over the overlayable policy chunks contained within the overlayable chunk data
ChunkIterator overlayable_iter(child_chunk.data_ptr(), child_chunk.data_size());
@@ -800,14 +808,21 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
global_string_pool_ = util::make_unique<OverlayStringPool>(loaded_idmap);
}
+ const bool only_overlayable = (property_flags & PROPERTY_ONLY_OVERLAYABLES) != 0;
+
const size_t package_count = dtohl(header->packageCount);
size_t packages_seen = 0;
- packages_.reserve(package_count);
+ if (!only_overlayable) {
+ packages_.reserve(package_count);
+ }
ChunkIterator iter(chunk.data_ptr(), chunk.data_size());
while (iter.HasNext()) {
const Chunk child_chunk = iter.Next();
+ if (only_overlayable && child_chunk.type() != RES_TABLE_PACKAGE_TYPE) {
+ continue;
+ }
switch (child_chunk.type()) {
case RES_STRING_POOL_TYPE:
// Only use the first string pool. Ignore others.
@@ -837,6 +852,10 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
return false;
}
packages_.push_back(std::move(loaded_package));
+ if (only_overlayable) {
+ // Overlayable is always in the first package, no need to process anything else.
+ return true;
+ }
} break;
default:
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index 4d12885ad291..3a7287187781 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -96,6 +96,9 @@ enum : package_property_t {
// The apk assets is owned by the application running in this process and incremental crash
// protections for this APK must be disabled.
PROPERTY_DISABLE_INCREMENTAL_HARDENING = 1U << 4U,
+
+ // The apk assets only contain the overlayable declarations information.
+ PROPERTY_ONLY_OVERLAYABLES = 1U << 5U,
};
struct OverlayableInfo {
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index d471c8abb1b2..e54f12c37559 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -1301,7 +1301,8 @@ public final class OverlayManagerService extends SystemService {
ApkAssets apkAssets = null;
try {
- apkAssets = ApkAssets.loadFromPath(pkg.getSplits().get(0).getPath());
+ apkAssets = ApkAssets.loadFromPath(pkg.getSplits().get(0).getPath(),
+ ApkAssets.PROPERTY_ONLY_OVERLAYABLES);
return apkAssets.getOverlayableInfo(targetOverlayableName);
} finally {
if (apkAssets != null) {