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

Commit 3eb06511 authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi Committed by Android (Google) Code Review
Browse files

Merge "[res] Overlayable only mode of loading ApkAssets"

parents 5bdcc9ec 75663392
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) {