From df08d1c24dbbc242978ee33416d1e54998f88915 Mon Sep 17 00:00:00 2001 From: Jeff Davidson Date: Tue, 25 Feb 2014 12:28:08 -0800 Subject: [PATCH] Add --replace-version flag to aapt. Motivation: we'd like to programmatically specify the version name/code (i.e. to include the build number from the build server). However, this means that we cannot specify version info in the AndroidManifest.xml file, as this takes precedence. Not doing so makes IDE use more difficult, as the IDE gets version code 0 and won't install over an existing non-IDE version unless you first force a downgrade to an IDE build from the command line. This flag allows us to specify a very high version code in the AndroidManifest.xml file, making IDE builds take precedence, while still allowing us to override this info when performing command-line (official) builds. Change-Id: I5d01048698af5c26bdf19066c6cd4eca1115112a --- tools/aapt/Bundle.h | 11 +++++++---- tools/aapt/Main.cpp | 7 +++++++ tools/aapt/Resource.cpp | 38 +++++++++++++++++++++++++++++++------- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index cbeaae84d5738..49b8b55cb8dff 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -59,10 +59,10 @@ public: mAndroidManifestFile(NULL), mPublicOutputFile(NULL), mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL), mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL), - mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL), - mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL), - mUseCrunchCache(false), mErrorOnFailedInsert(false), mErrorOnMissingConfigEntry(false), - mOutputTextSymbols(NULL), + mVersionCode(NULL), mVersionName(NULL), mReplaceVersion(false), mCustomPackage(NULL), + mExtraPackages(NULL), mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), + mProduct(NULL), mUseCrunchCache(false), mErrorOnFailedInsert(false), + mErrorOnMissingConfigEntry(false), mOutputTextSymbols(NULL), mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL), mArgc(0), mArgv(NULL) {} @@ -166,6 +166,8 @@ public: void setVersionCode(const char* val) { mVersionCode = val; } const char* getVersionName() const { return mVersionName; } void setVersionName(const char* val) { mVersionName = val; } + bool getReplaceVersion() { return mReplaceVersion; } + void setReplaceVersion(bool val) { mReplaceVersion = val; } const char* getCustomPackage() const { return mCustomPackage; } void setCustomPackage(const char* val) { mCustomPackage = val; } const char* getExtraPackages() const { return mExtraPackages; } @@ -285,6 +287,7 @@ private: const char* mMaxSdkVersion; const char* mVersionCode; const char* mVersionName; + bool mReplaceVersion; const char* mCustomPackage; const char* mExtraPackages; const char* mMaxResVersion; diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp index 1ed46308fb30c..33711fa5ba9b2 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -153,6 +153,11 @@ void usage(void) " inserts android:versionCode in to manifest.\n" " --version-name\n" " inserts android:versionName in to manifest.\n" + " --replace-version\n" + " If --version-code and/or --version-name are specified, these\n" + " values will replace any value already in the manifest. By\n" + " default, nothing is changed if the manifest already defines\n" + " these attributes.\n" " --custom-package\n" " generates R.java into a different package.\n" " --extra-packages\n" @@ -532,6 +537,8 @@ int main(int argc, char* const argv[]) goto bail; } bundle.setVersionName(argv[0]); + } else if (strcmp(cp, "-replace-version") == 0) { + bundle.setReplaceVersion(true); } else if (strcmp(cp, "-values") == 0) { bundle.setValues(true); } else if (strcmp(cp, "-include-meta-data") == 0) { diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index c923bc2fbf982..6d9d62ebb5a2e 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -676,13 +676,15 @@ static bool applyFileOverlay(Bundle *bundle, } /* - * Inserts an attribute in a given node, only if the attribute does not - * exist. + * Inserts an attribute in a given node. * If errorOnFailedInsert is true, and the attribute already exists, returns false. - * Returns true otherwise, even if the attribute already exists. + * If replaceExisting is true, the attribute will be updated if it already exists. + * Returns true otherwise, even if the attribute already exists, and does not modify + * the existing attribute's value. */ bool addTagAttribute(const sp& node, const char* ns8, - const char* attr8, const char* value, bool errorOnFailedInsert) + const char* attr8, const char* value, bool errorOnFailedInsert, + bool replaceExisting) { if (value == NULL) { return true; @@ -691,7 +693,16 @@ bool addTagAttribute(const sp& node, const char* ns8, const String16 ns(ns8); const String16 attr(attr8); - if (node->getAttribute(ns, attr) != NULL) { + XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr); + if (existingEntry != NULL) { + if (replaceExisting) { + NOISY(printf("Info: AndroidManifest.xml already defines %s (in %s);" + " overwriting existing value from manifest.\n", + String8(attr).string(), String8(ns).string())); + existingEntry->string = String16(value); + return true; + } + if (errorOnFailedInsert) { fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);" " cannot insert new value %s.\n", @@ -711,6 +722,18 @@ bool addTagAttribute(const sp& node, const char* ns8, return true; } +/* + * Inserts an attribute in a given node, only if the attribute does not + * exist. + * If errorOnFailedInsert is true, and the attribute already exists, returns false. + * Returns true otherwise, even if the attribute already exists. + */ +bool addTagAttribute(const sp& node, const char* ns8, + const char* attr8, const char* value, bool errorOnFailedInsert) +{ + return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false); +} + static void fullyQualifyClassName(const String8& package, sp node, const String16& attrName) { XMLNode::attribute_entry* attr = node->editAttribute( @@ -748,13 +771,14 @@ status_t massageManifest(Bundle* bundle, sp root) } bool errorOnFailedInsert = bundle->getErrorOnFailedInsert(); + bool replaceVersion = bundle->getReplaceVersion(); if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode", - bundle->getVersionCode(), errorOnFailedInsert)) { + bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) { return UNKNOWN_ERROR; } if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName", - bundle->getVersionName(), errorOnFailedInsert)) { + bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) { return UNKNOWN_ERROR; }