Fail install when resources.arsc is compressed

If an application targets R+, prevent the application from being
installed if the app has a compressed resources.arsc or if the
resources.arsc is not aligned on a 4-byte boundary. Resources tables
that cannot be memory mapped have to be read into a buffer in RAM
and exert unnecessary memory pressure on the system.

Bug: 132742131
Test: manual (adding CTS tests)
Change-Id: Ieef764c87643863de24531fac12cc520fe6d90d0
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index eaf452b..b9765ea 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -331,6 +331,11 @@
   return true;
 }
 
+bool AssetManager2::ContainsAllocatedTable() const {
+  return std::find_if(apk_assets_.begin(), apk_assets_.end(),
+                      std::mem_fn(&ApkAssets::IsTableAllocated)) != apk_assets_.end();
+}
+
 void AssetManager2::SetConfiguration(const ResTable_config& configuration) {
   const int diff = configuration_.diff(configuration);
   configuration_ = configuration;
diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h
index 879b050..e57490a 100644
--- a/libs/androidfw/include/androidfw/ApkAssets.h
+++ b/libs/androidfw/include/androidfw/ApkAssets.h
@@ -119,31 +119,36 @@
       package_property_t flags = 0U,
       std::unique_ptr<const AssetsProvider> override_asset = nullptr);
 
-  inline const std::string& GetPath() const {
+  const std::string& GetPath() const {
     return path_;
   }
 
-  inline const AssetsProvider* GetAssetsProvider() const {
+  const AssetsProvider* GetAssetsProvider() const {
     return assets_provider_.get();
   }
 
   // This is never nullptr.
-  inline const LoadedArsc* GetLoadedArsc() const {
+  const LoadedArsc* GetLoadedArsc() const {
     return loaded_arsc_.get();
   }
 
-  inline const LoadedIdmap* GetLoadedIdmap() const {
+  const LoadedIdmap* GetLoadedIdmap() const {
     return loaded_idmap_.get();
   }
 
-  inline bool IsLoader() const {
+  bool IsLoader() const {
     return (property_flags_ & PROPERTY_LOADER) != 0;
   }
 
-  inline bool IsOverlay() const {
+  bool IsOverlay() const {
     return loaded_idmap_ != nullptr;
   }
 
+  // Returns whether the resources.arsc is allocated in RAM (not mmapped).
+  bool IsTableAllocated() const {
+    return resources_asset_ && resources_asset_->isAllocated();
+  }
+
   bool IsUpToDate() const;
 
   // Creates an Asset from a file on disk.
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index e21abad..30ef25c 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -134,6 +134,9 @@
   const std::unordered_map<std::string, std::string>*
     GetOverlayableMapForPackage(uint32_t package_id) const;
 
+  // Returns whether the resources.arsc of any loaded apk assets is allocated in RAM (not mmapped).
+  bool ContainsAllocatedTable() const;
+
   // Sets/resets the configuration for this AssetManager. This will cause all
   // caches that are related to the configuration change to be invalidated.
   void SetConfiguration(const ResTable_config& configuration);