diff options
5 files changed, 108 insertions, 3 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java index 9ae7131..c9abddb 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java @@ -48,6 +48,7 @@ public class LintConstants { // Tags: Manifest public static final String TAG_SERVICE = "service"; //$NON-NLS-1$ public static final String TAG_USES_PERMISSION = "uses-permission";//$NON-NLS-1$ + public static final String TAG_USES_LIBRARY = "uses-library"; //$NON-NLS-1$ public static final String TAG_APPLICATION = "application"; //$NON-NLS-1$ public static final String TAG_INTENT_FILTER = "intent-filter"; //$NON-NLS-1$ public static final String TAG_USES_SDK = "uses-sdk"; //$NON-NLS-1$ diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java index 0232245..74ddd8a 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java @@ -53,7 +53,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { private static final List<Issue> sIssues; static { - final int initialCapacity = 85; + final int initialCapacity = 86; List<Issue> issues = new ArrayList<Issue>(initialCapacity); issues.add(AccessibilityDetector.ISSUE); @@ -103,6 +103,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { issues.add(ManifestOrderDetector.ORDER); issues.add(ManifestOrderDetector.USES_SDK); issues.add(ManifestOrderDetector.MULTIPLE_USES_SDK); + issues.add(ManifestOrderDetector.WRONG_PARENT); issues.add(SecurityDetector.EXPORTED_SERVICE); issues.add(SecurityDetector.OPEN_PROVIDER); issues.add(SecurityDetector.WORLD_READABLE); diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ManifestOrderDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ManifestOrderDetector.java index 95ca8b9..856bd26 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ManifestOrderDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ManifestOrderDetector.java @@ -20,7 +20,12 @@ import static com.android.tools.lint.detector.api.LintConstants.ANDROID_MANIFEST import static com.android.tools.lint.detector.api.LintConstants.ANDROID_URI; import static com.android.tools.lint.detector.api.LintConstants.ATTR_MIN_SDK_VERSION; import static com.android.tools.lint.detector.api.LintConstants.ATTR_TARGET_SDK_VERSION; +import static com.android.tools.lint.detector.api.LintConstants.TAG_ACTIVITY; import static com.android.tools.lint.detector.api.LintConstants.TAG_APPLICATION; +import static com.android.tools.lint.detector.api.LintConstants.TAG_PROVIDER; +import static com.android.tools.lint.detector.api.LintConstants.TAG_RECEIVER; +import static com.android.tools.lint.detector.api.LintConstants.TAG_SERVICE; +import static com.android.tools.lint.detector.api.LintConstants.TAG_USES_LIBRARY; import static com.android.tools.lint.detector.api.LintConstants.TAG_USES_PERMISSION; import static com.android.tools.lint.detector.api.LintConstants.TAG_USES_SDK; @@ -35,6 +40,7 @@ import com.android.tools.lint.detector.api.Speed; import com.android.tools.lint.detector.api.XmlContext; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.io.File; @@ -93,11 +99,29 @@ public class ManifestOrderDetector extends Detector implements Detector.XmlScann Category.CORRECTNESS, 6, - Severity.ERROR, + Severity.FATAL, ManifestOrderDetector.class, EnumSet.of(Scope.MANIFEST)).setMoreInfo( "http://developer.android.com/guide/topics/manifest/uses-sdk-element.html"); //$NON-NLS-1$ + /** Missing a {@code <uses-sdk>} element */ + public static final Issue WRONG_PARENT = Issue.create( + "WrongManifestParent", //$NON-NLS-1$ + "Checks that various manifest elements are declared in the right place", + + "The <uses-library> element should be defined as a direct child of the " + + "<application> tag, not the <manifest> tag or an <activity> tag. Similarly, " + + "a <uses-sdk> tag much be declared at the root level, and so on. This check " + + "looks for incorrect declaration locations in the manifest, and complains " + + "if an element is found in the wrong place.", + + Category.CORRECTNESS, + 6, + Severity.FATAL, + ManifestOrderDetector.class, + EnumSet.of(Scope.MANIFEST)).setMoreInfo( + "http://developer.android.com/guide/topics/manifest/manifest-intro.html"); //$NON-NLS-1$ + /** Constructs a new {@link ManifestOrderDetector} check */ public ManifestOrderDetector() { } @@ -148,13 +172,41 @@ public class ManifestOrderDetector extends Detector implements Detector.XmlScann "uses-feature", //$NON-NLS-1$ "supports-screens", //$NON-NLS-1$ "compatible-screens", //$NON-NLS-1$ - "supports-gl-texture" //$NON-NLS-1$ + "supports-gl-texture", //$NON-NLS-1$ + TAG_USES_LIBRARY, + TAG_ACTIVITY, + TAG_SERVICE, + TAG_PROVIDER, + TAG_RECEIVER ); } @Override public void visitElement(XmlContext context, Element element) { String tag = element.getTagName(); + Node parentNode = element.getParentNode(); + + if (tag.equals(TAG_USES_LIBRARY) || tag.equals(TAG_ACTIVITY) || tag.equals(TAG_SERVICE) + || tag.equals(TAG_PROVIDER) || tag.equals(TAG_RECEIVER)) { + if (!TAG_APPLICATION.equals(parentNode.getNodeName()) + && context.isEnabled(WRONG_PARENT)) { + context.report(WRONG_PARENT, element, context.getLocation(element), + String.format( + "The <%1$s> element must be a direct child of the <application> element", + tag), null); + } + + return; + } + + if (parentNode != element.getOwnerDocument().getDocumentElement() + && context.isEnabled(WRONG_PARENT)) { + context.report(WRONG_PARENT, element, context.getLocation(element), + String.format( + "The <%1$s> element must be a direct child of the " + + "<manifest> root element", tag), null); + } + if (tag.equals(TAG_USES_SDK)) { mSeenUsesSdk++; diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ManifestOrderDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ManifestOrderDetectorTest.java index 8ecee91..9553d78 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ManifestOrderDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ManifestOrderDetectorTest.java @@ -77,4 +77,27 @@ public class ManifestOrderDetectorTest extends AbstractCheckTest { "multiplesdk.xml=>AndroidManifest.xml", "res/values/strings.xml")); } + + public void testWrongLocation() throws Exception { + assertEquals( + "AndroidManifest.xml:10: Error: The <permission> element must be a direct child of the <manifest> root element\n" + + "AndroidManifest.xml:11: Error: The <permission-tree> element must be a direct child of the <manifest> root element\n" + + "AndroidManifest.xml:12: Error: The <permission-group> element must be a direct child of the <manifest> root element\n" + + "AndroidManifest.xml:14: Error: The <uses-sdk> element must be a direct child of the <manifest> root element\n" + + "AndroidManifest.xml:15: Error: The <uses-configuration> element must be a direct child of the <manifest> root element\n" + + "AndroidManifest.xml:16: Error: The <uses-feature> element must be a direct child of the <manifest> root element\n" + + "AndroidManifest.xml:17: Error: The <supports-screens> element must be a direct child of the <manifest> root element\n" + + "AndroidManifest.xml:18: Error: The <compatible-screens> element must be a direct child of the <manifest> root element\n" + + "AndroidManifest.xml:19: Error: The <supports-gl-texture> element must be a direct child of the <manifest> root element\n" + + "AndroidManifest.xml:24: Error: The <uses-library> element must be a direct child of the <application> element\n" + + "AndroidManifest.xml:25: Error: The <activity> element must be a direct child of the <application> element\n" + + "AndroidManifest.xml:8: Error: The <uses-sdk> element must be a direct child of the <manifest> root element\n" + + "AndroidManifest.xml:8: Warning: <uses-sdk> tag appears after <application> tag\n" + + "AndroidManifest.xml:8: Warning: <uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion=\"?\"\n" + + "AndroidManifest.xml:9: Error: The <uses-permission> element must be a direct child of the <manifest> root element\n" + + "ManifestOrderDetectorTest_testWrongLocation/AndroidManifest.xml:14: Error: There should only be a single <uses-sdk> element in the manifest: merge these together\n" + + "=> ManifestOrderDetectorTest_testWrongLocation/AndroidManifest.xml:8: Also appears here", + + lintProject("broken-manifest2.xml=>AndroidManifest.xml")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/broken-manifest2.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/broken-manifest2.xml new file mode 100644 index 0000000..307046b --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/broken-manifest2.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.helloworld" + android:versionCode="1" + android:versionName="1.0"> + <application android:icon="@drawable/icon" android:label="@string/app_name"> + <!-- Wrong declaration locations --> + <uses-sdk android:minSdkVersion="Froyo" /> + <uses-permission /> + <permission /> + <permission-tree /> + <permission-group /> + <instrumentation /> + <uses-sdk /> + <uses-configuration /> + <uses-feature /> + <supports-screens /> + <compatible-screens /> + <supports-gl-texture /> + + </application> + + <!-- Wrong declaration locations --> + <uses-library /> + <activity android:name=".HelloWorld" + android:label="@string/app_name" /> + +</manifest> |
