Allow for RRO internal referencing

This change allows RROs to reference their own internal resources as
expected.

Overlays are loaded as shared libraries so they can have their own
resource id space that does not conflict with the resource id space of
the target or other overlays.

References to overlay resources that override target resources now
appear as references to the target resources.

Overlay values that are inlined into the xml file specified using
android:overlayResources are now able to be used at runtime.

See go/rro-references for more information.

Bug: 135943783
Test: idmap2_tests
Test: libandroidfw_tests
Change-Id: Ie349c56d7fd3f7d94b7d595ed6d01dc6b59b6178
diff --git a/libs/androidfw/tests/ApkAssets_test.cpp b/libs/androidfw/tests/ApkAssets_test.cpp
index e2b9f00..0f2ee6f 100644
--- a/libs/androidfw/tests/ApkAssets_test.cpp
+++ b/libs/androidfw/tests/ApkAssets_test.cpp
@@ -79,39 +79,6 @@
   EXPECT_TRUE(loaded_arsc->GetPackages()[0]->IsDynamic());
 }
 
-TEST(ApkAssetsTest, LoadApkWithIdmap) {
-  std::string contents;
-  ResTable target_table;
-  const std::string target_path = GetTestDataPath() + "/basic/basic.apk";
-  ASSERT_TRUE(ReadFileFromZipToString(target_path, "resources.arsc", &contents));
-  ASSERT_THAT(target_table.add(contents.data(), contents.size(), 0, true /*copyData*/),
-              Eq(NO_ERROR));
-
-  ResTable overlay_table;
-  const std::string overlay_path = GetTestDataPath() + "/overlay/overlay.apk";
-  ASSERT_TRUE(ReadFileFromZipToString(overlay_path, "resources.arsc", &contents));
-  ASSERT_THAT(overlay_table.add(contents.data(), contents.size(), 0, true /*copyData*/),
-              Eq(NO_ERROR));
-
-  util::unique_cptr<void> idmap_data;
-  void* temp_data;
-  size_t idmap_len;
-
-  ASSERT_THAT(target_table.createIdmap(overlay_table, 0u, 0u, target_path.c_str(),
-                                       overlay_path.c_str(), &temp_data, &idmap_len),
-              Eq(NO_ERROR));
-  idmap_data.reset(temp_data);
-
-  TemporaryFile tf;
-  ASSERT_TRUE(base::WriteFully(tf.fd, idmap_data.get(), idmap_len));
-  close(tf.fd);
-
-  // Open something so that the destructor of TemporaryFile closes a valid fd.
-  tf.fd = open("/dev/null", O_WRONLY);
-
-  ASSERT_THAT(ApkAssets::LoadOverlay(tf.path), NotNull());
-}
-
 TEST(ApkAssetsTest, CreateAndDestroyAssetKeepsApkAssetsOpen) {
   std::unique_ptr<const ApkAssets> loaded_apk =
       ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp
index 1591024..b3190be 100644
--- a/libs/androidfw/tests/AssetManager2_test.cpp
+++ b/libs/androidfw/tests/AssetManager2_test.cpp
@@ -718,15 +718,17 @@
 
   const auto map = assetmanager.GetOverlayableMapForPackage(0x7f);
   ASSERT_NE(nullptr, map);
-  ASSERT_EQ(2, map->size());
+  ASSERT_EQ(3, map->size());
   ASSERT_EQ(map->at("OverlayableResources1"), "overlay://theme");
   ASSERT_EQ(map->at("OverlayableResources2"), "overlay://com.android.overlayable");
+  ASSERT_EQ(map->at("OverlayableResources3"), "");
 
   std::string api;
   ASSERT_TRUE(assetmanager.GetOverlayablesToString("com.android.overlayable", &api));
   ASSERT_EQ(api.find("not_overlayable"), std::string::npos);
   ASSERT_NE(api.find("resource='com.android.overlayable:string/overlayable2' overlayable='OverlayableResources1' actor='overlay://theme' policy='0x0000000a'\n"),
             std::string::npos);
+
 }
 
 }  // namespace android
diff --git a/libs/androidfw/tests/Idmap_test.cpp b/libs/androidfw/tests/Idmap_test.cpp
index 10b83a7..b679672 100644
--- a/libs/androidfw/tests/Idmap_test.cpp
+++ b/libs/androidfw/tests/Idmap_test.cpp
@@ -14,114 +14,231 @@
  * limitations under the License.
  */
 
+#include "android-base/file.h"
+#include "androidfw/ApkAssets.h"
+#include "androidfw/AssetManager2.h"
 #include "androidfw/ResourceTypes.h"
 
 #include "utils/String16.h"
 #include "utils/String8.h"
 
 #include "TestHelpers.h"
-#include "data/basic/R.h"
+#include "data/overlay/R.h"
+#include "data/overlayable/R.h"
+#include "data/system/R.h"
 
-using ::com::android::basic::R;
+namespace overlay = com::android::overlay;
+namespace overlayable = com::android::overlayable;
 
 namespace android {
 
+namespace {
+
 class IdmapTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    std::string contents;
-    ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc",
-                                        &contents));
-    ASSERT_EQ(NO_ERROR, target_table_.add(contents.data(), contents.size(), 0, true));
+    // Move to the test data directory so the idmap can locate the overlay APK.
+    std::string original_path = base::GetExecutableDirectory();
+    chdir(GetTestDataPath().c_str());
 
