aboutsummaryrefslogtreecommitdiffstats
path: root/common/src/com/android/xml/AndroidManifest.java
diff options
context:
space:
mode:
Diffstat (limited to 'common/src/com/android/xml/AndroidManifest.java')
-rw-r--r--common/src/com/android/xml/AndroidManifest.java359
1 files changed, 359 insertions, 0 deletions
diff --git a/common/src/com/android/xml/AndroidManifest.java b/common/src/com/android/xml/AndroidManifest.java
new file mode 100644
index 0000000..d0f2126
--- /dev/null
+++ b/common/src/com/android/xml/AndroidManifest.java
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.xml;
+
+import com.android.SdkConstants;
+import com.android.io.IAbstractFile;
+import com.android.io.IAbstractFolder;
+import com.android.io.StreamException;
+
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+
+/**
+ * Helper and Constants for the AndroidManifest.xml file.
+ *
+ */
+public final class AndroidManifest {
+
+ public final static String NODE_MANIFEST = "manifest";
+ public final static String NODE_APPLICATION = "application";
+ public final static String NODE_ACTIVITY = "activity";
+ public final static String NODE_ACTIVITY_ALIAS = "activity-alias";
+ public final static String NODE_SERVICE = "service";
+ public final static String NODE_RECEIVER = "receiver";
+ public final static String NODE_PROVIDER = "provider";
+ public final static String NODE_INTENT = "intent-filter";
+ public final static String NODE_ACTION = "action";
+ public final static String NODE_CATEGORY = "category";
+ public final static String NODE_USES_SDK = "uses-sdk";
+ public final static String NODE_INSTRUMENTATION = "instrumentation";
+ public final static String NODE_USES_LIBRARY = "uses-library";
+ public final static String NODE_SUPPORTS_SCREENS = "supports-screens";
+ public final static String NODE_USES_CONFIGURATION = "uses-configuration";
+ public final static String NODE_USES_FEATURE = "uses-feature";
+
+ public final static String ATTRIBUTE_PACKAGE = "package";
+ public final static String ATTRIBUTE_VERSIONCODE = "versionCode";
+ public final static String ATTRIBUTE_NAME = "name";
+ public final static String ATTRIBUTE_REQUIRED = "required";
+ public final static String ATTRIBUTE_GLESVERSION = "glEsVersion";
+ public final static String ATTRIBUTE_PROCESS = "process";
+ public final static String ATTRIBUTE_DEBUGGABLE = "debuggable";
+ public final static String ATTRIBUTE_LABEL = "label";
+ public final static String ATTRIBUTE_ICON = "icon";
+ public final static String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion";
+ public final static String ATTRIBUTE_TARGET_SDK_VERSION = "targetSdkVersion";
+ public final static String ATTRIBUTE_TARGET_PACKAGE = "targetPackage";
+ public final static String ATTRIBUTE_TARGET_ACTIVITY = "targetActivity";
+ public final static String ATTRIBUTE_MANAGE_SPACE_ACTIVITY = "manageSpaceActivity";
+ public final static String ATTRIBUTE_EXPORTED = "exported";
+ public final static String ATTRIBUTE_RESIZEABLE = "resizeable";
+ public final static String ATTRIBUTE_ANYDENSITY = "anyDensity";
+ public final static String ATTRIBUTE_SMALLSCREENS = "smallScreens";
+ public final static String ATTRIBUTE_NORMALSCREENS = "normalScreens";
+ public final static String ATTRIBUTE_LARGESCREENS = "largeScreens";
+ public final static String ATTRIBUTE_REQ_5WAYNAV = "reqFiveWayNav";
+ public final static String ATTRIBUTE_REQ_NAVIGATION = "reqNavigation";
+ public final static String ATTRIBUTE_REQ_HARDKEYBOARD = "reqHardKeyboard";
+ public final static String ATTRIBUTE_REQ_KEYBOARDTYPE = "reqKeyboardType";
+ public final static String ATTRIBUTE_REQ_TOUCHSCREEN = "reqTouchScreen";
+ public static final String ATTRIBUTE_THEME = "theme";
+
+ /**
+ * Returns an {@link IAbstractFile} object representing the manifest for the given project.
+ *
+ * @param projectFolder The project containing the manifest file.
+ * @return An IAbstractFile object pointing to the manifest or null if the manifest
+ * is missing.
+ */
+ public static IAbstractFile getManifest(IAbstractFolder projectFolder) {
+ IAbstractFile file = projectFolder.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML);
+ if (file.exists()) {
+ return file;
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the package for a given project.
+ * @param projectFolder the folder of the project.
+ * @return the package info or null (or empty) if not found.
+ * @throws XPathExpressionException
+ * @throws StreamException If any error happens when reading the manifest.
+ */
+ public static String getPackage(IAbstractFolder projectFolder)
+ throws XPathExpressionException, StreamException {
+ IAbstractFile file = getManifest(projectFolder);
+ if (file != null) {
+ return getPackage(file);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the package for a given manifest.
+ * @param manifestFile the manifest to parse.
+ * @return the package info or null (or empty) if not found.
+ * @throws XPathExpressionException
+ * @throws StreamException If any error happens when reading the manifest.
+ */
+ public static String getPackage(IAbstractFile manifestFile)
+ throws XPathExpressionException, StreamException {
+ XPath xPath = AndroidXPathFactory.newXPath();
+
+ return xPath.evaluate(
+ "/" + NODE_MANIFEST +
+ "/@" + ATTRIBUTE_PACKAGE,
+ new InputSource(manifestFile.getContents()));
+ }
+
+ /**
+ * Returns whether the manifest is set to make the application debuggable.
+ *
+ * If the give manifest does not contain the debuggable attribute then the application
+ * is considered to not be debuggable.
+ *
+ * @param manifestFile the manifest to parse.
+ * @return true if the application is debuggable.
+ * @throws XPathExpressionException
+ * @throws StreamException If any error happens when reading the manifest.
+ */
+ public static boolean getDebuggable(IAbstractFile manifestFile)
+ throws XPathExpressionException, StreamException {
+ XPath xPath = AndroidXPathFactory.newXPath();
+
+ String value = xPath.evaluate(
+ "/" + NODE_MANIFEST +
+ "/" + NODE_APPLICATION +
+ "/@" + AndroidXPathFactory.DEFAULT_NS_PREFIX +
+ ":" + ATTRIBUTE_DEBUGGABLE,
+ new InputSource(manifestFile.getContents()));
+
+ // default is not debuggable, which is the same behavior as parseBoolean
+ return Boolean.parseBoolean(value);
+ }
+
+ /**
+ * Returns the value of the versionCode attribute or -1 if the value is not set.
+ * @param manifestFile the manifest file to read the attribute from.
+ * @return the integer value or -1 if not set.
+ * @throws XPathExpressionException
+ * @throws StreamException If any error happens when reading the manifest.
+ */
+ public static int getVersionCode(IAbstractFile manifestFile)
+ throws XPathExpressionException, StreamException {
+ XPath xPath = AndroidXPathFactory.newXPath();
+
+ String result = xPath.evaluate(
+ "/" + NODE_MANIFEST +
+ "/@" + AndroidXPathFactory.DEFAULT_NS_PREFIX +
+ ":" + ATTRIBUTE_VERSIONCODE,
+ new InputSource(manifestFile.getContents()));
+
+ try {
+ return Integer.parseInt(result);
+ } catch (NumberFormatException e) {
+ return -1;
+ }
+ }
+
+ /**
+ * Returns whether the version Code attribute is set in a given manifest.
+ * @param manifestFile the manifest to check
+ * @return true if the versionCode attribute is present and its value is not empty.
+ * @throws XPathExpressionException
+ * @throws StreamException If any error happens when reading the manifest.
+ */
+ public static boolean hasVersionCode(IAbstractFile manifestFile)
+ throws XPathExpressionException, StreamException {
+ XPath xPath = AndroidXPathFactory.newXPath();
+
+ Object result = xPath.evaluate(
+ "/" + NODE_MANIFEST +
+ "/@" + AndroidXPathFactory.DEFAULT_NS_PREFIX +
+ ":" + ATTRIBUTE_VERSIONCODE,
+ new InputSource(manifestFile.getContents()),
+ XPathConstants.NODE);
+
+ if (result != null) {
+ Node node = (Node)result;
+ if (node.getNodeValue().length() > 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the value of the minSdkVersion attribute.
+ * <p/>
+ * If the attribute is set with an int value, the method returns an Integer object.
+ * <p/>
+ * If the attribute is set with a codename, it returns the codename as a String object.
+ * <p/>
+ * If the attribute is not set, it returns null.
+ *
+ * @param manifestFile the manifest file to read the attribute from.
+ * @return the attribute value.
+ * @throws XPathExpressionException
+ * @throws StreamException If any error happens when reading the manifest.
+ */
+ public static Object getMinSdkVersion(IAbstractFile manifestFile)
+ throws XPathExpressionException, StreamException {
+ XPath xPath = AndroidXPathFactory.newXPath();
+
+ String result = xPath.evaluate(
+ "/" + NODE_MANIFEST +
+ "/" + NODE_USES_SDK +
+ "/@" + AndroidXPathFactory.DEFAULT_NS_PREFIX +
+ ":" + ATTRIBUTE_MIN_SDK_VERSION,
+ new InputSource(manifestFile.getContents()));
+
+ try {
+ return Integer.valueOf(result);
+ } catch (NumberFormatException e) {
+ return result.length() > 0 ? result : null;
+ }
+ }
+
+ /**
+ * Returns the value of the targetSdkVersion attribute (defaults to 1 if the attribute is
+ * not set), or -1 if the value is a codename.
+ * @param manifestFile the manifest file to read the attribute from.
+ * @return the integer value or -1 if not set.
+ * @throws XPathExpressionException
+ * @throws StreamException If any error happens when reading the manifest.
+ */
+ public static Integer getTargetSdkVersion(IAbstractFile manifestFile)
+ throws XPathExpressionException, StreamException {
+ XPath xPath = AndroidXPathFactory.newXPath();
+
+ String result = xPath.evaluate(
+ "/" + NODE_MANIFEST +
+ "/" + NODE_USES_SDK +
+ "/@" + AndroidXPathFactory.DEFAULT_NS_PREFIX +
+ ":" + ATTRIBUTE_TARGET_SDK_VERSION,
+ new InputSource(manifestFile.getContents()));
+
+ try {
+ return Integer.valueOf(result);
+ } catch (NumberFormatException e) {
+ return result.length() > 0 ? -1 : null;
+ }
+ }
+
+ /**
+ * Returns the application icon for a given manifest.
+ * @param manifestFile the manifest to parse.
+ * @return the icon or null (or empty) if not found.
+ * @throws XPathExpressionException
+ * @throws StreamException If any error happens when reading the manifest.
+ */
+ public static String getApplicationIcon(IAbstractFile manifestFile)
+ throws XPathExpressionException, StreamException {
+ XPath xPath = AndroidXPathFactory.newXPath();
+
+ return xPath.evaluate(
+ "/" + NODE_MANIFEST +
+ "/" + NODE_APPLICATION +
+ "/@" + AndroidXPathFactory.DEFAULT_NS_PREFIX +
+ ":" + ATTRIBUTE_ICON,
+ new InputSource(manifestFile.getContents()));
+ }
+
+ /**
+ * Returns the application label for a given manifest.
+ * @param manifestFile the manifest to parse.
+ * @return the label or null (or empty) if not found.
+ * @throws XPathExpressionException
+ * @throws StreamException If any error happens when reading the manifest.
+ */
+ public static String getApplicationLabel(IAbstractFile manifestFile)
+ throws XPathExpressionException, StreamException {
+ XPath xPath = AndroidXPathFactory.newXPath();
+
+ return xPath.evaluate(
+ "/" + NODE_MANIFEST +
+ "/" + NODE_APPLICATION +
+ "/@" + AndroidXPathFactory.DEFAULT_NS_PREFIX +
+ ":" + ATTRIBUTE_LABEL,
+ new InputSource(manifestFile.getContents()));
+ }
+
+ /**
+ * Combines a java package, with a class value from the manifest to make a fully qualified
+ * class name
+ * @param javaPackage the java package from the manifest.
+ * @param className the class name from the manifest.
+ * @return the fully qualified class name.
+ */
+ public static String combinePackageAndClassName(String javaPackage, String className) {
+ if (className == null || className.length() == 0) {
+ return javaPackage;
+ }
+ if (javaPackage == null || javaPackage.length() == 0) {
+ return className;
+ }
+
+ // the class name can be a subpackage (starts with a '.'
+ // char), a simple class name (no dot), or a full java package
+ boolean startWithDot = (className.charAt(0) == '.');
+ boolean hasDot = (className.indexOf('.') != -1);
+ if (startWithDot || hasDot == false) {
+
+ // add the concatenation of the package and class name
+ if (startWithDot) {
+ return javaPackage + className;
+ } else {
+ return javaPackage + '.' + className;
+ }
+ } else {
+ // just add the class as it should be a fully qualified java name.
+ return className;
+ }
+ }
+
+ /**
+ * Given a fully qualified activity name (e.g. com.foo.test.MyClass) and given a project
+ * package base name (e.g. com.foo), returns the relative activity name that would be used
+ * the "name" attribute of an "activity" element.
+ *
+ * @param fullActivityName a fully qualified activity class name, e.g. "com.foo.test.MyClass"
+ * @param packageName The project base package name, e.g. "com.foo"
+ * @return The relative activity name if it can be computed or the original fullActivityName.
+ */
+ public static String extractActivityName(String fullActivityName, String packageName) {
+ if (packageName != null && fullActivityName != null) {
+ if (packageName.length() > 0 && fullActivityName.startsWith(packageName)) {
+ String name = fullActivityName.substring(packageName.length());
+ if (name.length() > 0 && name.charAt(0) == '.') {
+ return name;
+ }
+ }
+ }
+
+ return fullActivityName;
+ }
+}