Add warning on mismatch minSdkVersion.

This is for both Ant and ADT.
For Ant, also added a check for non-integer values when the platform
is not a preview.

BUG:2118374

Change-Id: Ic8ec533d66a31d9e4b51c9c38b5eaab97bca7414
diff --git a/tools/anttasks/src/com/android/ant/SetupTask.java b/tools/anttasks/src/com/android/ant/SetupTask.java
index 27d73d6..1201108 100644
--- a/tools/anttasks/src/com/android/ant/SetupTask.java
+++ b/tools/anttasks/src/com/android/ant/SetupTask.java
@@ -16,6 +16,7 @@
 
 package com.android.ant;
 
+import com.android.sdklib.AndroidVersion;
 import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.ISdkLog;
 import com.android.sdklib.SdkManager;
@@ -160,11 +161,8 @@
         }
         System.out.println("API level: " + androidTarget.getVersion().getApiString());
 
-        // if needed check the manifest so that it matches the target
-        if (androidTarget.getVersion().isPreview()) {
-            // for preview, the manifest minSdkVersion node *must* match the target codename
-            checkManifest(antProject, androidTarget.getVersion().getCodename());
-        }
+        // always check the manifest minSdkVersion.
+        checkManifest(antProject, androidTarget.getVersion());
 
         // sets up the properties to find android.jar/framework.aidl/target tools
         String androidJar = androidTarget.getPath(IAndroidTarget.ANDROID_JAR);
@@ -255,7 +253,12 @@
         mDoImport = value;
     }
 
-    private void checkManifest(Project antProject, String codename) {
+    /**
+     * Checks the manifest <code>minSdkVersion</code> attribute.
+     * @param antProject the ant project
+     * @param androidVersion the version of the platform the project is compiling against.
+     */
+    private void checkManifest(Project antProject, AndroidVersion androidVersion) {
         try {
             File manifest = new File(antProject.getBaseDir(), "AndroidManifest.xml");
 
@@ -267,10 +270,47 @@
                     ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
                     new InputSource(new FileInputStream(manifest)));
 
-            if (codename.equals(value) == false) {
-                throw new BuildException(String.format("For '%1$s' SDK Preview, application manifest must declare minSdkVersion to '%1$s'",
-                        codename));
+            if (androidVersion.isPreview()) {
+                // in preview mode, the content of the minSdkVersion must match exactly the
+                // platform codename.
+                String codeName = androidVersion.getCodename();
+                if (codeName.equals(value) == false) {
+                    throw new BuildException(String.format(
+                            "For '%1$s' SDK Preview, attribute minSdkVersion in AndroidManifest.xml must be '%1$s'",
+                            codeName));
+                }
+            } else if (value.length() > 0) {
+                // for normal platform, we'll only display warnings if the value is lower or higher
+                // than the target api level.
+                // First convert to an int.
+                int minSdkValue = -1;
+                try {
+                    minSdkValue = Integer.parseInt(value);
+                } catch (NumberFormatException e) {
+                    // looks like it's not a number: error!
+                    throw new BuildException(String.format(
+                            "Attribute %1$s in AndroidManifest.xml must be an Integer!",
+                            ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION));
+                }
+
+                int projectApiLevel = androidVersion.getApiLevel();
+                if (minSdkValue < projectApiLevel) {
+                    System.out.println(String.format(
+                            "WARNING: Attribute %1$s in AndroidManifest.xml (%2$d) is lower than the project target API level (%3$d)",
+                            ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
+                            minSdkValue, projectApiLevel));
+                } else if (minSdkValue > androidVersion.getApiLevel()) {
+                    System.out.println(String.format(
+                            "WARNING: Attribute %1$s in AndroidManifest.xml (%2$d) is higher than the project target API level (%3$d)",
+                            ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
+                            minSdkValue, projectApiLevel));
+                }
+            } else {
+                // no minSdkVersion? display a warning
+                System.out.println(
+                        "WARNING: No minSdkVersion value set. Application will install on all Android versions.");
             }
+
         } catch (XPathExpressionException e) {
             throw new BuildException(e);
         } catch (FileNotFoundException e) {
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java
index eb8fc53..af0960c 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java
@@ -335,7 +335,7 @@
                     if (codename != null) {
                         // integer minSdk when the target is a preview => fatal error
                         String msg = String.format(
-                                "Platform %1$s is a preview and requires appication manifests to set %2$s to '%1$s'",
+                                "Platform %1$s is a preview and requires appication manifest to set %2$s to '%1$s'",
                                 codename, ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION);
                         AdtPlugin.printErrorToConsole(project, msg);
                         BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
@@ -344,8 +344,18 @@
                     } else if (minSdkValue < projectVersion.getApiLevel()) {
                         // integer minSdk is not high enough for the target => warning
                         String msg = String.format(
-                                "Manifest min SDK version (%1$s) is lower than project target API level (%2$d)",
-                                minSdkVersion, projectVersion.getApiLevel());
+                                "Attribute %1$s (%2$d) is lower than the project target API level (%3$d)",
+                                ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
+                                minSdkValue, projectVersion.getApiLevel());
+                        AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
+                        BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
+                                IMarker.SEVERITY_WARNING);
+                    } else if (minSdkValue > projectVersion.getApiLevel()) {
+                        // integer minSdk is too high for the target => warning
+                        String msg = String.format(
+                                "Attribute %1$s (%2$d) is higher than the project target API level (%3$d)",
+                                ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
+                                minSdkValue, projectVersion.getApiLevel());
                         AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
                         BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
                                 IMarker.SEVERITY_WARNING);