Skip to content

Commit 7714a24

Browse files
author
Xavier Ducrohet
committed
Add --error-on-failed-insert option to aapt.
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. Change-Id: I8938ec1238da407a8562c974e9598db39001ffd9
1 parent 2415841 commit 7714a24

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
@@ -61,7 +61,7 @@ class Bundle {
6161
mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
6262
mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL),
6363
mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL),
64-
mUseCrunchCache(false), mArgc(0), mArgv(NULL)
64+
mUseCrunchCache(false), mErrorOnFailedInsert(false), mArgc(0), mArgv(NULL)
6565
{}
6666
~Bundle(void) {}
6767

@@ -110,6 +110,8 @@ class Bundle {
110110
void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }
111111
bool getGenDependencies() { return mGenDependencies; }
112112
void setGenDependencies(bool val) { mGenDependencies = val; }
113+
bool getErrorOnFailedInsert() { return mErrorOnFailedInsert; }
114+
void setErrorOnFailedInsert(bool val) { mErrorOnFailedInsert = val; }
113115

114116
bool getUTF16StringsOption() {
115117
return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);
@@ -276,6 +278,7 @@ class Bundle {
276278
bool mNonConstantId;
277279
const char* mProduct;
278280
bool mUseCrunchCache;
281+
bool mErrorOnFailedInsert;
279282

280283
/* file specification */
281284
int mArgc;

tools/aapt/Main.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ void usage(void)
177177
" Make the resources ID non constant. This is required to make an R java class\n"
178178
" that does not contain the final value but is used to make reusable compiled\n"
179179
" libraries that need to access resources.\n"
180+
" --error-on-failed-insert\n"
181+
" Forces aapt to return an error if it fails to insert values into the manifest\n"
182+
" with --debug-mode, --min-sdk-version, --target-sdk-version --version-code\n"
183+
" and --version-name.\n"
184+
" Insertion typically fails if the manifest already defines the attribute.\n"
180185
" --ignore-assets\n"
181186
" Assets to be ignored. Default pattern is:\n"
182187
" %s\n",
@@ -542,6 +547,8 @@ int main(int argc, char* const argv[])
542547
bundle.setInstrumentationPackageNameOverride(argv[0]);
543548
} else if (strcmp(cp, "-auto-add-overlay") == 0) {
544549
bundle.setAutoAddOverlay(true);
550+
} else if (strcmp(cp, "-error-on-failed-insert") == 0) {
551+
bundle.setErrorOnFailedInsert(true);
545552
} else if (strcmp(cp, "-product") == 0) {
546553
argc--;
547554
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)