-    ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/overlay/overlay.apk",
-                                        "resources.arsc", &overlay_data_));
-    ResTable overlay_table;
-    ASSERT_EQ(NO_ERROR, overlay_table.add(overlay_data_.data(), overlay_data_.size()));
+    system_assets_ = ApkAssets::Load("system/system.apk");
+    ASSERT_NE(nullptr, system_assets_);
 
-    char target_name[256] = "com.android.basic";
-    ASSERT_EQ(NO_ERROR, overlay_table.createIdmap(target_table_, 0, 0, target_name, target_name,
-                                                  &data_, &data_size_));
+    overlay_assets_ = ApkAssets::LoadOverlay("overlay/overlay.idmap");
+    ASSERT_NE(nullptr, overlay_assets_);
+
+    overlayable_assets_ = ApkAssets::Load("overlayable/overlayable.apk");
+    ASSERT_NE(nullptr, overlayable_assets_);
+    chdir(original_path.c_str());
   }
 
-  void TearDown() override {
-    ::free(data_);
-  }
-
-  ResTable target_table_;
-  std::string overlay_data_;
-  void* data_ = nullptr;
-  size_t data_size_ = 0;
+ protected:
+  std::unique_ptr<const ApkAssets> system_assets_;
+  std::unique_ptr<const ApkAssets> overlay_assets_;
+  std::unique_ptr<const ApkAssets> overlayable_assets_;
 };
 
-TEST_F(IdmapTest, CanLoadIdmap) {
-  ASSERT_EQ(NO_ERROR,
-            target_table_.add(overlay_data_.data(), overlay_data_.size(), data_, data_size_));
+std::string GetStringFromApkAssets(const AssetManager2& asset_manager, const Res_value& value,
+                                   ApkAssetsCookie cookie) {
+  auto assets = asset_manager.GetApkAssets();
+  const ResStringPool* string_pool = assets[cookie]->GetLoadedArsc()->GetStringPool();
+  return GetStringFromPool(string_pool, value.data);
+}
+
 }
 
 TEST_F(IdmapTest, OverlayOverridesResourceValue) {
+  AssetManager2 asset_manager;
+  asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(),
+                              overlay_assets_.get()});
   Res_value val;
-  ssize_t block = target_table_.getResource(R::string::test2, &val, false);
-  ASSERT_GE(block, 0);
-  ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
-  const ResStringPool* pool = target_table_.getTableStringBlock(block);
-  ASSERT_TRUE(pool != NULL);
-  ASSERT_LT(val.data, pool->size());
+  ResTable_config config;
+  uint32_t flags;
+  ApkAssetsCookie cookie = asset_manager.GetResource(overlayable::R::string::overlayable5,
+                                                    false /* may_be_bag */,
+                                                    0 /* density_override */, &val, &config,
+                                                    &flags);
+  ASSERT_EQ(cookie, 2U);
+  ASSERT_EQ(val.dataType, Res_value::TYPE_STRING);
+  ASSERT_EQ(GetStringFromApkAssets(asset_manager, val, cookie), "Overlay One");
+}
 
-  size_t str_len;
-  const char16_t* target_str16 = pool->stringAt(val.data, &str_len);
-  ASSERT_TRUE(target_str16 != NULL);
-  ASSERT_EQ(String16("test2"), String16(target_str16, str_len));
+TEST_F(IdmapTest, OverlayOverridesResourceValueUsingDifferentPackage) {
+  AssetManager2 asset_manager;
+  asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(),
+                              overlay_assets_.get()});
+  Res_value val;
+  ResTable_config config;
+  uint32_t flags;
+  ApkAssetsCookie cookie = asset_manager.GetResource(overlayable::R::string::overlayable10,
+                                                    false /* may_be_bag */,
+                                                    0 /* density_override */, &val, &config,
+                                                    &flags);
+  ASSERT_EQ(cookie, 0U);
+  ASSERT_EQ(val.dataType, Res_value::TYPE_STRING);
+  ASSERT_EQ(GetStringFromApkAssets(asset_manager, val, cookie), "yes");
+}
 
-  ASSERT_EQ(NO_ERROR,
-            target_table_.add(overlay_data_.data(), overlay_data_.size(), data_, data_size_));
+TEST_F(IdmapTest, OverlayOverridesResourceValueUsingInternalResource) {
+  AssetManager2 asset_manager;
+  asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(),
+                              overlay_assets_.get()});
+  Res_value val;
+  ResTable_config config;
+  uint32_t flags;
+  ApkAssetsCookie cookie = asset_manager.GetResource(overlayable::R::string::overlayable8,
+                                                    false /* may_be_bag */,
+                                                    0 /* density_override */, &val, &config,
+                                                    &flags);
+  ASSERT_EQ(cookie, 2U);
+  ASSERT_EQ(val.dataType, Res_value::TYPE_REFERENCE);
+  ASSERT_EQ(val.data, (overlay::R::string::internal & 0x00ffffff) | (0x02 << 24));
+}
 
