diff options
| author | 2016-05-10 10:01:12 -0700 | |
|---|---|---|
| committer | 2016-05-10 10:45:52 -0700 | |
| commit | 8ac51d14b614ba6a12df2ba90d50a01f50d548aa (patch) | |
| tree | b2afded5a45d6c5d14569b6691354d1613c1eb81 | |
| parent | b42afe9be02b23c50c0479e93df2a853be7c369a (diff) | |
Resource shared libraries: fix theme references
Theme values that would reference other theme values would not work
if they were declared in a shared library.
We now introduce a parallel resource type to TYPE_DYNAMIC_REFERENCE,
TYPE_DYNAMIC_ATTRIBUTE, which allows us to lookup and resolve
theme value references from shared libraries.
Bug:28687378
Change-Id: I4f2364e3e8b567679f90784fcaaea12b6b05e926
| -rw-r--r-- | include/androidfw/ResourceTypes.h | 3 | ||||
| -rw-r--r-- | libs/androidfw/ResourceTypes.cpp | 58 | ||||
| -rw-r--r-- | libs/androidfw/tests/ResTable_test.cpp | 5 | ||||
| -rw-r--r-- | libs/androidfw/tests/data/lib/R.h | 1 | ||||
| -rw-r--r-- | libs/androidfw/tests/data/lib/lib_arsc.h | 47 | ||||
| -rw-r--r-- | libs/androidfw/tests/data/lib/res/values/values.xml | 2 |
6 files changed, 79 insertions, 37 deletions
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h index 05596f0f7986..cf4ff8201b8c 100644 --- a/include/androidfw/ResourceTypes.h +++ b/include/androidfw/ResourceTypes.h @@ -289,6 +289,9 @@ struct Res_value // The 'data' holds a dynamic ResTable_ref, which needs to be // resolved before it can be used like a TYPE_REFERENCE. TYPE_DYNAMIC_REFERENCE = 0x07, + // The 'data' holds an attribute resource identifier, which needs to be resolved + // before it can be used like a TYPE_ATTRIBUTE. + TYPE_DYNAMIC_ATTRIBUTE = 0x08, // Beginning of integer flavors... TYPE_FIRST_INT = 0x10, diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index c3dfb89180de..36b1f4b664c2 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -5348,16 +5348,17 @@ bool ResTable::stringToValue(Res_value* outValue, String16* outString, return false; } } - if (!accessor) { - outValue->data = rid; - return true; + + if (accessor) { + rid = Res_MAKEID( + accessor->getRemappedPackage(Res_GETPACKAGE(rid)), + Res_GETTYPE(rid), Res_GETENTRY(rid)); + } + + uint32_t packageId = Res_GETPACKAGE(rid) + 1; + if (packageId != APP_PACKAGE_ID && packageId != SYS_PACKAGE_ID) { + outValue->dataType = Res_value::TYPE_DYNAMIC_ATTRIBUTE; } - rid = Res_MAKEID( - accessor->getRemappedPackage(Res_GETPACKAGE(rid)), - Res_GETTYPE(rid), Res_GETENTRY(rid)); - //printf("Incl %s:%s/%s: 0x%08x\n", - // String8(package).string(), String8(type).string(), - // String8(name).string(), rid); outValue->data = rid; return true; } @@ -5365,11 +5366,17 @@ bool ResTable::stringToValue(Res_value* outValue, String16* outString, if (accessor) { uint32_t rid = accessor->getCustomResource(package, type, name); if (rid != 0) { - //printf("Mine %s:%s/%s: 0x%08x\n", - // String8(package).string(), String8(type).string(), - // String8(name).string(), rid); - outValue->data = rid; - return true; + uint32_t packageId = Res_GETPACKAGE(rid) + 1; + if (packageId == 0x00) { + outValue->data = rid; + outValue->dataType = Res_value::TYPE_DYNAMIC_ATTRIBUTE; + return true; + } else if (packageId == APP_PACKAGE_ID || packageId == SYS_PACKAGE_ID) { + // We accept packageId's generated as 0x01 in order to support + // building the android system resources + outValue->data = rid; + return true; + } } } @@ -6526,10 +6533,25 @@ status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const { } status_t DynamicRefTable::lookupResourceValue(Res_value* value) const { - if (value->dataType != Res_value::TYPE_DYNAMIC_REFERENCE && - (value->dataType != Res_value::TYPE_REFERENCE || !mAppAsLib)) { + uint8_t resolvedType = Res_value::TYPE_REFERENCE; + switch (value->dataType) { + case Res_value::TYPE_ATTRIBUTE: + resolvedType = Res_value::TYPE_ATTRIBUTE; + // fallthrough + case Res_value::TYPE_REFERENCE: + if (!mAppAsLib) { + return NO_ERROR; + } + // If the package is loaded as shared library, the resource reference // also need to be fixed. + break; + case Res_value::TYPE_DYNAMIC_ATTRIBUTE: + resolvedType = Res_value::TYPE_ATTRIBUTE; + // fallthrough + case Res_value::TYPE_DYNAMIC_REFERENCE: + break; + default: return NO_ERROR; } @@ -6538,7 +6560,7 @@ status_t DynamicRefTable::lookupResourceValue(Res_value* value) const { return err; } - value->dataType = Res_value::TYPE_REFERENCE; + value->dataType = resolvedType; return NO_ERROR; } @@ -6816,6 +6838,8 @@ void ResTable::print_value(const Package* pkg, const Res_value& value) const printf("(dynamic reference) 0x%08x\n", value.data); } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) { printf("(attribute) 0x%08x\n", value.data); + } else if (value.dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE) { + printf("(dynamic attribute) 0x%08x\n", value.data); } else if (value.dataType == Res_value::TYPE_STRING) { size_t len; const char* str8 = pkg->header->values.string8At( diff --git a/libs/androidfw/tests/ResTable_test.cpp b/libs/androidfw/tests/ResTable_test.cpp index b8b46259f0d1..9e53dd279195 100644 --- a/libs/androidfw/tests/ResTable_test.cpp +++ b/libs/androidfw/tests/ResTable_test.cpp @@ -131,6 +131,11 @@ TEST(ResTableTest, libraryThemeIsAppliedCorrectly) { ASSERT_GE(index, 0); ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); ASSERT_EQ(uint32_t(700), val.data); + + index = theme.getAttribute(lib::R::attr::attr2, &val, &specFlags); + ASSERT_GE(index, 0); + ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); + ASSERT_EQ(uint32_t(700), val.data); } TEST(ResTableTest, referenceToBagIsNotResolved) { diff --git a/libs/androidfw/tests/data/lib/R.h b/libs/androidfw/tests/data/lib/R.h index ff311208d61a..6013973072cc 100644 --- a/libs/androidfw/tests/data/lib/R.h +++ b/libs/androidfw/tests/data/lib/R.h @@ -23,6 +23,7 @@ namespace R { namespace attr { enum { attr1 = 0x02010000, // default + attr2 = 0x02010001, // default }; } diff --git a/libs/androidfw/tests/data/lib/lib_arsc.h b/libs/androidfw/tests/data/lib/lib_arsc.h index dd3dad5d5f3d..62bed655f914 100644 --- a/libs/androidfw/tests/data/lib/lib_arsc.h +++ b/libs/androidfw/tests/data/lib/lib_arsc.h @@ -1,8 +1,8 @@ unsigned char lib_arsc[] = { - 0x02, 0x00, 0x0c, 0x00, 0xb8, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x0c, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x90, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xe4, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, @@ -25,37 +25,44 @@ unsigned char lib_arsc[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, - 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, - 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, - 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, - 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x31, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x05, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, + 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, + 0x8c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x54, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00, - 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, - 0x64, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x4c, 0x00, 0x78, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x10, 0xbc, 0x02, 0x00, 0x00 + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x10, 0xbc, 0x02, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00 }; -unsigned int lib_arsc_len = 696; +unsigned int lib_arsc_len = 780; diff --git a/libs/androidfw/tests/data/lib/res/values/values.xml b/libs/androidfw/tests/data/lib/res/values/values.xml index 3ec79b1c7663..ec8117a78c56 100644 --- a/libs/androidfw/tests/data/lib/res/values/values.xml +++ b/libs/androidfw/tests/data/lib/res/values/values.xml @@ -16,8 +16,10 @@ <resources> <attr name="attr1" format="integer" /> + <attr name="attr2" format="integer" /> <style name="Theme"> <item name="com.android.test.basic:attr1">700</item> + <item name="com.android.test.basic:attr2">?com.android.test.basic:attr1</item> </style> </resources> |