diff options
-rw-r--r-- | core/java/android/content/res/ApkAssets.java | 5 | ||||
-rw-r--r-- | libs/androidfw/LoadedArsc.cpp | 21 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/LoadedArsc.h | 3 | ||||
-rw-r--r-- | services/core/java/com/android/server/om/OverlayManagerService.java | 3 |
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) { |