-  ssize_t new_block = target_table_.getResource(R::string::test2, &val, false);
-  ASSERT_GE(new_block, 0);
-  ASSERT_NE(block, new_block);
-  ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
-  pool = target_table_.getTableStringBlock(new_block);
-  ASSERT_TRUE(pool != NULL);
-  ASSERT_LT(val.data, pool->size());
+TEST_F(IdmapTest, OverlayOverridesResourceValueUsingInlineInteger) {
+  AssetManager2 asset_manager;
+  asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(),
+                              overlay_assets_.get()});
+  Res_value val;
+  ResTable_config config;
+  uint32_t flags;
+  ApkAssetsCookie cookie = asset_manager.GetResource(overlayable::R::integer::config_integer,
+                                                  false /* may_be_bag */,
+                                                  0 /* density_override */, &val, &config,
+                                                  &flags);
+  ASSERT_EQ(cookie, 2U);
+  ASSERT_EQ(val.dataType, Res_value::TYPE_INT_DEC);
+  ASSERT_EQ(val.data, 42);
+}
 
-  target_str16 = pool->stringAt(val.data, &str_len);
-  ASSERT_TRUE(target_str16 != NULL);
-  ASSERT_EQ(String16("test2-overlay"), String16(target_str16, str_len));
+TEST_F(IdmapTest, OverlayOverridesResourceValueUsingInlineString) {
+  AssetManager2 asset_manager;
+  asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(),
+                              overlay_assets_.get()});
+  Res_value val;
+  ResTable_config config;
+  uint32_t flags;
+
+  ApkAssetsCookie cookie = asset_manager.GetResource(overlayable::R::string::overlayable11,
+                                                  false /* may_be_bag */,
+                                                  0 /* density_override */, &val, &config,
+                                                  &flags);
+  ASSERT_EQ(cookie, 2U);
+  ASSERT_EQ(val.dataType, Res_value::TYPE_STRING);
+  ASSERT_EQ(GetStringFromApkAssets(asset_manager, val, cookie), "Hardcoded string");
+}
+
+TEST_F(IdmapTest, OverlayOverridesResourceValueUsingOverlayingResource) {
+  AssetManager2 asset_manager;
+  asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(),
+                              overlay_assets_.get()});
+  Res_value val;
+  ResTable_config config;
+  uint32_t flags;
+  ApkAssetsCookie cookie = asset_manager.GetResource(overlayable::R::string::overlayable9,
+                                                    false /* may_be_bag */,
+                                                    0 /* density_override */, &val, &config,
+                                                    &flags);
+  ASSERT_EQ(cookie, 2U);
+  ASSERT_EQ(val.dataType, Res_value::TYPE_REFERENCE);
+  ASSERT_EQ(val.data, overlayable::R::string::overlayable7);
+}
+
+TEST_F(IdmapTest, OverlayOverridesXmlParser) {
+  AssetManager2 asset_manager;
+  asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(),
+                              overlay_assets_.get()});
+  Res_value val;
+  ResTable_config config;
+  uint32_t flags;
+  ApkAssetsCookie cookie = asset_manager.GetResource(overlayable::R::layout::hello_view,
+                                                    false /* may_be_bag */,
+                                                    0 /* density_override */, &val, &config,
+                                                    &flags);
+  ASSERT_EQ(cookie, 2U);
+  ASSERT_EQ(val.dataType, Res_value::TYPE_STRING);
+  ASSERT_EQ(GetStringFromApkAssets(asset_manager, val, cookie), "res/layout/hello_view.xml");
+
+  auto asset = asset_manager.OpenNonAsset("res/layout/hello_view.xml", cookie,
+                                          Asset::ACCESS_RANDOM);
+  auto dynamic_ref_table = asset_manager.GetDynamicRefTableForCookie(cookie);
+  auto xml_tree = util::make_unique<ResXMLTree>(std::move(dynamic_ref_table));
+  status_t err = xml_tree->setTo(asset->getBuffer(true), asset->getLength(), false);
+  ASSERT_EQ(err, NO_ERROR);
+
+  while (xml_tree->next() != ResXMLParser::START_TAG) { }
+
+  // The resource id of @id/hello_view should be rewritten to the resource id/hello_view within the
+  // target.
+  ASSERT_EQ(xml_tree->getAttributeNameResID(0), 0x010100d0 /* android:attr/id */);
+  ASSERT_EQ(xml_tree->getAttributeDataType(0), Res_value::TYPE_REFERENCE);
+  ASSERT_EQ(xml_tree->getAttributeData(0), overlayable::R::id::hello_view);
+
+  // The resource id of @android:string/yes should not be rewritten even though it overlays
+  // string/overlayable10 in the target.
+  ASSERT_EQ(xml_tree->getAttributeNameResID(1), 0x0101014f /* android:attr/text */);
+  ASSERT_EQ(xml_tree->getAttributeDataType(1), Res_value::TYPE_REFERENCE);
+  ASSERT_EQ(xml_tree->getAttributeData(1), 0x01040013 /* android:string/yes */);
+
+  // The resource id of the attribute within the overlay should be rewritten to the resource id of
+  // the attribute in the target.
+  ASSERT_EQ(xml_tree->getAttributeNameResID(2), overlayable::R::attr::max_lines);
+  ASSERT_EQ(xml_tree->getAttributeDataType(2), Res_value::TYPE_INT_DEC);
+  ASSERT_EQ(xml_tree->getAttributeData(2), 4);
 }
 
 TEST_F(IdmapTest, OverlaidResourceHasSameName) {
-  ASSERT_EQ(NO_ERROR,
-            target_table_.add(overlay_data_.data(), overlay_data_.size(), data_, data_size_));
+  AssetManager2 asset_manager;
+  asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(),
+                              overlay_assets_.get()});
 
