Do not look for R.class of overlays

Now that RROs are loaded as shared libraries,
LoadedApk#makeApplication is attempting to find the onResourcesLoaded
method of the overlays. This is a performance hit and causes more
memory than necessary to be allocated during application start up.

Bug: 143314947
Test: com.android.performance.tests.HermeticMemoryTest
Change-Id: I3b8cd22dae83e0164d6678c80279f9fffceb34e6
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index f0b3546..e858e6a 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -1215,7 +1215,8 @@
         }
 
         // Rewrite the R 'constants' for all library apks.
-        SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
+        SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers(
+                false, false);
         final int N = packageIdentifiers.size();
         for (int i = 0; i < N; i++) {
             final int id = packageIdentifiers.keyAt(i);
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 23e7720..070e282 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -1491,9 +1491,17 @@
      */
     @UnsupportedAppUsage
     public SparseArray<String> getAssignedPackageIdentifiers() {
+        return getAssignedPackageIdentifiers(true, true);
+    }
+
+    /**
+     * @hide
+     */
+    public SparseArray<String> getAssignedPackageIdentifiers(boolean includeOverlays,
+            boolean includeLoaders) {
         synchronized (this) {
             ensureValidLocked();
-            return nativeGetAssignedPackageIdentifiers(mObject);
+            return nativeGetAssignedPackageIdentifiers(mObject, includeOverlays, includeLoaders);
         }
     }
 
@@ -1557,7 +1565,7 @@
             int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, int screenLayout,
             int uiMode, int colorMode, int majorVersion);
     private static native @NonNull SparseArray<String> nativeGetAssignedPackageIdentifiers(
-            long ptr);
+            long ptr, boolean includeOverlays, boolean includeLoaders);
 
     // File native methods.
     private static native @Nullable String[] nativeList(long ptr, @NonNull String path)
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 3c0971b..5c4dc23 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -556,7 +556,9 @@
   assetmanager->SetConfiguration(configuration);
 }
 
-static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/, jlong ptr) {
+static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/, jlong ptr,
+                                                   jboolean includeOverlays,
+                                                   jboolean includeLoaders) {
   ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
 
   jobject sparse_array =
@@ -567,6 +569,10 @@
     return nullptr;
   }
 
+  // Optionally exclude overlays and loaders.
+  uint64_t exclusion_flags = ((includeOverlays) ? 0U : PROPERTY_OVERLAY)
+      | ((includeLoaders) ? 0U : PROPERTY_LOADER);
+
   assetmanager->ForEachPackage([&](const std::string& package_name, uint8_t package_id) -> bool {
     jstring jpackage_name = env->NewStringUTF(package_name.c_str());
     if (jpackage_name == nullptr) {
@@ -577,7 +583,8 @@
     env->CallVoidMethod(sparse_array, gSparseArrayOffsets.put, static_cast<jint>(package_id),
                         jpackage_name);
     return true;
-  });
+  }, exclusion_flags);
+
   return sparse_array;
 }
 
@@ -1591,7 +1598,7 @@
     {"nativeSetApkAssets", "(J[Landroid/content/res/ApkAssets;Z)V", (void*)NativeSetApkAssets},
     {"nativeSetConfiguration", "(JIILjava/lang/String;IIIIIIIIIIIIIII)V",
      (void*)NativeSetConfiguration},
-    {"nativeGetAssignedPackageIdentifiers", "(J)Landroid/util/SparseArray;",
+    {"nativeGetAssignedPackageIdentifiers", "(JZZ)Landroid/util/SparseArray;",
      (void*)NativeGetAssignedPackageIdentifiers},
 
     // AssetManager file methods.
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 16dbbf6..18934fd 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -43,20 +43,22 @@
 ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle,
                      const std::string& path,
                      time_t last_mod_time,
-                     bool for_loader)
+                     package_property_t property_flags)
     : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path), last_mod_time_(last_mod_time),
