Skip to content

Commit f7243dc

Browse files
author
Xavier Ducrohet
committed
Add --error-on-failed-insert option to aapt. do not merge.
The new SDK build system give the ability to insert versionCode/Name and min/targetSdkVersion in the manifest but aapt won't replace those if they already exist. The main problem is that aapt doesn't actually fail when it doesn't replace them, making the output not what the developer wanted. This patch set adds an option to aapt to make it return an error if the insert failed because the attribute already existed. Cherry-pick from 7714a24 Change-Id: I8938ec1238da407a8562c974e9598db39001ffd9
1 parent d8104d9 commit f7243dc

File tree

3 files changed

+60
-19
lines changed

3 files changed

+60
-19
lines changed

tools/aapt/Bundle.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class Bundle {
6262
mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
6363
mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL),
6464
mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL),
65-
mUseCrunchCache(false), mOutputTextSymbols(NULL),
65+
mUseCrunchCache(false), mErrorOnFailedInsert(false), mOutputTextSymbols(NULL),
6666
mArgc(0), mArgv(NULL)
6767
{}
6868
~Bundle(void) {}
@@ -114,6 +114,8 @@ class Bundle {
114114
void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }
115115
bool getGenDependencies() { return mGenDependencies; }
116116
void setGenDependencies(bool val) { mGenDependencies = val; }
117+
bool getErrorOnFailedInsert() { return mErrorOnFailedInsert; }
118+
void setErrorOnFailedInsert(bool val) { mErrorOnFailedInsert = val; }
117119

118120
bool getUTF16StringsOption() {
119121
return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);
@@ -283,6 +285,7 @@ class Bundle {
283285
bool mNonConstantId;
284286
const char* mProduct;
285287
bool mUseCrunchCache;
288+
bool mErrorOnFailedInsert;
286289
const char* mOutputTextSymbols;
287290

288291
/* file specification */

tools/aapt/Main.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ void usage(void)
180180
" Make the resources ID non constant. This is required to make an R java class\n"
181181
" that does not contain the final value but is used to make reusable compiled\n"
182182
" libraries that need to access resources.\n"
183+
" --error-on-failed-insert\n"
184+
" Forces aapt to return an error if it fails to insert values into the manifest\n"
185+
" with --debug-mode, --min-sdk-version, --target-sdk-version --version-code\n"
186+
" and --version-name.\n"
187+
" Insertion typically fails if the manifest already defines the attribute.\n"
183188
" --output-text-symbols\n"
184189
" Generates a text file containing the resource symbols of the R class in the\n"
185190
" specified folder.\n"
@@ -551,6 +556,8 @@ int main(int argc, char* const argv[])
551556
bundle.setInstrumentationPackageNameOverride(argv[0]);
552557
} else if (strcmp(cp, "-auto-add-overlay") == 0) {
553558
bundle.setAutoAddOverlay(true);
559+
} else if (strcmp(cp, "-error-on-failed-insert") == 0) {
560+
bundle.setErrorOnFailedInsert(true);
554561
} else if (strcmp(cp, "-output-text-symbols") == 0) {
555562
argc--;
556563
argv++;

tools/aapt/Resource.cpp

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -673,24 +673,40 @@ static bool applyFileOverlay(Bundle *bundle,
673673
return true;
674674
}
675675

676-
void addTagAttribute(const sp<XMLNode>& node, const char* ns8,
677-
const char* attr8, const char* value)
676+
/*
677+
* Inserts an attribute in a given node, only if the attribute does not
678+
* exist.
679+
* If errorOnFailedInsert is true, and the attribute already exists, returns false.
680+
* Returns true otherwise, even if the attribute already exists.
681+
*/
682+
bool addTagAttribute(const sp<XMLNode>& node, const char* ns8,
683+
const char* attr8, const char* value, bool errorOnFailedInsert)
678684
{
679685
if (value == NULL) {
680-
return;
686+
return true;
681687
}
682-
688+
683689
const String16 ns(ns8);
684690
const String16 attr(attr8);
685-
691+
686692
if (node->getAttribute(ns, attr) != NULL) {
693+
if (errorOnFailedInsert) {
694+
fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);"
695+
" cannot insert new value %s.\n",
696+
String8(attr).string(), String8(ns).string(), value);
697+
return false;
698+
}
699+
687700
fprintf(stderr, "Warning: AndroidManifest.xml already defines %s (in %s);"
688701
" using existing value in manifest.\n",
689702
String8(attr).string(), String8(ns).string());
690-
return;
703+
704+
// don't stop the build.
705+
return true;
691706
}
692707

693708
node->addAttribute(ns, attr, String16(value));
709+
return true;
694710
}
695711

696712
static void fullyQualifyClassName(const String8& package, sp<XMLNode> node,
@@ -728,11 +744,17 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
728744
fprintf(stderr, "No <manifest> tag.\n");
729745
return UNKNOWN_ERROR;
730746
}
731-
732-
addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode",
733-
bundle->getVersionCode());
734-
addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
735-
bundle->getVersionName());
747+
748+
bool errorOnFailedInsert = bundle->getErrorOnFailedInsert();
749+
750+
if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode",
751+
bundle->getVersionCode(), errorOnFailedInsert)) {
752+
return UNKNOWN_ERROR;
753+
}
754+
if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
755+
bundle->getVersionName(), errorOnFailedInsert)) {
756+
return UNKNOWN_ERROR;
757+
}
736758

737759
if (bundle->getMinSdkVersion() != NULL
738760
|| bundle->getTargetSdkVersion() != NULL
@@ -743,18 +765,27 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
743765
root->insertChildAt(vers, 0);
744766
}
745767

746-
addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion",
747-
bundle->getMinSdkVersion());
748-
addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "targetSdkVersion",
749-
bundle->getTargetSdkVersion());
750-
addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion",
751-
bundle->getMaxSdkVersion());
768+
if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion",
769+
bundle->getMinSdkVersion(), errorOnFailedInsert)) {
770+
return UNKNOWN_ERROR;
771+
}
772+
if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "targetSdkVersion",
773+
bundle->getTargetSdkVersion(), errorOnFailedInsert)) {
774+
return UNKNOWN_ERROR;
775+
}
776+
if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion",
777+
bundle->getMaxSdkVersion(), errorOnFailedInsert)) {
778+
return UNKNOWN_ERROR;
779+
}
752780
}
753781

754782
if (bundle->getDebugMode()) {
755783
sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
756784
if (application != NULL) {
757-
addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true");
785+
if (!addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true",
786+
errorOnFailedInsert)) {
787+
return UNKNOWN_ERROR;
788+
}
758789
}
759790
}
760791

0 commit comments

Comments
 (0)