-  ResTable::resource_name res_name;
-  ASSERT_TRUE(target_table_.getResourceName(R::array::integerArray1, true, &res_name));
-
-  ASSERT_TRUE(res_name.package != NULL);
-  ASSERT_TRUE(res_name.type != NULL);
-  ASSERT_TRUE(res_name.name8 != NULL);
-
-  EXPECT_EQ(String16("com.android.basic"), String16(res_name.package, res_name.packageLen));
-  EXPECT_EQ(String16("array"), String16(res_name.type, res_name.typeLen));
-  EXPECT_EQ(String8("integerArray1"), String8(res_name.name8, res_name.nameLen));
+  AssetManager2::ResourceName name;
+  ASSERT_TRUE(asset_manager.GetResourceName(overlayable::R::string::overlayable9, &name));
+  ASSERT_EQ(std::string(name.package), "com.android.overlayable");
+  ASSERT_EQ(String16(name.type16), u"string");
+  ASSERT_EQ(std::string(name.entry), "overlayable9");
 }
 
-constexpr const uint32_t kNonOverlaidResourceId = 0x7fff0000u;
+TEST_F(IdmapTest, OverlayLoaderInterop) {
+  std::string contents;
+  auto loader_assets = ApkAssets::LoadArsc(GetTestDataPath() + "/loader/resources.arsc",
+                                           /* for_loader */ true);
 
-TEST_F(IdmapTest, OverlayDoesNotIncludeNonOverlaidResources) {
-  // First check that the resource we're trying to not include when overlaid is present when
-  // the overlay is loaded as a standalone APK.
-  ResTable table;
-  ASSERT_EQ(NO_ERROR, table.add(overlay_data_.data(), overlay_data_.size(), 0, true));
+  AssetManager2 asset_manager;
+  asset_manager.SetApkAssets({overlayable_assets_.get(), loader_assets.get(),
+                              overlay_assets_.get()});
 
   Res_value val;
-  ssize_t block = table.getResource(kNonOverlaidResourceId, &val, false /*mayBeBag*/);
-  ASSERT_GE(block, 0);
-
-  // Now add the overlay and verify that the unoverlaid resource is gone.
-  ASSERT_EQ(NO_ERROR,
-            target_table_.add(overlay_data_.data(), overlay_data_.size(), data_, data_size_));
-  block = target_table_.getResource(kNonOverlaidResourceId, &val, false /*mayBeBag*/);
-  ASSERT_LT(block, 0);
+  ResTable_config config;
+  uint32_t flags;
+  ApkAssetsCookie cookie = asset_manager.GetResource(overlayable::R::string::overlayable11,
+                                                    false /* may_be_bag */,
+                                                    0 /* density_override */, &val, &config,
+                                                    &flags);
+  std::cout << asset_manager.GetLastResourceResolution();
+  ASSERT_EQ(cookie, 1U);
+  ASSERT_EQ(val.dataType, Res_value::TYPE_STRING);
+  ASSERT_EQ(GetStringFromApkAssets(asset_manager, val, cookie), "loader");
 }
 
 }  // namespace
diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp
index fd57a92..82dd335 100644
--- a/libs/androidfw/tests/LoadedArsc_test.cpp
+++ b/libs/androidfw/tests/LoadedArsc_test.cpp
@@ -144,7 +144,7 @@
                                       "resources.arsc", &contents));
 
   std::unique_ptr<const LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(StringPiece(contents), nullptr /*loaded_idmap*/, false /*system*/,
+      LoadedArsc::Load(StringPiece(contents), nullptr /* loaded_idmap */, false /*system*/,
                        true /*load_as_shared_library*/);
   ASSERT_THAT(loaded_arsc, NotNull());
 
@@ -222,67 +222,13 @@
   ASSERT_THAT(type_spec->types[0], NotNull());
 }
 