-      for_loader_(for_loader) {
+      property_flags_(property_flags) {
 }
 
 std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system,
                                                  bool for_loader) {
-  return LoadImpl({} /*fd*/, path, nullptr, nullptr, system, false /*load_as_shared_library*/,
-                  for_loader);
+  package_property_t flags = (system ? PROPERTY_SYSTEM : 0U) |
+                             (for_loader ? PROPERTY_LOADER : 0U);
+  return LoadImpl({} /*fd*/, path, nullptr, nullptr, flags);
 }
 
 std::unique_ptr<const ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path,
                                                                 bool system) {
-  return LoadImpl({} /*fd*/, path, nullptr, nullptr, system, true /*load_as_shared_library*/);
+  package_property_t flags = PROPERTY_DYNAMIC | (system ? PROPERTY_SYSTEM : 0U);
+  return LoadImpl({} /*fd*/, path, nullptr, nullptr, flags);
 }
 
 std::unique_ptr<const ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap_path,
@@ -74,27 +76,33 @@
     LOG(ERROR) << "failed to load IDMAP " << idmap_path;
     return {};
   }
-  return LoadImpl({} /*fd*/, loaded_idmap->OverlayApkPath(), std::move(idmap_asset),
-                  std::move(loaded_idmap), system, true /*load_as_shared_library*/);
+
+  return LoadImpl({} /*fd*/, loaded_idmap->OverlayApkPath(),
+                  std::move(idmap_asset),
+                  std::move(loaded_idmap),
+                  PROPERTY_OVERLAY | (system ? PROPERTY_SYSTEM : 0U));
 }
 
 std::unique_ptr<const ApkAssets> ApkAssets::LoadFromFd(unique_fd fd,
                                                        const std::string& friendly_name,
                                                        bool system, bool force_shared_lib,
                                                        bool for_loader) {
+  package_property_t flags = (system ? PROPERTY_SYSTEM : 0U) |
+                             (force_shared_lib ? PROPERTY_DYNAMIC : 0U) |
+                             (for_loader ? PROPERTY_LOADER : 0U);
   return LoadImpl(std::move(fd), friendly_name, nullptr /*idmap_asset*/, nullptr /*loaded_idmap*/,
-                  system, force_shared_lib, for_loader);
+                  flags);
 }
 
 std::unique_ptr<const ApkAssets> ApkAssets::LoadArsc(const std::string& path,
                                                      bool for_loader) {
-  return LoadArscImpl({} /*fd*/, path, for_loader);
+  return LoadArscImpl({} /*fd*/, path, for_loader ? PROPERTY_LOADER : 0U);
 }
 
 std::unique_ptr<const ApkAssets> ApkAssets::LoadArsc(unique_fd fd,
                                                      const std::string& friendly_name,
                                                      bool for_loader) {
-  return LoadArscImpl(std::move(fd), friendly_name, for_loader);
+  return LoadArscImpl(std::move(fd), friendly_name, for_loader ? PROPERTY_LOADER : 0U);
 }
 
 std::unique_ptr<Asset> ApkAssets::CreateAssetFromFile(const std::string& path) {
@@ -120,8 +128,7 @@
 
 std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
     unique_fd fd, const std::string& path, std::unique_ptr<Asset> idmap_asset,
-    std::unique_ptr<const LoadedIdmap> loaded_idmap, bool system, bool load_as_shared_library,
-    bool for_loader) {
+    std::unique_ptr<const LoadedIdmap> loaded_idmap, package_property_t property_flags) {
   ::ZipArchiveHandle unmanaged_handle;
   int32_t result;
   if (fd >= 0) {
@@ -141,7 +148,7 @@
 
   // Wrap the handle in a unique_ptr so it gets automatically closed.
   std::unique_ptr<ApkAssets>
-      loaded_apk(new ApkAssets(unmanaged_handle, path, last_mod_time, for_loader));
+      loaded_apk(new ApkAssets(unmanaged_handle, path, last_mod_time, property_flags));
 
   // Find the resource table.
   ::ZipEntry entry;
@@ -170,9 +177,8 @@
   const StringPiece data(
       reinterpret_cast<const char*>(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/)),
       loaded_apk->resources_asset_->getLength());
-  loaded_apk->loaded_arsc_ =
-      LoadedArsc::Load(data, loaded_apk->loaded_idmap_.get(), system, load_as_shared_library,
-                       for_loader);
+  loaded_apk->loaded_arsc_ = LoadedArsc::Load(data, loaded_apk->loaded_idmap_.get(),
+                                              property_flags);
   if (loaded_apk->loaded_arsc_ == nullptr) {
     LOG(ERROR) << "Failed to load '" << kResourcesArsc << "' in APK '" << path << "'.";
     return {};
@@ -184,7 +190,7 @@
 
 std::unique_ptr<const ApkAssets> ApkAssets::LoadArscImpl(unique_fd fd,
                                                          const std::string& path,
-                                                         bool for_loader) {
+                                                         package_property_t property_flags) {
   std::unique_ptr<Asset> resources_asset;
 
   if (fd >= 0) {
@@ -201,13 +207,14 @@
 
   time_t last_mod_time = getFileModDate(path.c_str());
 
-  std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(nullptr, path, last_mod_time, for_loader));
+  std::unique_ptr<ApkAssets> loaded_apk(
+      new ApkAssets(nullptr, path, last_mod_time, property_flags));
   loaded_apk->resources_asset_ = std::move(resources_asset);
 
   const StringPiece data(
       reinterpret_cast<const char*>(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/)),
       loaded_apk->resources_asset_->getLength());
-  loaded_apk->loaded_arsc_ = LoadedArsc::Load(data, nullptr, false, false, for_loader);
+  loaded_apk->loaded_arsc_ = LoadedArsc::Load(data, nullptr, property_flags);
   if (loaded_apk->loaded_arsc_ == nullptr) {
     LOG(ERROR) << "Failed to load '" << kResourcesArsc << path;
     return {};
@@ -320,8 +327,8 @@
 }
 
 bool ApkAssets::IsUpToDate() const {
-  // Loaders are invalidated by the app, not the system, so assume up to date
-  if (for_loader_) {
+  if (IsLoader()) {
+    // Loaders are invalidated by the app, not the system, so assume up to date.
     return true;
   }
 
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp
index 2b69c92..773353d 100644
--- a/libs/androidfw/Idmap.cpp
+++ b/libs/androidfw/Idmap.cpp
@@ -44,8 +44,8 @@
 }
 
 OverlayStringPool::OverlayStringPool(const LoadedIdmap* loaded_idmap)
-                                     : data_header_(loaded_idmap->data_header_),
-                                       idmap_string_pool_(loaded_idmap->string_pool_.get()) { };
+    : data_header_(loaded_idmap->data_header_),
+      idmap_string_pool_(loaded_idmap->string_pool_.get()) { };
 
 OverlayStringPool::~OverlayStringPool() {
   uninit();
@@ -188,11 +188,12 @@
                          const Idmap_data_header* data_header,
                          const Idmap_target_entry* target_entries,
                          const Idmap_overlay_entry* overlay_entries,
-                         ResStringPool* string_pool) : header_(header),
-                                                       data_header_(data_header),
-                                                       target_entries_(target_entries),
-                                                       overlay_entries_(overlay_entries),
-                                                       string_pool_(string_pool) {
+                         ResStringPool* string_pool)
+     : header_(header),
+       data_header_(data_header),
+       target_entries_(target_entries),
+       overlay_entries_(overlay_entries),
+       string_pool_(string_pool) {
 
   size_t length = strnlen(reinterpret_cast<const char*>(header_->overlay_path),
                           arraysize(header_->overlay_path));
@@ -264,7 +265,7 @@
     }
   }
 
-   // Can't use make_unique because LoadedImpl constructor is private.
+  // Can't use make_unique because LoadedIdmap constructor is private.
   std::unique_ptr<LoadedIdmap> loaded_idmap = std::unique_ptr<LoadedIdmap>(
       new LoadedIdmap(header, data_header, target_entries, overlay_entries,
                       idmap_string_pool.release()));
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index c896241..e35c024 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -397,9 +397,7 @@
 }
 
 std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
-                                                         bool system,
-                                                         bool load_as_shared_library,
-                                                         bool for_loader) {
+                                                         package_property_t property_flags) {
   ATRACE_NAME("LoadedPackage::Load");
   std::unique_ptr<LoadedPackage> loaded_package(new LoadedPackage());
 
@@ -413,17 +411,24 @@
     return {};
   }
 
