]> git.saurik.com Git - android/aapt.git/commitdiff
Add --error-on-failed-insert option to aapt. do not merge.
authorXavier Ducrohet <xav@android.com>
Thu, 6 Sep 2012 00:49:21 +0000 (17:49 -0700)
committerXavier Ducrohet <xav@android.com>
Wed, 26 Sep 2012 22:05:22 +0000 (15:05 -0700)
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 7714a2429b192c88e134ff67b969121bbaeb5457

Change-Id: I8938ec1238da407a8562c974e9598db39001ffd9

Bundle.h
Main.cpp
Resource.cpp

index 4f93294307d254cf8ccf13c1ebced3d777c82165..8e0be1cb1d39bcdd65a2727aa210ba6a7f01d22e 100644 (file)
--- a/Bundle.h
+++ b/Bundle.h
@@ -62,7 +62,7 @@ public:
           mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
           mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL),
           mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(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), mOutputTextSymbols(NULL),
+          mUseCrunchCache(false), mErrorOnFailedInsert(false), mOutputTextSymbols(NULL),
           mArgc(0), mArgv(NULL)
         {}
     ~Bundle(void) {}
           mArgc(0), mArgv(NULL)
         {}
     ~Bundle(void) {}
@@ -114,6 +114,8 @@ public:
     void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }
     bool getGenDependencies() { return mGenDependencies; }
     void setGenDependencies(bool val) { mGenDependencies = val; }
     void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }
     bool getGenDependencies() { return mGenDependencies; }
     void setGenDependencies(bool val) { mGenDependencies = val; }
+    bool getErrorOnFailedInsert() { return mErrorOnFailedInsert; }
+    void setErrorOnFailedInsert(bool val) { mErrorOnFailedInsert = val; }
 
     bool getUTF16StringsOption() {
         return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);
 
     bool getUTF16StringsOption() {
         return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);
@@ -283,6 +285,7 @@ private:
     bool        mNonConstantId;
     const char* mProduct;
     bool        mUseCrunchCache;
     bool        mNonConstantId;
     const char* mProduct;
     bool        mUseCrunchCache;
+    bool        mErrorOnFailedInsert;
     const char* mOutputTextSymbols;
 
     /* file specification */
     const char* mOutputTextSymbols;
 
     /* file specification */
index 98c65d2a932f0f0a8de65420e2b352328d281dd2..d48394ad4c89885a6191f8a755121ff34eda00ed 100644 (file)
--- a/Main.cpp
+++ b/Main.cpp
@@ -180,6 +180,11 @@ void usage(void)
         "       Make the resources ID non constant. This is required to make an R java class\n"
         "       that does not contain the final value but is used to make reusable compiled\n"
         "       libraries that need to access resources.\n"
         "       Make the resources ID non constant. This is required to make an R java class\n"
         "       that does not contain the final value but is used to make reusable compiled\n"
         "       libraries that need to access resources.\n"
+        "   --error-on-failed-insert\n"
+        "       Forces aapt to return an error if it fails to insert values into the manifest\n"
+        "       with --debug-mode, --min-sdk-version, --target-sdk-version --version-code\n"
+        "       and --version-name.\n"
+        "       Insertion typically fails if the manifest already defines the attribute.\n"
         "   --output-text-symbols\n"
         "       Generates a text file containing the resource symbols of the R class in the\n"
         "       specified folder.\n"
         "   --output-text-symbols\n"
         "       Generates a text file containing the resource symbols of the R class in the\n"
         "       specified folder.\n"
@@ -551,6 +556,8 @@ int main(int argc, char* const argv[])
                     bundle.setInstrumentationPackageNameOverride(argv[0]);
                 } else if (strcmp(cp, "-auto-add-overlay") == 0) {
                     bundle.setAutoAddOverlay(true);
                     bundle.setInstrumentationPackageNameOverride(argv[0]);
                 } else if (strcmp(cp, "-auto-add-overlay") == 0) {
                     bundle.setAutoAddOverlay(true);
+                } else if (strcmp(cp, "-error-on-failed-insert") == 0) {
+                    bundle.setErrorOnFailedInsert(true);
                 } else if (strcmp(cp, "-output-text-symbols") == 0) {
                     argc--;
                     argv++;
                 } else if (strcmp(cp, "-output-text-symbols") == 0) {
                     argc--;
                     argv++;
index 8bdea44b4676ce869e891adf3157fa8dc1c0b3a3..77168f948640fa57abbc70094ebf313e4c5be0af 100644 (file)
@@ -673,24 +673,40 @@ static bool applyFileOverlay(Bundle *bundle,
     return true;
 }
 
     return true;
 }
 