-class MockLoadedIdmap : public LoadedIdmap {
- public:
-  MockLoadedIdmap() : LoadedIdmap() {
-    local_header_.magic = kIdmapMagic;
-    local_header_.version = kIdmapCurrentVersion;
-    local_header_.target_package_id = 0x08;
-    local_header_.type_count = 1;
-    header_ = &local_header_;
-
-    entry_header = util::unique_cptr<IdmapEntry_header>(
-        (IdmapEntry_header*)::malloc(sizeof(IdmapEntry_header) + sizeof(uint32_t)));
-    entry_header->target_type_id = 0x03;
-    entry_header->overlay_type_id = 0x02;
-    entry_header->entry_id_offset = 1;
-    entry_header->entry_count = 1;
-    entry_header->entries[0] = 0x00000000u;
-    type_map_[entry_header->overlay_type_id] = entry_header.get();
-  }
-
- private:
-  Idmap_header local_header_;
-  util::unique_cptr<IdmapEntry_header> entry_header;
-};
-
-TEST(LoadedArscTest, LoadOverlay) {
-  std::string contents;
-  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/overlay/overlay.apk", "resources.arsc",
-                                      &contents));
-
-  MockLoadedIdmap loaded_idmap;
-
-  std::unique_ptr<const LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(StringPiece(contents), &loaded_idmap);
-  ASSERT_THAT(loaded_arsc, NotNull());
-
-  const LoadedPackage* package = loaded_arsc->GetPackageById(0x08u);
-  ASSERT_THAT(package, NotNull());
-
-  const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(0x03u - 1);
-  ASSERT_THAT(type_spec, NotNull());
-  ASSERT_THAT(type_spec->type_count, Ge(1u));
-  ASSERT_THAT(type_spec->types[0], NotNull());
-
-  // The entry being overlaid doesn't exist at the original entry index.
-  ASSERT_THAT(LoadedPackage::GetEntry(type_spec->types[0], 0x0001u), IsNull());
-
-  // Since this is an overlay, the actual entry ID must be mapped.
-  ASSERT_THAT(type_spec->idmap_entries, NotNull());
-  uint16_t target_entry_id = 0u;
-  ASSERT_TRUE(LoadedIdmap::Lookup(type_spec->idmap_entries, 0x0001u, &target_entry_id));
-  ASSERT_THAT(target_entry_id, Eq(0x0u));
-  ASSERT_THAT(LoadedPackage::GetEntry(type_spec->types[0], 0x0000), NotNull());
-}
-
 TEST(LoadedArscTest, LoadOverlayable) {
   std::string contents;
   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*/,
+      LoadedArsc::Load(StringPiece(contents), nullptr /* loaded_idmap */, false /*system*/,
                        false /*load_as_shared_library*/);
 
   ASSERT_THAT(loaded_arsc, NotNull());
@@ -383,9 +329,10 @@
   ASSERT_EQ(std::string("com.android.overlayable"), packages[0]->GetPackageName());
 
   const auto map = packages[0]->GetOverlayableMap();
-  ASSERT_EQ(2, map.size());
+  ASSERT_EQ(3, map.size());
   ASSERT_EQ(map.at("OverlayableResources1"), "overlay://theme");
   ASSERT_EQ(map.at("OverlayableResources2"), "overlay://com.android.overlayable");
+  ASSERT_EQ(map.at("OverlayableResources3"), "");
 }
 
 TEST(LoadedArscTest, LoadCustomLoader) {
@@ -394,7 +341,6 @@
   std::unique_ptr<Asset>
       asset = ApkAssets::CreateAssetFromFile(GetTestDataPath() + "/loader/resources.arsc");
 
-  MockLoadedIdmap loaded_idmap;
   const StringPiece data(
       reinterpret_cast<const char*>(asset->getBuffer(true /*wordAligned*/)),
       asset->getLength());
@@ -404,13 +350,13 @@
   ASSERT_THAT(loaded_arsc, NotNull());
 
   const LoadedPackage* package =
-      loaded_arsc->GetPackageById(get_package_id(android::R::string::cancel));
+      loaded_arsc->GetPackageById(get_package_id(overlayable::R::string::overlayable11));
   ASSERT_THAT(package, NotNull());
-  EXPECT_THAT(package->GetPackageName(), StrEq("android"));
-  EXPECT_THAT(package->GetPackageId(), Eq(0x01));
+  EXPECT_THAT(package->GetPackageName(), StrEq("com.android.loader"));
+  EXPECT_THAT(package->GetPackageId(), Eq(0x7f));
 
-  const uint8_t type_index = get_type_id(android::R::string::cancel) - 1;
-  const uint16_t entry_index = get_entry_id(android::R::string::cancel);
+  const uint8_t type_index = get_type_id(overlayable::R::string::overlayable11) - 1;
+  const uint16_t entry_index = get_entry_id(overlayable::R::string::overlayable11);
 
   const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
   ASSERT_THAT(type_spec, NotNull());
diff --git a/libs/androidfw/tests/data/loader/AndroidManifest.xml b/libs/androidfw/tests/data/loader/AndroidManifest.xml
new file mode 100644
index 0000000..4c0bb47
--- /dev/null
+++ b/libs/androidfw/tests/data/loader/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest package="com.android.loader">
+    <application>
+    </application>
+</manifest>
diff --git a/libs/androidfw/tests/data/loader/build b/libs/androidfw/tests/data/loader/build
new file mode 100755
index 0000000..457ec51
--- /dev/null
+++ b/libs/androidfw/tests/data/loader/build
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set -e
+
+FRAMEWORK_RES_APK=${ANDROID_PRODUCT_OUT}/system/framework/framework-res.apk
+
+rm resources.arsc
+aapt2 compile --dir res -o compiled.flata
+aapt2 link -I $FRAMEWORK_RES_APK --manifest AndroidManifest.xml -o loader.apk compiled.flata
+unzip loader.apk resources.arsc
+rm loader.apk
+rm compiled.flata
diff --git a/libs/androidfw/tests/data/loader/res/values/public.xml b/libs/androidfw/tests/data/loader/res/values/public.xml
new file mode 100644
index 0000000..3293229
--- /dev/null
+++ b/libs/androidfw/tests/data/loader/res/values/public.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <public type="string" name="overlayable11" id="0x7f01000b" />
+</resources>
\ No newline at end of file
diff --git a/libs/androidfw/tests/data/loader/res/values/values.xml b/libs/androidfw/tests/data/loader/res/values/values.xml
new file mode 100644
index 0000000..0653536
--- /dev/null
+++ b/libs/androidfw/tests/data/loader/res/values/values.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="overlayable11">loader</string>
+</resources>
diff --git a/libs/androidfw/tests/data/loader/resources.arsc b/libs/androidfw/tests/data/loader/resources.arsc
index 2c881f2..2bdb288 100644
--- a/libs/androidfw/tests/data/loader/resources.arsc
+++ b/libs/androidfw/tests/data/loader/resources.arsc
Binary files differ
diff --git a/libs/androidfw/tests/data/overlay/AndroidManifest.xml b/libs/androidfw/tests/data/overlay/AndroidManifest.xml
index a56ac18..28a1148 100644
--- a/libs/androidfw/tests/data/overlay/AndroidManifest.xml
+++ b/libs/androidfw/tests/data/overlay/AndroidManifest.xml
@@ -15,7 +15,9 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.test.basic">
-    <application>
-    </application>
+    package="com.android.test.overlay">
+    <overlay
+        android:targetPackage="com.android.test.basic"
+        android:targetName="OverlayableResources3"
+        android:resourcesMap="@xml/overlays"/>
 </manifest>
diff --git a/libs/androidfw/tests/data/overlay/R.h b/libs/androidfw/tests/data/overlay/R.h
new file mode 100644
index 0000000..f3dbed2
--- /dev/null
+++ b/libs/androidfw/tests/data/overlay/R.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TESTS_DATA_OVERLAY_R_H_
+#define TESTS_DATA_OVERLAY_R_H_
+
+#include <cstdint>
+
+namespace com {
+namespace android {
+namespace overlay {
+
+struct R {
+  struct string {
+    enum : uint32_t {
+      internal = 0x7f040000,
+    };
+  };
+};
+
+}  // namespace overlay
+}  // namespace android
+}  // namespace com
+
+#endif /* TESTS_DATA_OVERLAY_R_H_ */
diff --git a/libs/androidfw/tests/data/overlay/build b/libs/androidfw/tests/data/overlay/build
index 716b1bd..99dfd63 100755
--- a/libs/androidfw/tests/data/overlay/build
+++ b/libs/androidfw/tests/data/overlay/build
@@ -17,6 +17,15 @@
 
 set -e
 
+FRAMEWORK_RES_APK=${ANDROID_PRODUCT_OUT}/system/framework/framework-res.apk
+
 aapt2 compile --dir res -o compiled.flata
-aapt2 link --manifest AndroidManifest.xml -o overlay.apk compiled.flata
+aapt2 link -I $FRAMEWORK_RES_APK --manifest AndroidManifest.xml -o overlay.apk compiled.flata \
+    --no-auto-version
 rm compiled.flata
+
+# Navigate back a directory so the idmap can find the overlays in the test data directory when being
+# loaded during testing.
+cd ../
+idmap2 create --target-apk-path overlayable/overlayable.apk \
+    --overlay-apk-path overlay/overlay.apk --idmap-path overlay/overlay.idmap
diff --git a/libs/androidfw/tests/data/overlay/overlay.apk b/libs/androidfw/tests/data/overlay/overlay.apk
index d37874d..c594b8e 100644
--- a/libs/androidfw/tests/data/overlay/overlay.apk
+++ b/libs/androidfw/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/overlay/overlay.idmap b/libs/androidfw/tests/data/overlay/overlay.idmap
new file mode 100644
index 0000000..27cf792f
--- /dev/null
+++ b/libs/androidfw/tests/data/overlay/overlay.idmap
Binary files differ
diff --git a/libs/androidfw/tests/data/overlay/res/layout/hello_view.xml b/libs/androidfw/tests/data/overlay/res/layout/hello_view.xml
new file mode 100644
index 0000000..54dc6c0
--- /dev/null
+++ b/libs/androidfw/tests/data/overlay/res/layout/hello_view.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/hello_view"
+    android:text="@android:string/yes"
+    app:max_lines="4"/>
\ No newline at end of file
diff --git a/libs/androidfw/tests/data/overlay/res/values/values.xml b/libs/androidfw/tests/data/overlay/res/values/values.xml
index 8e4417e..ba018ec 100644
--- a/libs/androidfw/tests/data/overlay/res/values/values.xml
+++ b/libs/androidfw/tests/data/overlay/res/values/values.xml
@@ -13,13 +13,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <resources>
-    <string name="test2">test2-overlay</string>
-    <integer-array name="integerArray1">
-        <item>10</item>
-        <item>11</item>
-    </integer-array>
-    <public type="animator" name="unoverlaid" id="0x7fff0000" />
-    <item type="animator" name="unoverlaid">@null</item>
+    <string name="overlay1">Overlay One</string>
+    <string name="overlay2">Overlay Two</string>
+    <string name="overlay3">@string/internal</string>
+    <string name="overlay4">@string/overlay2</string>
+    <string name="internal">Internal</string>
+    <attr name="max_lines" format="integer" />
 </resources>
diff --git a/libs/androidfw/tests/data/overlay/res/xml/overlays.xml b/libs/androidfw/tests/data/overlay/res/xml/overlays.xml
new file mode 100644
index 0000000..9eca2fa
--- /dev/null
+++ b/libs/androidfw/tests/data/overlay/res/xml/overlays.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language language governing permissions and
+     limitations under the License.
+-->
+<overlay>
+    <!-- Overlays string/overlayable5 with the string "Overlay One". -->
+    <item target="string/overlayable5" value="@string/overlay1"/>
+
+    <!-- Overlays string/overlayable6 and string/overlayable7 with the string "Overlay Two". -->
+    <item target="string/overlayable7" value="@string/overlay2" />
+    <item target="string/overlayable6" value="@string/overlay2" />
+
+    <!-- Overlays string/overlayable8 with a reference to @string/internal. -->
+    <item target="string/overlayable8" value="@string/overlay3" />
+
+    <!-- Overlays string/overlayable9 with a reference to @string/overlay2. The reference to
+         @string/overlay2 should be rewritten to @string/overlayable7 in the target. -->
+    <item target="string/overlayable9" value="@string/overlay4" />
+
+    <!-- Overlays string/overlayable10 with the string "yes". -->
+    <item target="string/overlayable10" value="@android:string/yes" />
+
+    <!-- Overlays string/overlayable11 with the string "Hardcoded string". -->
+    <item target="string/overlayable11" value="Hardcoded string" />
+
+    <!-- Overlays string/overlayable10 with the string "yes". -->
+    <item target="integer/config_int" value="42" />
+
+    <!-- @attr/max_lines and @id/hello_view should be rewritten to @attr/max_lines and
+         @id/hello_view in the target. -->
+    <item target="layout/hello_view" value="@layout/hello_view" />
+    <item target="attr/max_lines" value="@attr/max_lines" />
+    <item target="id/hello_view" value="@id/hello_view" />
+</overlay>
+
+
diff --git a/libs/androidfw/tests/data/overlayable/R.h b/libs/androidfw/tests/data/overlayable/R.h
index e46e264d..35125a6 100644
--- a/libs/androidfw/tests/data/overlayable/R.h
+++ b/libs/androidfw/tests/data/overlayable/R.h
@@ -31,6 +31,43 @@
       overlayable2 = 0x7f010002,
       overlayable3 = 0x7f010003,
       overlayable4 = 0x7f010004,
+      overlayable5 = 0x7f010005,
+      overlayable6 = 0x7f010006,
+      overlayable7 = 0x7f010007,
+      overlayable8 = 0x7f010008,
+      overlayable9 = 0x7f010009,
+      overlayable10 = 0x7f01000a,
+      overlayable11 = 0x7f01000b,
+    };
+  };
+
+  struct attr {
+    enum : uint32_t  {
+      max_lines = 0x7f020000,
+    };
+  };
+
+  struct boolean {
+    enum : uint32_t {
+      config_bool = 0x7f030000,
+    };
+  };
+
+  struct id {
+    enum : uint32_t  {
+      hello_view = 0x7f040000,
+    };
+  };
+
+  struct integer {
+    enum : uint32_t {
+      config_integer = 0x7f050000,
+    };
+  };
+
+  struct layout {
+    enum : uint32_t  {
+      hello_view = 0x7f060000,
     };
   };
 };
