Store string frros in a string pool and copy that pool to the idmap
Bug: 232940948
Test: manual with test app and added automated tests
Change-Id: I30f5efefff7cf4fb0869188be78cc08e8efe7f04
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 2beb33a..9aa3787 100755
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -141,6 +141,9 @@
return {};
}
loaded_arsc = LoadedArsc::Load(data, length, loaded_idmap.get(), property_flags);
+ } else if (loaded_idmap != nullptr &&
+ IsFabricatedOverlay(std::string(loaded_idmap->OverlayApkPath()))) {
+ loaded_arsc = LoadedArsc::Load(loaded_idmap.get());
} else {
loaded_arsc = LoadedArsc::CreateEmpty();
}
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index 35b6170..5b69cca 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -820,6 +820,13 @@
return true;
}
+bool LoadedArsc::LoadStringPool(const LoadedIdmap* loaded_idmap) {
+ if (loaded_idmap != nullptr) {
+ global_string_pool_ = util::make_unique<OverlayStringPool>(loaded_idmap);
+ }
+ return true;
+}
+
std::unique_ptr<LoadedArsc> LoadedArsc::Load(incfs::map_ptr<void> data,
const size_t length,
const LoadedIdmap* loaded_idmap,
@@ -855,6 +862,16 @@
return loaded_arsc;
}
+std::unique_ptr<LoadedArsc> LoadedArsc::Load(const LoadedIdmap* loaded_idmap) {
+ ATRACE_NAME("LoadedArsc::Load");
+
+ // Not using make_unique because the constructor is private.
+ std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc());
+ loaded_arsc->LoadStringPool(loaded_idmap);
+ return loaded_arsc;
+}
+
+
std::unique_ptr<LoadedArsc> LoadedArsc::CreateEmpty() {
return std::unique_ptr<LoadedArsc>(new LoadedArsc());
}
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index b3d6a4d..e459639 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -314,6 +314,8 @@
const LoadedIdmap* loaded_idmap = nullptr,
package_property_t property_flags = 0U);
+ static std::unique_ptr<LoadedArsc> Load(const LoadedIdmap* loaded_idmap = nullptr);
+
// Create an empty LoadedArsc. This is used when an APK has no resources.arsc.
static std::unique_ptr<LoadedArsc> CreateEmpty();
@@ -338,6 +340,7 @@
LoadedArsc() = default;
bool LoadTable(
const Chunk& chunk, const LoadedIdmap* loaded_idmap, package_property_t property_flags);
+ bool LoadStringPool(const LoadedIdmap* loaded_idmap);
std::unique_ptr<ResStringPool> global_string_pool_ = util::make_unique<ResStringPool>();
std::vector<std::unique_ptr<const LoadedPackage>> packages_;
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 3d66244..8c614bc 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -53,7 +53,7 @@
// The version should only be changed when a backwards-incompatible change must be made to the
// fabricated overlay file format. Old fabricated overlays must be migrated to the new file format
// to prevent losing fabricated overlay data.
-constexpr const uint32_t kFabricatedOverlayCurrentVersion = 1;
+constexpr const uint32_t kFabricatedOverlayCurrentVersion = 2;
// Returns whether or not the path represents a fabricated overlay.
bool IsFabricatedOverlay(const std::string& path);