AAPT2: Support id reference chaining from AAPT
AAPT would allow for ids to be declared in the form:
<item name="name" type="id>@id/other</item>
@id/name should hold a reference to @id/other. When
getResources().getValue() is called on R.id.name with resolveRefs
enabled, the resuling reference should be R.id.other.
Bug: 69445910
Test: Created tests for correct parsing of id references and correct
resolving of deep references
Change-Id: Id1feb37b2565c213dc6a19b4c401906260d7fc14
diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp
index 3118009..f1cc569 100644
--- a/libs/androidfw/tests/AssetManager2_test.cpp
+++ b/libs/androidfw/tests/AssetManager2_test.cpp
@@ -386,6 +386,38 @@
EXPECT_EQ(basic::R::array::integerArray1, last_ref);
}
+TEST_F(AssetManager2Test, ResolveDeepIdReference) {
+ AssetManager2 assetmanager;
+ assetmanager.SetApkAssets({basic_assets_.get()});
+
+ // Set up the resource ids
+ const uint32_t high_ref = assetmanager
+ .GetResourceId("@id/high_ref", "values", "com.android.basic");
+ ASSERT_NE(high_ref, 0u);
+ const uint32_t middle_ref = assetmanager
+ .GetResourceId("@id/middle_ref", "values", "com.android.basic");
+ ASSERT_NE(middle_ref, 0u);
+ const uint32_t low_ref = assetmanager
+ .GetResourceId("@id/low_ref", "values", "com.android.basic");
+ ASSERT_NE(low_ref, 0u);
+
+ // Retrieve the most shallow resource
+ Res_value value;
+ ResTable_config config;
+ uint32_t flags;
+ ApkAssetsCookie cookie = assetmanager.GetResource(high_ref, false /*may_be_bag*/,
+ 0 /*density_override*/,
+ &value, &config, &flags);
+ ASSERT_NE(kInvalidCookie, cookie);
+ EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
+ EXPECT_EQ(middle_ref, value.data);
+
+ // Check that resolving the reference resolves to the deepest id
+ uint32_t last_ref = high_ref;
+ assetmanager.ResolveReference(cookie, &value, &config, &flags, &last_ref);
+ EXPECT_EQ(last_ref, low_ref);
+}
+
TEST_F(AssetManager2Test, KeepLastReferenceIdUnmodifiedIfNoReferenceIsResolved) {
AssetManager2 assetmanager;
assetmanager.SetApkAssets({basic_assets_.get()});