diff --git a/libs/androidfw/tests/data/overlayable/build b/libs/androidfw/tests/data/overlayable/build
index 98fdc51..0aa97d6 100755
--- a/libs/androidfw/tests/data/overlayable/build
+++ b/libs/androidfw/tests/data/overlayable/build
@@ -17,6 +17,9 @@
 
 set -e
 
+FRAMEWORK_RES_APK=${ANDROID_PRODUCT_OUT}/system/framework/framework-res.apk
+
 aapt2 compile --dir res -o compiled.flata
-aapt2 link --manifest AndroidManifest.xml -o overlayable.apk compiled.flata
+aapt2 link -I $FRAMEWORK_RES_APK --manifest AndroidManifest.xml -o overlayable.apk compiled.flata \
+    --no-auto-version
 rm compiled.flata
diff --git a/libs/androidfw/tests/data/overlayable/overlayable.apk b/libs/androidfw/tests/data/overlayable/overlayable.apk
index 047e6af..9dc9c15 100644
--- a/libs/androidfw/tests/data/overlayable/overlayable.apk
+++ b/libs/androidfw/tests/data/overlayable/overlayable.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/overlayable/res/layout/hello_view.xml b/libs/androidfw/tests/data/overlayable/res/layout/hello_view.xml
new file mode 100644
index 0000000..268118a
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/res/layout/hello_view.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/hello_view"
+    android:text="None"
+    app:max_lines="0"/>
\ No newline at end of file
diff --git a/libs/androidfw/tests/data/overlayable/res/values/overlayable.xml b/libs/androidfw/tests/data/overlayable/res/values/overlayable.xml
index fcdbe94..b3e8f7d 100644
--- a/libs/androidfw/tests/data/overlayable/res/values/overlayable.xml
+++ b/libs/androidfw/tests/data/overlayable/res/values/overlayable.xml
@@ -15,27 +15,41 @@
 -->
 
 <resources>