-  loaded_package->system_ = system;
+  if ((property_flags & PROPERTY_SYSTEM) != 0) {
+    loaded_package->property_flags_ |= PROPERTY_SYSTEM;
+  }
+
+  if ((property_flags & PROPERTY_LOADER) != 0) {
+    loaded_package->property_flags_ |= PROPERTY_LOADER;
+  }
+
+  if ((property_flags & PROPERTY_OVERLAY) != 0) {
+    // Overlay resources must have an exclusive resource id space for referencing internal
+    // resources.
+    loaded_package->property_flags_ |= PROPERTY_OVERLAY | PROPERTY_DYNAMIC;
+  }
 
   loaded_package->package_id_ = dtohl(header->id);
   if (loaded_package->package_id_ == 0 ||
-      (loaded_package->package_id_ == kAppPackageId && load_as_shared_library)) {
-    // Package ID of 0 means this is a shared library.
-    loaded_package->dynamic_ = true;
-  }
-
-  if (for_loader) {
-    loaded_package->custom_loader_ = true;
+      (loaded_package->package_id_ == kAppPackageId && (property_flags & PROPERTY_DYNAMIC) != 0)) {
+    loaded_package->property_flags_ |= PROPERTY_DYNAMIC;
   }
 
   if (header->header.headerSize >= sizeof(ResTable_package)) {
@@ -677,7 +682,7 @@
 }
 
 bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
