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";
&& 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);
}
}
}
DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles =
baseGroup->getFiles();
for (size_t i=0; i < baseFiles.size(); i++) {
- printf("baseFile %d has flavor %s\n", i,
+ printf("baseFile %ld has flavor %s\n", i,
baseFiles.keyAt(i).toString().string());
}
for (size_t i=0; i < overlayFiles.size(); i++) {
- printf("overlayFile %d has flavor %s\n", i,
+ printf("overlayFile %ld has flavor %s\n", i,
overlayFiles.keyAt(i).toString().string());
}
}
keyAt(overlayGroupIndex));
if(baseFileIndex < UNKNOWN_ERROR) {
if (bundle->getVerbose()) {
- printf("found a match (%d) for overlay file %s, for flavor %s\n",
+ printf("found a match (%ld) for overlay file %s, for flavor %s\n",
baseFileIndex,
overlayGroup->getLeaf().string(),
overlayFiles.keyAt(overlayGroupIndex).toString().string());
node->addAttribute(ns, attr, String16(value));
}
+static void fullyQualifyClassName(const String8& package, sp<XMLNode> node,
+ const String16& attrName) {
+ XMLNode::attribute_entry* attr = node->editAttribute(
+ String16("http://schemas.android.com/apk/res/android"), attrName);
+ if (attr != NULL) {
+ String8 name(attr->string);
+
+ // asdf --> package.asdf
+ // .asdf .a.b --> package.asdf package.a.b
+ // asdf.adsf --> asdf.asdf
+ String8 className;
+ const char* p = name.string();
+ const char* q = strchr(p, '.');
+ if (p == q) {
+ className += package;
+ className += name;
+ } else if (q == NULL) {
+ className += package;
+ className += ".";
+ className += name;
+ } else {
+ className += name;
+ }
+ NOISY(printf("Qualifying class '%s' to '%s'", name.string(), className.string()));
+ attr->string.setTo(String16(className));
+ }
+}
+
status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
{
root = root->searchElement(String16(), String16("manifest"));
addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion",
bundle->getMaxSdkVersion());
}
+
+ // Deal with manifest package name overrides
+ const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();
+ if (manifestPackageNameOverride != NULL) {
+ // Update the actual package name
+ XMLNode::attribute_entry* attr = root->editAttribute(String16(), String16("package"));
+ if (attr == NULL) {
+ fprintf(stderr, "package name is required with --rename-manifest-package.\n");
+ return UNKNOWN_ERROR;
+ }
+ String8 origPackage(attr->string);
+ attr->string.setTo(String16(manifestPackageNameOverride));
+ NOISY(printf("Overriding package '%s' to be '%s'\n", origPackage.string(), manifestPackageNameOverride));
+
+ // Make class names fully qualified
+ sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
+ if (application != NULL) {
+ fullyQualifyClassName(origPackage, application, String16("name"));
+
+ Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren());
+ for (size_t i = 0; i < children.size(); i++) {
+ sp<XMLNode> child = children.editItemAt(i);
+ String8 tag(child->getElementName());
+ if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") {
+ 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<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(root->getChildren());
+ for (size_t i = 0; i < children.size(); i++) {
+ sp<XMLNode> 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;
}
table.writePublicDefinitions(String16(assets->getPackage()), fp);
fclose(fp);
}
-
+#if 0
NOISY(
ResTable rt;
rt.add(resFile->getData(), resFile->getSize(), NULL);
printf("Generated resources:\n");
rt.print();
)
-
+#endif
// These resources are now considered to be a part of the included
// resources, for others to reference.
err = assets->addIncludedResources(resFile);
depth++;
String8 tag(tree.getElementName(&len));
// printf("Depth %d tag %s\n", depth, tag.string());
+ bool keepTag = false;
if (depth == 1) {
if (tag != "manifest") {
fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n");
return -1;
}
pkg = getAttribute(tree, NULL, "package", NULL);
- } else if (depth == 2 && tag == "application") {
- inApplication = true;
- }
- if (inApplication) {
- if (tag == "application" || tag == "activity" || tag == "service" || tag == "receiver"
- || tag == "provider") {
- String8 name = getAttribute(tree, "http://schemas.android.com/apk/res/android",
- "name", &error);
- if (error != "") {
- fprintf(stderr, "ERROR: %s\n", error.string());
- return -1;
+ } else if (depth == 2) {
+ if (tag == "application") {
+ inApplication = true;
+ keepTag = true;
+ } else if (tag == "instrumentation") {
+ keepTag = true;
+ }
+ }
+ if (!keepTag && inApplication && depth == 3) {
+ if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") {
+ keepTag = true;
+ }
+ }
+ if (keepTag) {
+ String8 name = getAttribute(tree, "http://schemas.android.com/apk/res/android",
+ "name", &error);
+ if (error != "") {
+ fprintf(stderr, "ERROR: %s\n", error.string());
+ return -1;
+ }
+ if (name.length() > 0) {
+ // asdf --> package.asdf
+ // .asdf .a.b --> package.asdf package.a.b
+ // asdf.adsf --> asdf.asdf
+ String8 rule("-keep class ");
+ const char* p = name.string();
+ const char* q = strchr(p, '.');
+ if (p == q) {
+ rule += pkg;
+ rule += name;
+ } else if (q == NULL) {
+ rule += pkg;
+ rule += ".";
+ rule += name;
+ } else {
+ rule += name;
}
- if (name.length() > 0) {
- // asdf --> package.asdf
- // .asdf .a.b --> package.asdf package.a.b
- // asdf.adsf --> asdf.asdf
- String8 rule("-keep class ");
- const char* p = name.string();
- const char* q = strchr(p, '.');
- if (p == q) {
- rule += pkg;
- rule += name;
- } else if (q == NULL) {
- rule += pkg;
- rule += ".";
- rule += name;
- } else {
- rule += name;
- }
- String8 location = tag;
- location += " ";
- location += assFile->getSourceFile();
- char lineno[20];
- sprintf(lineno, ":%d", tree.getLineNumber());
- location += lineno;
+ String8 location = tag;
+ location += " ";
+ location += assFile->getSourceFile();
+ char lineno[20];
+ sprintf(lineno, ":%d", tree.getLineNumber());
+ location += lineno;
- keep->add(rule, location);
- }
+ keep->add(rule, location);
}
}
}
writeProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
{
status_t err;
- sp<AaptDir> layout = assets->resDir(String8("layout"));
+ const Vector<sp<AaptDir> >& dirs = assets->resDirs();
+ const size_t K = dirs.size();
+ for (size_t k=0; k<K; k++) {
+ const sp<AaptDir>& d = dirs.itemAt(k);
+ const String8& dirName = d->getLeaf();
+ if ((dirName != String8("layout")) && (strncmp(dirName.string(), "layout-", 7) != 0)) {
+ continue;
+ }
- if (layout != NULL) {
- const KeyedVector<String8,sp<AaptGroup> > groups = layout->getFiles();
+ const KeyedVector<String8,sp<AaptGroup> > groups = d->getFiles();
const size_t N = groups.size();
for (size_t i=0; i<N; i++) {
const sp<AaptGroup>& group = groups.valueAt(i);