diff options
author | Tor Norbye <tnorbye@google.com> | 2011-11-21 16:12:31 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2011-11-23 08:56:14 -0800 |
commit | bb54cce6ded6e5f95388b3352797bfc85e1eb838 (patch) | |
tree | fc436a4419dfafdd9a4402ca1c7b0bebfbf7bdb9 /lint | |
parent | d1804c6668a9b8eb878b7247b9e55ddfb056128b (diff) | |
download | sdk-bb54cce6ded6e5f95388b3352797bfc85e1eb838.zip sdk-bb54cce6ded6e5f95388b3352797bfc85e1eb838.tar.gz sdk-bb54cce6ded6e5f95388b3352797bfc85e1eb838.tar.bz2 |
Add package support for Rules API and Detector API
When writing custom view rules, and custom detectors, you may need
access to the package name of the application (in order to produce the
right namespace to look up custom attributes for).
This changeset adds new methods to the two APIs such that clients can
look up the application package. For lint, it also changes things
such that the manifest file is always processed and information
stashed in the Project object. This meant I could also remove the icon
detector code to look up the manifest info directly.
Change-Id: Id8eec96e2788f6d27481d7dcab0c544ea6e0a06d
Diffstat (limited to 'lint')
4 files changed, 119 insertions, 39 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/Lint.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/Lint.java index 0a2d6a6..b809331 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/Lint.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/Lint.java @@ -327,16 +327,22 @@ public class Lint { private void runFileDetectors(Project project, File projectDir) { // Look up manifest information - if (mScope.contains(Scope.MANIFEST)) { - List<Detector> detectors = mScopeDetectors.get(Scope.MANIFEST); - if (detectors != null) { - File file = new File(project.getDir(), ANDROID_MANIFEST_XML); - if (file.exists()) { - Context context = new Context(mClient, project, file, mScope); - context.location = new Location(file, null, null); - XmlVisitor v = new XmlVisitor(mClient.getParser(), detectors); - fireEvent(EventType.SCANNING_FILE, context); - v.visitFile(context, file); + File manifestFile = new File(project.getDir(), ANDROID_MANIFEST_XML); + if (manifestFile.exists()) { + Context context = new Context(mClient, project, manifestFile, mScope); + context.location = new Location(manifestFile, null, null); + IDomParser parser = mClient.getParser(); + context.document = parser.parse(context); + if (context.document != null) { + project.readManifest(context.document); + + if (mScope.contains(Scope.MANIFEST)) { + List<Detector> detectors = mScopeDetectors.get(Scope.MANIFEST); + if (detectors != null) { + XmlVisitor v = new XmlVisitor(parser, detectors); + fireEvent(EventType.SCANNING_FILE, context); + v.visitFile(context, manifestFile); + } } } } 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 146cd04..9aeb0a5 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 @@ -64,6 +64,7 @@ public class LintConstants { public static final String ATTR_MIN_SDK_VERSION = "minSdkVersion"; //$NON-NLS-1$ public static final String ATTR_TARGET_SDK_VERSION = "targetSdkVersion"; //$NON-NLS-1$ public static final String ATTR_ICON = "icon"; //$NON-NLS-1$ + public final static String ATTRIBUTE_PACKAGE = "package"; //$NON-NLS-1$ // Attributes: Resources public static final String ATTR_NAME = "name"; //$NON-NLS-1$ diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java index 2011e86..f38c286 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java @@ -16,9 +16,19 @@ package com.android.tools.lint.detector.api; +import static com.android.tools.lint.detector.api.LintConstants.ANDROID_URI; +import static com.android.tools.lint.detector.api.LintConstants.ATTRIBUTE_PACKAGE; +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_USES_SDK; + import com.android.tools.lint.client.api.Configuration; import com.android.tools.lint.client.api.LintClient; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + import java.io.File; import java.util.ArrayList; import java.util.List; @@ -36,6 +46,9 @@ public class Project { private final File mDir; private final File mReferenceDir; private Configuration mConfiguration; + private String mPackage; + private int mMinSdk = -1; + private int mTargetSdk = -1; /** * If non null, specifies a non-empty list of specific files under this @@ -218,4 +231,80 @@ public class Project { public void setConfiguration(Configuration configuration) { mConfiguration = configuration; } + + /** + * Returns the application package specified by the manifest + * + * @return the application package, or null if unknown + */ + public String getPackage() { + return mPackage; + } + + /** + * Returns the minimum API level requested by the manifest, or -1 if not + * specified + * + * @return the minimum API level or -1 if unknown + */ + public int getMinSdk() { + return mMinSdk; + } + + /** + * Returns the target API level specified by the manifest, or -1 if not + * specified + * + * @return the target API level or -1 if unknown + */ + public int getTargetSdk() { + return mTargetSdk; + } + + /** + * Initialized the manifest state from the given manifest model + * + * @param document the DOM document for the manifest XML document + */ + public void readManifest(Document document) { + Element root = document.getDocumentElement(); + if (root == null) { + return; + } + + mPackage = root.getAttribute(ATTRIBUTE_PACKAGE); + + // Initialize minSdk and targetSdk + NodeList usesSdks = root.getElementsByTagName(TAG_USES_SDK); + if (usesSdks.getLength() > 0) { + Element element = (Element) usesSdks.item(0); + + String minSdk = null; + if (element.hasAttributeNS(ANDROID_URI, ATTR_MIN_SDK_VERSION)) { + minSdk = element.getAttributeNS(ANDROID_URI, ATTR_MIN_SDK_VERSION); + } + if (minSdk != null) { + try { + mMinSdk = Integer.valueOf(minSdk); + } catch (NumberFormatException e) { + mMinSdk = -1; + } + } + + String targetSdk = null; + if (element.hasAttributeNS(ANDROID_URI, ATTR_TARGET_SDK_VERSION)) { + targetSdk = element.getAttributeNS(ANDROID_URI, ATTR_TARGET_SDK_VERSION); + } else if (minSdk != null) { + targetSdk = minSdk; + } + if (targetSdk != null) { + try { + mTargetSdk = Integer.valueOf(targetSdk); + } catch (NumberFormatException e) { + // TODO: Handle codenames? + mTargetSdk = -1; + } + } + } + } } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java index 9852fea..09d46a7 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java @@ -19,7 +19,6 @@ package com.android.tools.lint.checks; import static com.android.tools.lint.detector.api.LintConstants.ANDROID_MANIFEST_XML; import static com.android.tools.lint.detector.api.LintConstants.ANDROID_URI; import static com.android.tools.lint.detector.api.LintConstants.ATTR_ICON; -import static com.android.tools.lint.detector.api.LintConstants.ATTR_MIN_SDK_VERSION; import static com.android.tools.lint.detector.api.LintConstants.DOT_9PNG; import static com.android.tools.lint.detector.api.LintConstants.DOT_GIF; import static com.android.tools.lint.detector.api.LintConstants.DOT_JPG; @@ -33,7 +32,6 @@ import static com.android.tools.lint.detector.api.LintConstants.DRAWABLE_RESOURC import static com.android.tools.lint.detector.api.LintConstants.DRAWABLE_XHDPI; import static com.android.tools.lint.detector.api.LintConstants.RES_FOLDER; import static com.android.tools.lint.detector.api.LintConstants.TAG_APPLICATION; -import static com.android.tools.lint.detector.api.LintConstants.TAG_USES_SDK; import static com.android.tools.lint.detector.api.LintUtils.difference; import static com.android.tools.lint.detector.api.LintUtils.endsWith; import static com.android.tools.lint.detector.api.LintUtils.intersection; @@ -56,7 +54,6 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -255,7 +252,6 @@ public class IconDetector extends Detector.XmlDetectorAdapter { IconDetector.class, Scope.ALL_RESOURCES_SCOPE); - private int mMinSdk; private String mApplicationIcon; /** Constructs a new accessibility check */ @@ -269,7 +265,6 @@ public class IconDetector extends Detector.XmlDetectorAdapter { @Override public void beforeCheckProject(Context context) { - mMinSdk = -1; mApplicationIcon = null; } @@ -992,7 +987,7 @@ public class IconDetector extends Detector.XmlDetectorAdapter { * manifest is at least 11. */ private boolean isAndroid30(Context context, int folderVersion) { - return folderVersion >= 11 || mMinSdk >= 11; + return folderVersion >= 11 || context.project.getMinSdk() >= 11; } /** @@ -1005,7 +1000,13 @@ public class IconDetector extends Detector.XmlDetectorAdapter { return false; } - return folderVersion == 9 || folderVersion == 10 || mMinSdk == 9 || mMinSdk == 10; + if (folderVersion == 9 || folderVersion == 10) { + return true; + } + + int minSdk = context.project.getMinSdk(); + + return minSdk == 9 || minSdk == 10; } private float getMdpiScalingFactor(String folderName) { @@ -1124,32 +1125,15 @@ public class IconDetector extends Detector.XmlDetectorAdapter { @Override public Collection<String> getApplicableElements() { - return Arrays.asList(new String[] { - TAG_APPLICATION, - TAG_USES_SDK, - }); + return Collections.singletonList(TAG_APPLICATION); } @Override public void visitElement(Context context, Element element) { - if (element.getTagName().equals(TAG_USES_SDK)) { - String minSdk = null; - if (element.hasAttributeNS(ANDROID_URI, ATTR_MIN_SDK_VERSION)) { - minSdk = element.getAttributeNS(ANDROID_URI, ATTR_MIN_SDK_VERSION); - } - if (minSdk != null) { - try { - mMinSdk = Integer.valueOf(minSdk); - } catch (NumberFormatException e) { - mMinSdk = -1; - } - } - } else { - assert element.getTagName().equals(TAG_APPLICATION); - mApplicationIcon = element.getAttributeNS(ANDROID_URI, ATTR_ICON); - if (mApplicationIcon.startsWith(DRAWABLE_RESOURCE_PREFIX)) { - mApplicationIcon = mApplicationIcon.substring(DRAWABLE_RESOURCE_PREFIX.length()); - } + assert element.getTagName().equals(TAG_APPLICATION); + mApplicationIcon = element.getAttributeNS(ANDROID_URI, ATTR_ICON); + if (mApplicationIcon.startsWith(DRAWABLE_RESOURCE_PREFIX)) { + mApplicationIcon = mApplicationIcon.substring(DRAWABLE_RESOURCE_PREFIX.length()); } } } |