-                           bool load_as_shared_library, bool for_loader) {
+                           package_property_t property_flags) {
   const ResTable_header* header = chunk.header<ResTable_header>();
   if (header == nullptr) {
     LOG(ERROR) << "RES_TABLE_TYPE too small.";
@@ -720,7 +725,7 @@
         packages_seen++;
 
         std::unique_ptr<const LoadedPackage> loaded_package =
-            LoadedPackage::Load(child_chunk, system_, load_as_shared_library, for_loader);
+            LoadedPackage::Load(child_chunk, property_flags);
         if (!loaded_package) {
           return false;
         }
@@ -744,24 +749,18 @@
 
 std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const StringPiece& data,
                                                    const LoadedIdmap* loaded_idmap,
-                                                   bool system,
-                                                   bool load_as_shared_library,
-                                                   bool for_loader) {
+                                                   package_property_t property_flags) {
   ATRACE_NAME("LoadedArsc::Load");
 
   // Not using make_unique because the constructor is private.
   std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc());
-  loaded_arsc->system_ = system;
 
   ChunkIterator iter(data.data(), data.size());
   while (iter.HasNext()) {
     const Chunk chunk = iter.Next();
     switch (chunk.type()) {
       case RES_TABLE_TYPE:
-        if (!loaded_arsc->LoadTable(chunk,
-                                    loaded_idmap,
-                                    load_as_shared_library,
-                                    for_loader)) {
+        if (!loaded_arsc->LoadTable(chunk, loaded_idmap, property_flags)) {
           return {};
         }
         break;
diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h
index 2047287..af802b0 100644
--- a/libs/androidfw/include/androidfw/ApkAssets.h
+++ b/libs/androidfw/include/androidfw/ApkAssets.h
@@ -76,10 +76,10 @@
   // Takes ownership of the file descriptor.
   static std::unique_ptr<const ApkAssets> LoadArsc(base::unique_fd fd,
                                                    const std::string& friendly_name,
-                                                   bool resource_loader = false);
+                                                   bool for_loader = false);
 
   // Creates a totally empty ApkAssets with no resources table and no file entries.
-  static std::unique_ptr<const ApkAssets> LoadEmpty(bool resource_loader = false);
+  static std::unique_ptr<const ApkAssets> LoadEmpty(bool for_loader = false);
 
   std::unique_ptr<Asset> Open(const std::string& path,
                               Asset::AccessMode mode = Asset::AccessMode::ACCESS_RANDOM) const;
@@ -100,12 +100,12 @@
     return loaded_idmap_.get();
   }
 
-  inline bool IsOverlay() const {
-    return idmap_asset_.get() != nullptr;
+  inline bool IsLoader() const {
+    return (property_flags_ & PROPERTY_LOADER) != 0;
   }
 
-  inline bool IsLoader() const {
-    return for_loader_;
+  inline bool IsOverlay() const {
+    return (property_flags_ & PROPERTY_OVERLAY) != 0;
   }
 
   bool IsUpToDate() const;
@@ -119,24 +119,23 @@
   static std::unique_ptr<const ApkAssets> LoadImpl(base::unique_fd fd, const std::string& path,
                                                    std::unique_ptr<Asset> idmap_asset,
                                                    std::unique_ptr<const LoadedIdmap> loaded_idmap,
-                                                   bool system, bool load_as_shared_library,
-                                                   bool resource_loader = false);
+                                                   package_property_t property_flags);
 
   static std::unique_ptr<const ApkAssets> LoadArscImpl(base::unique_fd fd,
                                                        const std::string& path,
-                                                       bool resource_loader = false);
+                                                       package_property_t property_flags);
 
   ApkAssets(ZipArchiveHandle unmanaged_handle,
             const std::string& path,
             time_t last_mod_time,
-            bool for_loader = false);
+            package_property_t property_flags);
 
   using ZipArchivePtr = std::unique_ptr<ZipArchive, void (*)(ZipArchiveHandle)>;
 
   ZipArchivePtr zip_handle_;
   const std::string path_;
   time_t last_mod_time_;
-  bool for_loader_;
+  package_property_t property_flags_ = 0U;
   std::unique_ptr<Asset> resources_asset_;
   std::unique_ptr<Asset> idmap_asset_;
   std::unique_ptr<const LoadedArsc> loaded_arsc_;
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index 20e4023..00cbbca 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -263,10 +263,13 @@
   // Creates a new Theme from this AssetManager.
   std::unique_ptr<Theme> NewTheme();
 
-  void ForEachPackage(const std::function<bool(const std::string&, uint8_t)> func) const {
+  void ForEachPackage(const std::function<bool(const std::string&, uint8_t)> func,
+                      package_property_t excluded_property_flags = 0U) const {
     for (const PackageGroup& package_group : package_groups_) {
-      if (!func(package_group.packages_.front().loaded_package_->GetPackageName(),
-           package_group.dynamic_ref_table->mAssignedPackageId)) {
+      const auto loaded_package = package_group.packages_.front().loaded_package_;
+      if ((loaded_package->GetPropertyFlags() & excluded_property_flags) == 0U
+          && !func(loaded_package->GetPackageName(),
+                   package_group.dynamic_ref_table->mAssignedPackageId)) {
         return;
       }
     }
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index ba1beaa..6cbda07 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -69,6 +69,14 @@
   }
 };
 
+using package_property_t = uint32_t;
+enum : package_property_t {
+  PROPERTY_DYNAMIC = 1,
+  PROPERTY_LOADER = 2,
+  PROPERTY_OVERLAY = 4,
+  PROPERTY_SYSTEM = 8,
+};
+
 // TypeSpecPtr points to a block of memory that holds a TypeSpec struct, followed by an array of
 // ResTable_type pointers.
 // TypeSpecPtr is a managed pointer that knows how to delete itself.
@@ -131,9 +139,8 @@
     return iterator(this, resource_ids_.size() + 1, 0);
   }
 
-  static std::unique_ptr<const LoadedPackage> Load(const Chunk& chunk, bool system,
-                                                   bool load_as_shared_library,
-                                                   bool load_as_custom_loader);
+  static std::unique_ptr<const LoadedPackage> Load(const Chunk& chunk,
+                                                   package_property_t property_flags);
 
   ~LoadedPackage();
 
@@ -170,17 +177,26 @@
 
   // Returns true if this package is dynamic (shared library) and needs to have an ID assigned.
   inline bool IsDynamic() const {
-    return dynamic_;
+    return (property_flags_ & PROPERTY_DYNAMIC) != 0;
+  }
+
+  // Returns true if this package is a Runtime Resource Overlay.
+  inline bool IsOverlay() const {
+    return (property_flags_ & PROPERTY_OVERLAY) != 0;
   }
 
   // Returns true if this package originates from a system provided resource.
   inline bool IsSystem() const {
-    return system_;
+    return (property_flags_ & PROPERTY_SYSTEM) != 0;
   }
 
-  // Returns true if this package is a custom loader and should behave like an overlay
+  // Returns true if this package is a custom loader and should behave like an overlay.
   inline bool IsCustomLoader() const {
-    return custom_loader_;
+    return (property_flags_ & PROPERTY_LOADER) != 0;
+  }
+
+  inline package_property_t GetPropertyFlags() const {
+    return property_flags_;
   }
 
   // Returns the map of package name to package ID used in this LoadedPackage. At runtime, a
@@ -248,12 +264,10 @@
   ResStringPool type_string_pool_;
   ResStringPool key_string_pool_;
   std::string package_name_;
+  bool defines_overlayable_ = false;
   int package_id_ = -1;
   int type_id_offset_ = 0;
-  bool dynamic_ = false;
-  bool system_ = false;
-  bool custom_loader_ = false;
-  bool defines_overlayable_ = false;
+  package_property_t property_flags_ = 0U;
 
   ByteBucketArray<TypeSpecPtr> type_specs_;
   ByteBucketArray<uint32_t> resource_ids_;
@@ -274,9 +288,7 @@
   // ID.
   static std::unique_ptr<const LoadedArsc> Load(const StringPiece& data,
                                                 const LoadedIdmap* loaded_idmap = nullptr,
-                                                bool system = false,
-                                                bool load_as_shared_library = false,
-                                                bool for_loader = false);
+                                                package_property_t property_flags = 0U);
 
   // Create an empty LoadedArsc. This is used when an APK has no resources.arsc.
   static std::unique_ptr<const LoadedArsc> CreateEmpty();