-void addTagAttribute(const sp<XMLNode>& node, const char* ns8,
-        const char* attr8, const char* value)
+/*
+ * 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<XMLNode>& node, const char* ns8,
+        const char* attr8, const char* value, bool errorOnFailedInsert)
 {
     if (value == NULL) {
 {
     if (value == NULL) {
-        return;
+        return true;
     }
     }
-    
+
     const String16 ns(ns8);
     const String16 attr(attr8);
     const String16 ns(ns8);
     const String16 attr(attr8);
-    
+
     if (node->getAttribute(ns, attr) != NULL) {
     if (node->getAttribute(ns, attr) != NULL) {
+        if (errorOnFailedInsert) {
+            fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);"
+                            " cannot insert new value %s.\n",
+                    String8(attr).string(), String8(ns).string(), value);
+            return false;
+        }
+
         fprintf(stderr, "Warning: AndroidManifest.xml already defines %s (in %s);"
                         " using existing value in manifest.\n",
                 String8(attr).string(), String8(ns).string());
         fprintf(stderr, "Warning: AndroidManifest.xml already defines %s (in %s);"
                         " using existing value in manifest.\n",
                 String8(attr).string(), String8(ns).string());
-        return;
+
+        // don't stop the build.
+        return true;
     }
     
     node->addAttribute(ns, attr, String16(value));
     }
     
     node->addAttribute(ns, attr, String16(value));
+    return true;
 }
 
 static void fullyQualifyClassName(const String8& package, sp<XMLNode> node,
 }
 
 static void fullyQualifyClassName(const String8& package, sp<XMLNode> node,
@@ -728,11 +744,17 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
         fprintf(stderr, "No <manifest> tag.\n");
         return UNKNOWN_ERROR;
     }
         fprintf(stderr, "No <manifest> tag.\n");
         return UNKNOWN_ERROR;
     }
-    
-    addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode",
-            bundle->getVersionCode());
-    addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
-            bundle->getVersionName());
+
+    bool errorOnFailedInsert = bundle->getErrorOnFailedInsert();
+
+    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode",
+            bundle->getVersionCode(), errorOnFailedInsert)) {
+        return UNKNOWN_ERROR;
+    }
+    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
+            bundle->getVersionName(), errorOnFailedInsert)) {
+        return UNKNOWN_ERROR;
+    }
     
     if (bundle->getMinSdkVersion() != NULL
             || bundle->getTargetSdkVersion() != NULL
     
     if (bundle->getMinSdkVersion() != NULL
             || bundle->getTargetSdkVersion() != NULL
@@ -743,18 +765,27 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
             root->insertChildAt(vers, 0);
         }
         
             root->insertChildAt(vers, 0);
         }
         
-        addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion",
-                bundle->getMinSdkVersion());
-        addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "targetSdkVersion",
-                bundle->getTargetSdkVersion());
-        addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion",
-                bundle->getMaxSdkVersion());
+        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion",
+                bundle->getMinSdkVersion(), errorOnFailedInsert)) {
+            return UNKNOWN_ERROR;
+        }
+        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "targetSdkVersion",
+                bundle->getTargetSdkVersion(), errorOnFailedInsert)) {
+            return UNKNOWN_ERROR;
+        }
+        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion",
+                bundle->getMaxSdkVersion(), errorOnFailedInsert)) {
+            return UNKNOWN_ERROR;
+        }
     }
 
     if (bundle->getDebugMode()) {
         sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
         if (application != NULL) {
     }
 
     if (bundle->getDebugMode()) {
         sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
         if (application != NULL) {
-            addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true");
+            if (!addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true",
+                    errorOnFailedInsert)) {
+                return UNKNOWN_ERROR;
+            }
         }
     }
 
         }
     }