-<overlayable name="OverlayableResources1" actor="overlay://theme">
-    <!-- Any overlay can overlay the value of @string/overlayable1 -->
-    <item type="string" name="overlayable1" />
+    <overlayable name="OverlayableResources1" actor="overlay://theme">
+        <!-- Any overlay on the product or system partition can overlay the value of
+            @string/overlayable2 -->
+        <policy type="product|system">
+            <item type="string" name="overlayable2" />
+        </policy>
 
-    <!-- Any overlay on the product or system partition can overlay the value of
-        @string/overlayable2 -->
-    <policy type="product|system">
-        <item type="string" name="overlayable2" />
-    </policy>
+        <!-- Any overlay can overlay the value of @string/overlayable4 -->
+        <policy type="public">
+            <item type="string" name="overlayable1" />
+            <item type="string" name="overlayable4" />
+        </policy>
+    </overlayable>
 
-    <!-- Any overlay can overlay the value of @string/overlayable4 -->
-    <policy type="public">
-        <item type="string" name="overlayable4" />
-    </policy>
-</overlayable>
+    <overlayable name="OverlayableResources2" actor="overlay://com.android.overlayable">
+        <!-- Any overlay on the vendor or product partition can overlay the value of
+            @string/overlayable3 -->
+        <policy type="vendor|product">
+            <item type="string" name="overlayable3" />
+        </policy>
+    </overlayable>
 