@@ -296,28 +308,15 @@
     return packages_;
   }
 
-  // Returns true if this is a system provided resource.
-  inline bool IsSystem() const {
-    return system_;
-  }
-
  private:
   DISALLOW_COPY_AND_ASSIGN(LoadedArsc);
 
   LoadedArsc() = default;
-  bool LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, bool load_as_shared_library,
-                 bool for_loader);
-
-  static std::unique_ptr<const LoadedArsc> LoadData(std::unique_ptr<LoadedArsc>& loaded_arsc,
-                                                    const char* data,
-                                                    size_t length,
-                                                    const LoadedIdmap* loaded_idmap = nullptr,
-                                                    bool load_as_shared_library = false,
-                                                    bool for_loader = false);
+  bool LoadTable(
+      const Chunk& chunk, const LoadedIdmap* loaded_idmap, package_property_t property_flags);
 
   std::unique_ptr<ResStringPool> global_string_pool_ = util::make_unique<ResStringPool>();
   std::vector<std::unique_ptr<const LoadedPackage>> packages_;
-  bool system_ = false;
 };
 
 }  // namespace android
diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp
index 82dd335..8615069 100644
--- a/libs/androidfw/tests/LoadedArsc_test.cpp
+++ b/libs/androidfw/tests/LoadedArsc_test.cpp
@@ -144,8 +144,7 @@
                                       "resources.arsc", &contents));
 
   std::unique_ptr<const LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(StringPiece(contents), nullptr /* loaded_idmap */, false /*system*/,
-                       true /*load_as_shared_library*/);
+      LoadedArsc::Load(StringPiece(contents), nullptr /* loaded_idmap */, PROPERTY_DYNAMIC);
   ASSERT_THAT(loaded_arsc, NotNull());
 
   const auto& packages = loaded_arsc->GetPackages();
@@ -227,9 +226,7 @@
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/overlayable/overlayable.apk",
                                       "resources.arsc", &contents));
 
-  std::unique_ptr<const LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(StringPiece(contents), nullptr /* loaded_idmap */, false /*system*/,
-                       false /*load_as_shared_library*/);
+  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
 
   ASSERT_THAT(loaded_arsc, NotNull());
   const LoadedPackage* package = loaded_arsc->GetPackageById(
@@ -346,7 +343,7 @@
       asset->getLength());
 
   std::unique_ptr<const LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(data, nullptr, false, false, true);
+      LoadedArsc::Load(data, nullptr, PROPERTY_LOADER);
   ASSERT_THAT(loaded_arsc, NotNull());
 
   const LoadedPackage* package =