X-Git-Url: https://git.saurik.com/android/aapt.git/blobdiff_plain/59302c96c6ad1258529cdf052d4a4a71d474e85d..9f1b920f0ba1eac153da266ec8c6f564f56df591:/Resource.cpp diff --git a/Resource.cpp b/Resource.cpp index 0d2ea60..9fcb21c 100644 --- a/Resource.cpp +++ b/Resource.cpp @@ -101,13 +101,13 @@ public: String8 leaf(group->getLeaf()); mLeafName = String8(leaf); mParams = file->getGroupEntry().toParams(); - NOISY(printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d density=%d touch=%d key=%d inp=%d nav=%d\n", + NOISY(printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\n", group->getPath().string(), mParams.mcc, mParams.mnc, mParams.language[0] ? mParams.language[0] : '-', mParams.language[1] ? mParams.language[1] : '-', mParams.country[0] ? mParams.country[0] : '-', mParams.country[1] ? mParams.country[1] : '-', - mParams.orientation, + mParams.orientation, mParams.uiMode, mParams.density, mParams.touchscreen, mParams.keyboard, mParams.inputFlags, mParams.navigation)); mPath = "res"; @@ -221,12 +221,12 @@ static status_t parsePackage(Bundle* bundle, const sp& assets, && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::START_TAG) { if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) { - ssize_t minSdkIndex = block.indexOfAttribute("android", + ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "minSdkVersion"); if (minSdkIndex >= 0) { - String8 minSdkString = String8( - block.getAttributeStringValue(minSdkIndex, &len)); - bundle->setMinSdkVersion(minSdkString.string()); + const uint16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len); + const char* minSdk8 = strdup(String8(minSdk16).string()); + bundle->setMinSdkVersion(minSdk8); } } } @@ -562,9 +562,10 @@ void addTagAttribute(const sp& node, const char* ns8, node->addAttribute(ns, attr, String16(value)); } -static void fullyQualifyClassName(String8& package, sp node) { +static void fullyQualifyClassName(const String8& package, sp node, + const String16& attrName) { XMLNode::attribute_entry* attr = node->editAttribute( - String16("http://schemas.android.com/apk/res/android"), String16("name")); + String16("http://schemas.android.com/apk/res/android"), attrName); if (attr != NULL) { String8 name(attr->string); @@ -635,19 +636,40 @@ status_t massageManifest(Bundle* bundle, sp root) // Make class names fully qualified sp application = root->getChildElement(String16(), String16("application")); if (application != NULL) { - fullyQualifyClassName(origPackage, application); + fullyQualifyClassName(origPackage, application, String16("name")); Vector >& children = const_cast >&>(application->getChildren()); for (size_t i = 0; i < children.size(); i++) { sp child = children.editItemAt(i); String8 tag(child->getElementName()); if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") { - fullyQualifyClassName(origPackage, child); + fullyQualifyClassName(origPackage, child, String16("name")); + } else if (tag == "activity-alias") { + fullyQualifyClassName(origPackage, child, String16("name")); + fullyQualifyClassName(origPackage, child, String16("targetActivity")); } } } } + // Deal with manifest package name overrides + const char* instrumentationPackageNameOverride = bundle->getInstrumentationPackageNameOverride(); + if (instrumentationPackageNameOverride != NULL) { + // Fix up instrumentation targets. + Vector >& children = const_cast >&>(root->getChildren()); + for (size_t i = 0; i < children.size(); i++) { + sp child = children.editItemAt(i); + String8 tag(child->getElementName()); + if (tag == "instrumentation") { + XMLNode::attribute_entry* attr = child->editAttribute( + String16("http://schemas.android.com/apk/res/android"), String16("targetPackage")); + if (attr != NULL) { + attr->string.setTo(String16(instrumentationPackageNameOverride)); + } + } + } + } + return NO_ERROR; } @@ -1866,8 +1888,26 @@ writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp& ass return NO_ERROR; } +void +addProguardKeepRule(ProguardKeepSet* keep, const String8& className, + const String8& srcName, int line) +{ + String8 rule("-keep class "); + rule += className; + rule += " { (...); }"; + + String8 location("view "); + location += srcName; + char lineno[20]; + sprintf(lineno, ":%d", line); + location += lineno; + + keep->add(rule, location); +} + status_t -writeProguardForLayout(ProguardKeepSet* keep, const sp& layoutFile) +writeProguardForXml(ProguardKeepSet* keep, const sp& layoutFile, + const char* startTag, const char* altTag) { status_t err; ResXMLTree tree; @@ -1881,6 +1921,23 @@ writeProguardForLayout(ProguardKeepSet* keep, const sp& layoutFile) tree.restart(); + if (startTag != NULL) { + bool haveStart = false; + while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { + if (code != ResXMLTree::START_TAG) { + continue; + } + String8 tag(tree.getElementName(&len)); + if (tag == startTag) { + haveStart = true; + } + break; + } + if (!haveStart) { + return NO_ERROR; + } + } + while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code != ResXMLTree::START_TAG) { continue; @@ -1889,17 +1946,19 @@ writeProguardForLayout(ProguardKeepSet* keep, const sp& layoutFile) // If there is no '.', we'll assume that it's one of the built in names. if (strchr(tag.string(), '.')) { - String8 rule("-keep class "); - rule += tag; - rule += " { (...); }"; - - String8 location("view "); - location += layoutFile->getSourceFile(); - char lineno[20]; - sprintf(lineno, ":%d", tree.getLineNumber()); - location += lineno; - - keep->add(rule, location); + addProguardKeepRule(keep, tag, + layoutFile->getPrintableSource(), tree.getLineNumber()); + } else if (altTag != NULL && tag == altTag) { + ssize_t classIndex = tree.indexOfAttribute(NULL, "class"); + if (classIndex < 0) { + fprintf(stderr, "%s:%d: does not have class attribute.\n", + layoutFile->getPrintableSource().string(), tree.getLineNumber()); + } else { + size_t len; + addProguardKeepRule(keep, + String8(tree.getAttributeStringValue(classIndex, &len)), + layoutFile->getPrintableSource(), tree.getLineNumber()); + } } } @@ -1915,10 +1974,16 @@ writeProguardForLayouts(ProguardKeepSet* keep, const sp& assets) for (size_t k=0; k& d = dirs.itemAt(k); const String8& dirName = d->getLeaf(); - if ((dirName != String8("layout")) && (strncmp(dirName.string(), "layout-", 7) != 0)) { + const char* startTag = NULL; + const char* altTag = NULL; + if ((dirName == String8("layout")) || (strncmp(dirName.string(), "layout-", 7) == 0)) { + altTag = "view"; + } else if ((dirName == String8("xml")) || (strncmp(dirName.string(), "xml-", 4) == 0)) { + startTag = "PreferenceScreen"; + } else { continue; } - + const KeyedVector > groups = d->getFiles(); const size_t N = groups.size(); for (size_t i=0; i& assets) const DefaultKeyedVector >& files = group->getFiles(); const size_t M = files.size(); for (size_t j=0; j