summaryrefslogtreecommitdiff
path: root/tools/aapt/Resource.cpp
diff options
context:
space:
mode:
author Adam Lesinski <adamlesinski@google.com> 2014-09-17 18:34:15 -0700
committer Adam Lesinski <adamlesinski@google.com> 2014-09-18 14:05:24 -0700
commit82a2dd8efe48d3a4e04655f01329da857ace4b7d (patch)
tree9c5ec064aeba43cf4b27fd4bb36e31f0bf425f35 /tools/aapt/Resource.cpp
parent49c0e7375b237bc6eff8746ae91466ea6a660233 (diff)
Fix backwards compat problem with AAPT public attrs
AAPT has traditionally assigned resource IDs to public attributes, and then followed those public definitions with private attributes. --- PUBLIC --- | 0x01010234 | attr/color | 0x01010235 | attr/background --- PRIVATE --- | 0x01010236 | attr/secret | 0x01010237 | attr/shhh Each release, when attributes are added, they take the place of the private attributes and the private attributes are shifted down again. --- PUBLIC --- | 0x01010234 | attr/color | 0x01010235 | attr/background | 0x01010236 | attr/shinyNewAttr | 0x01010237 | attr/highlyValuedFeature --- PRIVATE --- | 0x01010238 | attr/secret | 0x01010239 | attr/shhh Platform code may look for private attributes set in a theme. If an app compiled against a newer version of the platform uses a new public attribute that happens to have the same ID as the private attribute the older platform is expecting, then the behavior is undefined. We get around this by detecting any newly defined attributes (in L), copy the resource into a -v21 qualified resource, and delete the attribute from the original resource. This ensures that older platforms don't see the new attribute, but when running on L+ platforms, the attribute will be respected. We still need to address this problem in the platform moving forward, as this will only help us in the transition from pre L to L. Bug:17520380 Change-Id: Ia2a985798b50006c21c7c3431d30d9598f27cd91
Diffstat (limited to 'tools/aapt/Resource.cpp')
-rw-r--r--tools/aapt/Resource.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index afec5edd3f0f..d60520284fa2 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -781,12 +781,18 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) {
return UNKNOWN_ERROR;
+ } else {
+ const XMLNode::attribute_entry* attr = root->getAttribute(
+ String16(RESOURCES_ANDROID_NAMESPACE), String16("versionName"));
+ if (attr != NULL) {
+ bundle->setVersionName(strdup(String8(attr->string).string()));
+ }
}
+ sp<XMLNode> vers = root->getChildElement(String16(), String16("uses-sdk"));
if (bundle->getMinSdkVersion() != NULL
|| bundle->getTargetSdkVersion() != NULL
|| bundle->getMaxSdkVersion() != NULL) {
- sp<XMLNode> vers = root->getChildElement(String16(), String16("uses-sdk"));
if (vers == NULL) {
vers = XMLNode::newElement(root->getFilename(), String16(), String16("uses-sdk"));
root->insertChildAt(vers, 0);
@@ -806,6 +812,14 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
}
}
+ if (vers != NULL) {
+ const XMLNode::attribute_entry* attr = vers->getAttribute(
+ String16(RESOURCES_ANDROID_NAMESPACE), String16("minSdkVersion"));
+ if (attr != NULL) {
+ bundle->setMinSdkVersion(strdup(String8(attr->string).string()));
+ }
+ }
+
if (bundle->getPlatformBuildVersionCode() != "") {
if (!addTagAttribute(root, "", "platformBuildVersionCode",
bundle->getPlatformBuildVersionCode(), errorOnFailedInsert, true)) {
@@ -973,8 +987,8 @@ static ssize_t extractPlatformBuildVersion(ResXMLTree& tree, Bundle* bundle) {
static ssize_t extractPlatformBuildVersion(AssetManager& assets, Bundle* bundle) {
int32_t cookie = getPlatformAssetCookie(assets);
if (cookie == 0) {
- fprintf(stderr, "ERROR: Platform package not found\n");
- return UNKNOWN_ERROR;
+ // No platform was loaded.
+ return NO_ERROR;
}
ResXMLTree tree;
@@ -1500,6 +1514,10 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
return err;
}
+ if (table.modifyForCompat(bundle) != NO_ERROR) {
+ return UNKNOWN_ERROR;
+ }
+
//block.restart();
//printXMLBlock(&block);