Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 75663392 authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi
Browse files

[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
parent 06560ed4
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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,
+20 −1
Original line number Diff line number Diff line
@@ -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;

  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:
+3 −0
Original line number Diff line number Diff line
@@ -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 {
+2 −1
Original line number Diff line number Diff line
@@ -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) {