-<overlayable name="OverlayableResources2" actor="overlay://com.android.overlayable">
-    <!-- Any overlay on the vendor or product partition can overlay the value of
-        @string/overlayable3 -->
-    <policy type="vendor|product">
-        <item type="string" name="overlayable3" />
-    </policy>
-</overlayable>
+    <overlayable name="OverlayableResources3">
+        <policy type="public">
+            <item type="string" name="overlayable5" />
+            <item type="string" name="overlayable6" />
+            <item type="string" name="overlayable7" />
+            <item type="string" name="overlayable8" />
+            <item type="string" name="overlayable9" />
+            <item type="string" name="overlayable10" />
+            <item type="string" name="overlayable11" />
+            <item type="integer" name="config_int" />
+            <item type="id" name="hello_view" />
+            <item type="attr" name="max_lines" />
+            <item type="layout" name="hello_view" />
+        </policy>
+    </overlayable>
 </resources>
\ No newline at end of file
diff --git a/libs/androidfw/tests/data/overlayable/res/values/public.xml b/libs/androidfw/tests/data/overlayable/res/values/public.xml
index 5676d7c..042a311 100644
--- a/libs/androidfw/tests/data/overlayable/res/values/public.xml
+++ b/libs/androidfw/tests/data/overlayable/res/values/public.xml
@@ -20,4 +20,21 @@
     <public type="string" name="overlayable2" id="0x7f010002" />
     <public type="string" name="overlayable3" id="0x7f010003" />
     <public type="string" name="overlayable4" id="0x7f010004" />
+    <public type="string" name="overlayable5" id="0x7f010005" />
+    <public type="string" name="overlayable6" id="0x7f010006" />
+    <public type="string" name="overlayable7" id="0x7f010007" />
+    <public type="string" name="overlayable8" id="0x7f010008" />
+    <public type="string" name="overlayable9" id="0x7f010009" />
+    <public type="string" name="overlayable10" id="0x7f01000a" />
+    <public type="string" name="overlayable11" id="0x7f01000b" />
+
+    <public type="attr" name="max_lines" id="0x7f020000" />
+
+    <public type="bool" name="config_bool" id="0x7f030000" />
+
+    <public type="id" name="hello_view" id="0x7f040000" />
+
+    <public type="integer" name="config_int" id="0x7f050000" />
+
+    <public type="layout" name="hello_view" id="0x7f060000" />
 </resources>
\ No newline at end of file
diff --git a/libs/androidfw/tests/data/overlayable/res/values/values.xml b/libs/androidfw/tests/data/overlayable/res/values/values.xml
index a86b312..235772d 100644
--- a/libs/androidfw/tests/data/overlayable/res/values/values.xml
+++ b/libs/androidfw/tests/data/overlayable/res/values/values.xml
@@ -20,4 +20,15 @@
     <string name="overlayable2">Overlayable Two</string>
     <string name="overlayable3">Overlayable Three</string>
     <string name="overlayable4">Overlayable Four</string>
+    <string name="overlayable5">Overlayable Five</string>
+    <string name="overlayable6">Overlayable Six</string>
+    <string name="overlayable7">Overlayable Seven</string>
+    <string name="overlayable8">Overlayable Eight</string>
+    <string name="overlayable9">Overlayable Nine</string>
+    <string name="overlayable10">Overlayable Ten</string>
+    <string name="overlayable11">Overlayable Eleven</string>
+
+    <integer name="config_int">0</integer>
+    <bool name="config_bool">false</bool>
+    <attr name="max_lines" format="integer" />
 </resources>
diff --git a/libs/androidfw/tests/data/system/R.h b/libs/androidfw/tests/data/system/R.h
index 3741074..c0160c0 100644
--- a/libs/androidfw/tests/data/system/R.h
+++ b/libs/androidfw/tests/data/system/R.h
@@ -43,7 +43,8 @@
 
   struct string {
     enum : uint32_t {
-      cancel = 0x01040000,
+      no = 0x01040009,
+      yes = 0x01040013,
     };
   };
 };
diff --git a/libs/androidfw/tests/data/system/res/values/public.xml b/libs/androidfw/tests/data/system/res/values/public.xml
new file mode 100644
index 0000000..077874d
--- /dev/null
+++ b/libs/androidfw/tests/data/system/res/values/public.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <public type="string" name="no" id="0x01040009" />
+    <public type="string" name="yes" id="0x01040013" />
+</resources>
\ No newline at end of file
diff --git a/libs/androidfw/tests/data/system/res/values/values.xml b/libs/androidfw/tests/data/system/res/values/values.xml
new file mode 100644
index 0000000..0629c1d1
--- /dev/null
+++ b/libs/androidfw/tests/data/system/res/values/values.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="yes">yes</string>
+    <string name="no">no</string>
+</resources>
\ No newline at end of file
diff --git a/libs/androidfw/tests/data/system/system.apk b/libs/androidfw/tests/data/system/system.apk
index 9045d6c..1f7e007 100644
--- a/libs/androidfw/tests/data/system/system.apk
+++ b/libs/androidfw/tests/data/system/system.apk
Binary files differ