aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2011-11-21 16:12:31 -0800
committerTor Norbye <tnorbye@google.com>2011-11-23 08:56:14 -0800
commitbb54cce6ded6e5f95388b3352797bfc85e1eb838 (patch)
treefc436a4419dfafdd9a4402ca1c7b0bebfbf7bdb9
parentd1804c6668a9b8eb878b7247b9e55ddfb056128b (diff)
downloadsdk-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
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java6
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/Lint.java26
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java1
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java89
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java42
-rwxr-xr-xrule_api/src/com/android/ide/common/api/IClientRulesEngine.java7
7 files changed, 137 insertions, 39 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java
index dd24322..ae66dbf 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java
@@ -509,4 +509,9 @@ class ClientRulesEngine implements IClientRulesEngine {
prefix = Character.toLowerCase(prefix.charAt(0)) + prefix.substring(1);
return DescriptorsUtils.getFreeWidgetId(root, prefix);
}
+
+ public String getAppNameSpace() {
+ ManifestInfo info = ManifestInfo.get(mRulesEngine.getEditor().getProject());
+ return info.getPackage();
+ }
} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java
index 4454e1b..279e918 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java
@@ -42,6 +42,7 @@ import junit.framework.TestCase;
/**
* Common layout helpers from LayoutRule tests
*/
+@SuppressWarnings("javadoc")
public class LayoutTestBase extends TestCase {
/**
* Helper function used by tests to drag a button into a canvas containing
@@ -309,6 +310,11 @@ public class LayoutTestBase extends TestCase {
fail("Not supported in tests yet");
return 0;
}
+
+ public String getAppNameSpace() {
+ fail("Not supported in tests yet");
+ return null;
+ }
}
public void testDummy() {
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());
}
}
}
diff --git a/rule_api/src/com/android/ide/common/api/IClientRulesEngine.java b/rule_api/src/com/android/ide/common/api/IClientRulesEngine.java
index 0853378..68d7bac 100755
--- a/rule_api/src/com/android/ide/common/api/IClientRulesEngine.java
+++ b/rule_api/src/com/android/ide/common/api/IClientRulesEngine.java
@@ -242,5 +242,12 @@ public interface IClientRulesEngine {
*/
public String getUniqueId(String fqcn);
+ /**
+ * Returns the namespace URI for attributes declared and used inside the
+ * app. (This is not the Android namespace.)
+ *
+ * @return the namespace URI
+ */
+ public String getAppNameSpace();
}