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
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace R {
|
||||
namespace attr {
|
||||
enum {
|
||||
attr1 = 0x02010000, // default
|
||||
attr2 = 0x02010001, // default
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user