aboutsummaryrefslogtreecommitdiffstats
path: root/device_validator
diff options
context:
space:
mode:
Diffstat (limited to 'device_validator')
-rw-r--r--device_validator/Android.mk5
-rw-r--r--device_validator/MODULE_LICENSE_APACHE20
-rw-r--r--device_validator/app/.classpath7
-rw-r--r--device_validator/app/.project17
-rw-r--r--device_validator/app/.settings/org.eclipse.jdt.ui.prefs3
-rw-r--r--device_validator/app/Android.mk31
-rw-r--r--device_validator/app/etc/Android.mk10
-rwxr-xr-xdevice_validator/app/etc/device_validator79
-rw-r--r--device_validator/app/etc/manifest.txt3
-rw-r--r--device_validator/app/src/com/android/validator/DeviceValidator.java55
-rw-r--r--device_validator/dvlib/.classpath8
-rw-r--r--device_validator/dvlib/.gitignore1
-rw-r--r--device_validator/dvlib/.project17
-rw-r--r--device_validator/dvlib/Android.mk26
-rw-r--r--device_validator/dvlib/src/com/android/dvlib/DeviceSchema.java344
-rw-r--r--device_validator/dvlib/src/com/android/dvlib/devices.xsd884
-rw-r--r--device_validator/dvlib/tests/Android.mk30
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/DeviceSchemaTest.java311
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/devices.xml290
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/devices_minimal.xml155
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/devices_no_default.xml134
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/devices_no_hardware.xml80
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/devices_no_software.xml80
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/devices_no_states.xml128
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/devices_too_many_defaults.xml140
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/extras/frame.jpeg0
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/extras/frame.png0
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/extras/sixteen.jpeg0
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/extras/sixteen.png0
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/extras/sixtyfour.jpeg0
-rw-r--r--device_validator/dvlib/tests/src/com/android/dvlib/extras/sixtyfour.png0
31 files changed, 2838 insertions, 0 deletions
diff --git a/device_validator/Android.mk b/device_validator/Android.mk
new file mode 100644
index 0000000..9e32461
--- /dev/null
+++ b/device_validator/Android.mk
@@ -0,0 +1,5 @@
+# Copyright 2012 The Android Open Source Project
+
+DEVICE_VALIDATOR_LOCAL_DIR := $(call my-dir)
+include $(DEVICE_VALIDATOR_LOCAL_DIR)/dvlib/Android.mk
+include $(DEVICE_VALIDATOR_LOCAL_DIR)/app/Android.mk
diff --git a/device_validator/MODULE_LICENSE_APACHE2 b/device_validator/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/device_validator/MODULE_LICENSE_APACHE2
diff --git a/device_validator/app/.classpath b/device_validator/app/.classpath
new file mode 100644
index 0000000..a1d7856
--- /dev/null
+++ b/device_validator/app/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/dvlib"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/device_validator/app/.project b/device_validator/app/.project
new file mode 100644
index 0000000..fda9e3d
--- /dev/null
+++ b/device_validator/app/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>device_validator</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/device_validator/app/.settings/org.eclipse.jdt.ui.prefs b/device_validator/app/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..c0fbc32
--- /dev/null
+++ b/device_validator/app/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,3 @@
+#Fri May 25 10:41:24 PDT 2012
+eclipse.preferences.version=1
+formatter_settings_version=11
diff --git a/device_validator/app/Android.mk b/device_validator/app/Android.mk
new file mode 100644
index 0000000..93e6226
--- /dev/null
+++ b/device_validator/app/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2012 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAR_MANIFEST := etc/manifest.txt
+
+LOCAL_JAVA_LIBRARIES := \
+ dvlib
+
+LOCAL_MODULE := device_validator
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+# Build all sub-directories
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/device_validator/app/etc/Android.mk b/device_validator/app/etc/Android.mk
new file mode 100644
index 0000000..69a948c
--- /dev/null
+++ b/device_validator/app/etc/Android.mk
@@ -0,0 +1,10 @@
+# Copyright 2012 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_EXECUTABLES := device_validator
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/device_validator/app/etc/device_validator b/device_validator/app/etc/device_validator
new file mode 100755
index 0000000..08a1023
--- /dev/null
+++ b/device_validator/app/etc/device_validator
@@ -0,0 +1,79 @@
+#!/bin/bash
+# Copyright 2012, 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.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+ newProg=`/bin/ls -ld "${prog}"`
+ newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+ if expr "x${newProg}" : 'x/' >/dev/null; then
+ prog="${newProg}"
+ else
+ progdir=`dirname "${prog}"`
+ prog="${progdir}/${newProg}"
+ fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=device_validator.jar
+frameworkdir="$progdir"
+libdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+ frameworkdir=`dirname "$progdir"`/tools/lib
+ libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+ frameworkdir=`dirname "$progdir"`/framework
+ libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+ echo `basename "$prog"`": can't find $jarfile"
+ exit 1
+fi
+
+
+# Check args.
+if [ debug = "$1" ]; then
+ # add this in for debugging
+ java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
+ shift 1
+else
+ java_debug=
+fi
+
+javaCmd="java"
+
+# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
+if [ `uname` = "Darwin" ]; then
+ os_opts="-XstartOnFirstThread"
+else
+ os_opts=
+fi
+
+jarpath="$frameworkdir/$jarfile"
+
+exec "$javaCmd" \
+ -Xmx256M $os_opts $java_debug \
+ -classpath "$jarpath" \
+ com.android.validator.DeviceValidator "$@"
diff --git a/device_validator/app/etc/manifest.txt b/device_validator/app/etc/manifest.txt
new file mode 100644
index 0000000..55b9038
--- /dev/null
+++ b/device_validator/app/etc/manifest.txt
@@ -0,0 +1,3 @@
+Main-Class: com.android.validator.DeviceValidator
+Class-Path: dvlib.jar
+
diff --git a/device_validator/app/src/com/android/validator/DeviceValidator.java b/device_validator/app/src/com/android/validator/DeviceValidator.java
new file mode 100644
index 0000000..4b4b16d
--- /dev/null
+++ b/device_validator/app/src/com/android/validator/DeviceValidator.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
+ *
+ * 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.validator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import com.android.dvlib.DeviceSchema;
+
+public class DeviceValidator {
+
+ public static void main(String[] args) {
+ if (args.length == 0){
+ printHelp();
+ System.exit(1);
+ }
+ int ret = 0;
+ for (String a : args) {
+ File f = new File(a);
+ try {
+ if (!DeviceSchema.validate(new FileInputStream(f), System.err, f.getParentFile())) {
+ System.err.println("Error validating " + f.getAbsolutePath());
+ System.out.println();
+ ret = 1;
+ } else {
+ System.out.println(f.getAbsolutePath() + " validated successfully.");
+ }
+ } catch (FileNotFoundException e) {
+ System.err.println("File not found: " + a);
+ ret = 1;
+ }
+ }
+ System.exit(ret);
+ }
+
+ private static void printHelp() {
+ System.err.printf("Usage: device_validator [files to validate]...\n");
+ }
+
+}
diff --git a/device_validator/dvlib/.classpath b/device_validator/dvlib/.classpath
new file mode 100644
index 0000000..88fb9b4
--- /dev/null
+++ b/device_validator/dvlib/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="tests/src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/device_validator/dvlib/.gitignore b/device_validator/dvlib/.gitignore
new file mode 100644
index 0000000..e660fd9
--- /dev/null
+++ b/device_validator/dvlib/.gitignore
@@ -0,0 +1 @@
+bin/
diff --git a/device_validator/dvlib/.project b/device_validator/dvlib/.project
new file mode 100644
index 0000000..13abbdf
--- /dev/null
+++ b/device_validator/dvlib/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>dvlib</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/device_validator/dvlib/Android.mk b/device_validator/dvlib/Android.mk
new file mode 100644
index 0000000..1869adb
--- /dev/null
+++ b/device_validator/dvlib/Android.mk
@@ -0,0 +1,26 @@
+# Copyright (C) 2012 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_JAVA_RESOURCE_DIRS := src
+
+LOCAL_MODULE := dvlib
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/device_validator/dvlib/src/com/android/dvlib/DeviceSchema.java b/device_validator/dvlib/src/com/android/dvlib/DeviceSchema.java
new file mode 100644
index 0000000..101baf4
--- /dev/null
+++ b/device_validator/dvlib/src/com/android/dvlib/DeviceSchema.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
+ *
+ * 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.dvlib;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class DeviceSchema {
+
+ public static final String NS_DEVICES_XSD = "http://schemas.android.com/sdk/devices/1";
+
+ /**
+ * The "devices" element is the root element of this schema.
+ *
+ * It must contain one or more "device" elements that each define the
+ * hardware, software, and states for a given device.
+ */
+ public static final String NODE_DEVICES = "devices";
+
+ /**
+ * A "device" element contains a "hardware" element, a "software" element
+ * for each API version it supports, and a "state" element for each possible
+ * state the device could be in.
+ */
+ public static final String NODE_DEVICE = "device";
+
+ /**
+ * The "hardware" element contains all of the hardware information for a
+ * given device.
+ */
+ public static final String NODE_HARDWARE = "hardware";
+
+ /**
+ * The "software" element contains all of the software information for an
+ * API version of the given device.
+ */
+ public static final String NODE_SOFTWARE = "software";
+
+ /**
+ * The "state" element contains all of the parameters for a given state of
+ * the device. It's also capable of redefining hardware configurations if
+ * they change based on state.
+ */
+ public static final String NODE_STATE = "state";
+
+ public static final String NODE_KEYBOARD = "keyboard";
+
+ public static final String NODE_TOUCH = "touch";
+
+ public static final String NODE_GL_EXTENSIONS = "gl-extensions";
+
+ public static final String NODE_GL_VERSION = "gl-version";
+
+ public static final String NODE_NETWORKING = "networking";
+
+ public static final String NODE_REMOVABLE_STORAGE = "removable-storage";
+
+ public static final String NODE_FLASH = "flash";
+
+ public static final String NODE_LIVE_WALLPAPER_SUPPORT = "live-wallpaper-support";
+
+ public static final String NODE_BUTTONS = "buttons";
+
+ public static final String NODE_CAMERA = "camera";
+
+ public static final String NODE_LOCATION = "location";
+
+ public static final String NODE_GPU = "gpu";
+
+ public static final String NODE_DOCK = "dock";
+
+ public static final String NODE_YDPI = "ydpi";
+
+ public static final String NODE_PLUGGED_IN = "plugged-in";
+
+ public static final String NODE_Y_DIMENSION = "y-dimension";
+
+ public static final String NODE_SCREEN_RATIO = "screen-ratio";
+
+ public static final String NODE_NAV_STATE = "nav-state";
+
+ public static final String NODE_HAS_MIC = "has-mic";
+
+ public static final String NODE_RAM = "ram";
+
+ public static final String NODE_XDPI = "xdpi";
+
+ public static final String NODE_DIMENSIONS = "dimensions";
+
+ public static final String NODE_ABI = "abi";
+
+ public static final String NODE_MECHANISM = "mechanism";
+
+ public static final String NODE_MULTITOUCH = "multitouch";
+
+ public static final String NODE_NAV = "nav";
+
+ public static final String NODE_PIXEL_DENSITY = "pixel-density";
+
+ public static final String NODE_SCREEN_ORIENTATION = "screen-orientation";
+
+ public static final String NODE_AUTOFOCUS = "autofocus";
+
+ public static final String NODE_SCREEN_SIZE = "screen-size";
+
+ public static final String NODE_DESCRIPTION = "description";
+
+ public static final String NODE_BLUETOOTH_PROFILES = "bluetooth-profiles";
+
+ public static final String NODE_SCREEN = "screen";
+
+ public static final String NODE_SENSORS = "sensors";
+
+ public static final String NODE_DIAGONAL_LENGTH = "diagonal-length";
+
+ public static final String NODE_SCREEN_TYPE = "screen-type";
+
+ public static final String NODE_KEYBOARD_STATE = "keyboard-state";
+
+ public static final String NODE_X_DIMENSION = "x-dimension";
+
+ public static final String NODE_CPU = "cpu";
+
+ public static final String NODE_INTERNAL_STORAGE = "internal-storage";
+
+ public static final String NODE_META = "meta";
+
+ public static final String NODE_ICONS = "icons";
+
+ public static final String NODE_SIXTY_FOUR = "sixty-four";
+
+ public static final String NODE_SIXTEEN = "sixteen";
+
+ public static final String NODE_FRAME = "frame";
+
+ public static final String NODE_PATH = "path";
+
+ public static final String NODE_PORTRAIT_X_OFFSET = "portrait-x-offset";
+
+ public static final String NODE_PORTRAIT_Y_OFFSET = "portrait-y-offset";
+
+ public static final String NODE_LANDSCAPE_X_OFFSET = "landscape-x-offset";
+
+ public static final String NODE_LANDSCAPE_Y_OFFSET = "landscape-y-offset";
+
+ public static final String NODE_NAME = "name";
+
+ public static final String NODE_API_LEVEL = "api-level";
+
+ public static final String NODE_MANUFACTURER = "manufacturer";
+
+ public static final String ATTR_DEFAULT = "default";
+
+ public static final String ATTR_UNIT = "unit";
+
+ /**
+ * Validates the input stream.
+ *
+ * @param deviceXml
+ * The XML InputStream to validate.
+ * @param out
+ * The OutputStream for error messages.
+ * @param parent
+ * The parent directory of the input stream.
+ * @return Whether the given input constitutes a valid devices file.
+ */
+ public static boolean validate(InputStream deviceXml, OutputStream out, File parent) {
+ Schema s;
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ PrintWriter writer = new PrintWriter(out);
+ try {
+ s = DeviceSchema.getSchema();
+ factory.setValidating(false);
+ factory.setNamespaceAware(true);
+ factory.setSchema(s);
+ ValidationHandler validator = new ValidationHandler(parent, writer);
+ SAXParser parser = factory.newSAXParser();
+ parser.parse(deviceXml, validator);
+ return validator.isValidDevicesFile();
+ } catch (SAXException e) {
+ writer.println(e.getMessage());
+ return false;
+ } catch (ParserConfigurationException e) {
+ writer.println("Error creating SAX parser:");
+ writer.println(e.getMessage());
+ return false;
+ } catch (IOException e) {
+ writer.println("Error reading file stream:");
+ writer.println(e.getMessage());
+ return false;
+ } finally {
+ writer.flush();
+ }
+ }
+
+ /**
+ * Helper to get an input stream of the device config XML schema.
+ */
+ public static InputStream getXsdStream() {
+ return DeviceSchema.class.getResourceAsStream("devices.xsd"); //$NON-NLS-1$
+ }
+
+ /** Helper method that returns a {@link Validator} for our XSD */
+ public static Schema getSchema() throws SAXException {
+ InputStream xsdStream = getXsdStream();
+ SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ Schema schema = factory.newSchema(new StreamSource(xsdStream));
+ return schema;
+ }
+
+ /**
+ * A DefaultHandler that parses only to validate the XML is actually a valid
+ * devices config, since validation can't be entirely encoded in the devices
+ * schema.
+ */
+ private static class ValidationHandler extends DefaultHandler {
+ private boolean mValidDevicesFile = true;
+ private boolean mDefaultSeen = false;
+ private String mDeviceName;
+ private final File mDirectory;
+ private final PrintWriter mWriter;
+ private final StringBuilder mStringAccumulator = new StringBuilder();
+
+ public ValidationHandler(File directory, PrintWriter writer) {
+ mDirectory = directory; // Possibly null
+ mWriter = writer;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String name, Attributes attributes)
+ throws SAXException {
+ if (NODE_DEVICE.equals(localName)) {
+ // Reset for a new device
+ mDefaultSeen = false;
+ } else if (NODE_STATE.equals(localName)) {
+ // Check if the state is set to be a default state
+ String val = attributes.getValue(ATTR_DEFAULT);
+ if (val != null && ("1".equals(val) || Boolean.parseBoolean(val))) {
+ /*
+ * If it is and we already have a default state for this
+ * device, then the device configuration is invalid.
+ * Otherwise, set that we've seen a default state for this
+ * device and continue
+ */
+
+ if (mDefaultSeen) {
+ validationError("More than one default state for device " + mDeviceName);
+ } else {
+ mDefaultSeen = true;
+ }
+ }
+ }
+ mStringAccumulator.setLength(0);
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) {
+ mStringAccumulator.append(ch, start, length);
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String name) throws SAXException {
+ // If this is the end of a device node, make sure we have at least
+ // one default state
+ if (NODE_DEVICE.equals(localName) && !mDefaultSeen) {
+ validationError("No default state for device " + mDeviceName);
+ } else if (NODE_NAME.equals(localName)) {
+ mDeviceName = mStringAccumulator.toString().trim();
+ } else if (NODE_PATH.equals(localName) || NODE_SIXTY_FOUR.equals(localName)
+ || NODE_SIXTEEN.equals(localName)) {
+ if (mDirectory == null) {
+ // There is no given parent directory, so this is not a
+ // valid devices file
+ validationError("No parent directory given, but relative paths exist.");
+ return;
+ }
+ // This is going to break on any files that end with a space,
+ // but that should be an incredibly rare corner case.
+ String relativePath = mStringAccumulator.toString().trim();
+ File f = new File(mDirectory, relativePath);
+ if (f == null || !f.isFile()) {
+ validationError(relativePath + " is not a valid path.");
+ return;
+ }
+ String fileName = f.getName();
+ int extensionStart = fileName.lastIndexOf(".");
+ if (extensionStart == -1 || !fileName.substring(extensionStart + 1).equals("png")) {
+ validationError(relativePath + " is not a valid file type.");
+ }
+ }
+ }
+
+ @Override
+ public void error(SAXParseException e) {
+ validationError(e.getMessage());
+ }
+
+ @Override
+ public void fatalError(SAXParseException e) {
+ validationError(e.getMessage());
+ }
+
+ public boolean isValidDevicesFile() {
+ return mValidDevicesFile;
+ }
+
+ private void validationError(String reason) {
+ mWriter.println("Error: " + reason);
+ mValidDevicesFile = false;
+ }
+
+ }
+}
diff --git a/device_validator/dvlib/src/com/android/dvlib/devices.xsd b/device_validator/dvlib/src/com/android/dvlib/devices.xsd
new file mode 100644
index 0000000..c3fa482
--- /dev/null
+++ b/device_validator/dvlib/src/com/android/dvlib/devices.xsd
@@ -0,0 +1,884 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
+ *
+ * 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.
+-->
+
+<xsd:schema
+ targetNamespace="http://schemas.android.com/sdk/devices/1"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:c="http://schemas.android.com/sdk/devices/1"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1">
+
+ <xsd:element name="devices" type="c:devicesType" />
+
+ <xsd:complexType name="devicesType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ The "devices" element is the root element of this schema.
+
+ It must contain one or more "device" elements that each define the configurations
+ and states available for a given device.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="device" minOccurs="1" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ A device element contains one hardware profile for a device, along with
+ 1 or more software profiles and 1 or more states. Each software profile
+ defines the supported software for a given API release, and each state
+ profile defines a different possible state of the device (screen in
+ portrait orientation, screen in landscape orientation with the keyboard
+ out, etc.)
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="name" type= "xsd:token" />
+ <xsd:element name="manufacturer" type= "xsd:token" />
+ <xsd:element name="meta" type= "c:metaType" minOccurs="0" />
+ <xsd:element name="hardware" type= "c:hardwareType" />
+ <xsd:element name="software" type= "c:softwareType"
+ maxOccurs="unbounded" />
+ <xsd:element name="state" type= "c:stateType"
+ maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="hardwareType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ The hardwareType contains all of the hardware information for
+ a given device. This includes things like the GPU type, screen
+ size, mic presence, etc.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="screen" type= "c:screenType" />
+ <xsd:element name="networking" type= "c:networkingType" />
+ <xsd:element name="sensors" type= "c:sensorsType" />
+ <xsd:element name="mic" type= "c:micType" />
+ <xsd:element name="camera" type= "c:cameraType"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="keyboard" type= "c:keyboardType" />
+ <xsd:element name="nav" type= "c:navType" />
+ <xsd:element name="ram" type= "c:ramType" />
+ <xsd:element name="buttons" type= "c:buttonsType" />
+ <xsd:element name="internal-storage" type= "c:internalStorageType" />
+ <xsd:element name="removable-storage" type= "c:removableStorageType" />
+ <xsd:element name="cpu" type= "c:cpuType" />
+ <xsd:element name="gpu" type= "c:gpuType" />
+ <xsd:element name="abi" type= "c:abiType" />
+ <xsd:element name="dock" type= "c:dockType" />
+ <xsd:element name="plugged-in" type= "c:pluggedInType" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="softwareType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ The softwareType contains all of the device's software
+ information for a given API version. This includes things like
+ live wallpaper support, OpenGL version, etc.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="api-level">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies which API version(s) this this element is
+ defining. This can in the form of a single number
+ or a range of low to high, separated with a dash and
+ with either limit missing. The default lower limit is
+ one, and the default upper limit is unbounded.
+ The following are valid:
+ 10
+ 7-10
+ -10
+ 7-
+ -
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:pattern value="[\d]*-[\d]*|[\d]+" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+ <xsd:element name="live-wallpaper-support" type="xsd:boolean">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies whether the device supports live wallpapers.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+
+ <xsd:element name="bluetooth-profiles">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies all of the available Bluetooth profiles.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="A2DP" />
+ <xsd:enumeration value="ATT" />
+ <xsd:enumeration value="AVRCP" />
+ <xsd:enumeration value="AVDTP" />
+ <xsd:enumeration value="BIP" />
+ <xsd:enumeration value="BPP" />
+ <xsd:enumeration value="CIP" />
+ <xsd:enumeration value="CTP" />
+ <xsd:enumeration value="DIP" />
+ <xsd:enumeration value="DUN" />
+ <xsd:enumeration value="FAX" />
+ <xsd:enumeration value="FTP" />
+ <xsd:enumeration value="GAVDP" />
+ <xsd:enumeration value="GAP" />
+ <xsd:enumeration value="GATT" />
+ <xsd:enumeration value="GOEP" />
+ <xsd:enumeration value="HCRP" />
+ <xsd:enumeration value="HDP" />
+ <xsd:enumeration value="HFP" />
+ <xsd:enumeration value="HID" />
+ <xsd:enumeration value="HSP" />
+ <xsd:enumeration value="ICP" />
+ <xsd:enumeration value="LAP" />
+ <xsd:enumeration value="MAP" />
+ <xsd:enumeration value="OPP" />
+ <xsd:enumeration value="PAN" />
+ <xsd:enumeration value="PBA" />
+ <xsd:enumeration value="PBAP" />
+ <xsd:enumeration value="SPP" />
+ <xsd:enumeration value="SDAP" />
+ <xsd:enumeration value="SAP" />
+ <xsd:enumeration value="SIM" />
+ <xsd:enumeration value="rSAP" />
+ <xsd:enumeration value="SYNCH" />
+ <xsd:enumeration value="VDP" />
+ <xsd:enumeration value="WAPB" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="gl-version">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the OpenGL version supported for this release.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:decimal">
+ <xsd:pattern value="[0-9]\.[0-9]" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="gl-extensions">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies all of the supported OpenGL extensions for
+ this release.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:list itemType="xsd:NMTOKEN" />
+ </xsd:simpleType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="stateType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ The stateType contains the information for a given state of
+ of the device. States include things like portrait mode,
+ landscape with the keyboard exposed, etc. States can also
+ modify the hardware attributes of a device. For instance, if
+ sliding out the keyboard increased the available screen
+ real estate, you can define a new screenType to override the
+ default one defined in the device's hardwareType.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:token">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ A description of the defined state.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+
+ <xsd:element name="screen-orientation">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Defines the orientation of the screen. Use square if
+ the device's screen has equal height and width,
+ otherwise use landscape or portrait.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="portrait" />
+ <xsd:enumeration value="landscape" />
+ <xsd:enumeration value="square" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="keyboard-state">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Defines the state of the keyboard. If the device has no
+ keyboard use keysoft, otherwise use keysexposed or keyshidden.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="keyssoft" />
+ <xsd:enumeration value="keyshidden" />
+ <xsd:enumeration value="keysexposed" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+ <xsd:element name="nav-state">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Defines the state of the primary non-touchscreen
+ navigation hardware on the devices. If the device
+ doesn't have non-touchscreen navigation hardware use
+ nonav, otherwise use navexposed or navhidden.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="nonav" />
+ <xsd:enumeration value="navhidden" />
+ <xsd:enumeration value="navexposed" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+ <xsd:element name="screen" type="c:screenType" minOccurs="0" />
+ <xsd:element name="networking" type="c:networkingType"
+ minOccurs="0" />
+ <xsd:element name="sensors" type="c:sensorsType" minOccurs="0" />
+ <xsd:element name="mic" type="c:micType" minOccurs="0" />
+ <xsd:element name="camera" type="c:cameraType"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="keyboard" type="c:keyboardType" minOccurs="0" />
+ <xsd:element name="nav" type="c:navType" minOccurs="0" />
+ <xsd:element name="ram" type="c:ramType" minOccurs="0" />
+ <xsd:element name="buttons" type="c:buttonsType" minOccurs="0" />
+ <xsd:element name="internal-storage" type="c:internalStorageType"
+ minOccurs="0" />
+ <xsd:element name="removable-storage" type="c:removableStorageType"
+ minOccurs="0" />
+ <xsd:element name="cpu" type="c:cpuType" minOccurs="0" />
+ <xsd:element name="gpu" type="c:gpuType" minOccurs="0" />
+ <xsd:element name="abi" type="c:abiType" minOccurs="0" />
+ <xsd:element name="dock" type="c:dockType" minOccurs="0" />
+ <xsd:element name="plugged-in" type="c:pluggedInType"
+ minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:token" />
+ <xsd:attribute name="default" use="optional" type="xsd:boolean" />
+ </xsd:complexType>
+
+ <xsd:complexType name="metaType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Details where more device information can be found, such as
+ icons and frame images.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="icons" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Contains the relative paths to the icon files for this
+ device.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="sixty-four" type="xsd:normalizedString">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Relative path for the 64x64 icon.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="sixteen" type="xsd:normalizedString"
+ minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Relative path for the 16x16 icon.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="frame" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Contains information about the frame for the device.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="path"
+ type="xsd:normalizedString">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ The relative path to the emulator frame for
+ the device.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="portrait-x-offset"
+ type="xsd:nonNegativeInteger">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ The offset for the frame in the x direction,
+ in portrait mode.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="portrait-y-offset"
+ type="xsd:nonNegativeInteger">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ The offset for the frame in the y direction,
+ in portrait mode.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="landscape-x-offset"
+ type="xsd:nonNegativeInteger">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ The offset for the frame in the x direction,
+ in landscape mode.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="landscape-y-offset"
+ type="xsd:nonNegativeInteger">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ The offset for the frame in the y direction,
+ in landscape mode.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="screenType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Contains the specifications for the device's screen.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="screen-size">
+ <xsd:simpleType>
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the class of the screen.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="small" />
+ <xsd:enumeration value="normal" />
+ <xsd:enumeration value="large" />
+ <xsd:enumeration value="xlarge" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="diagonal-length">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the diagonal length of the screen in inches.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:decimal">
+ <!-- Negative lengths are not valid -->
+ <xsd:minInclusive value="0" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="pixel-density">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the screen density of the device. The
+ medium density of traditional HVGA screens (mdpi)
+ is defined to be approximately 160dpi; low density
+ (ldpi) is 120, and high density (hdpi) is 240. There
+ is thus a 4:3 scaling factor between each density,
+ so a 9x9 bitmap in ldpi would be 12x12 in mdpi and
+ 16x16 in hdpi.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="ldpi" />
+ <xsd:enumeration value="mdpi" />
+ <xsd:enumeration value="tvdpi" />
+ <xsd:enumeration value="hdpi" />
+ <xsd:enumeration value="xhdpi" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="screen-ratio">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies whether the configuration is for a taller or
+ wider than traditional screen. This is based purely on
+ the aspect ratio of the screen: QVGA, HVGA, and VGA are
+ notlong; WQVGA, WVGA, FWVGA are long. Note that long may
+ mean either wide or tall, depending on the current
+ orientation.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="notlong" />
+ <xsd:enumeration value="long" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="dimensions">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the device screen resolution in pixels.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="x-dimension">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the x-dimension's resolution in
+ pixels.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:positiveInteger" />
+ </xsd:simpleType>
+ </xsd:element>
+ <xsd:element name="y-dimension">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the y-dimension's resolution in
+ pixels.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:positiveInteger" />
+ </xsd:simpleType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="xdpi">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the actual density in X of the device screen.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:decimal">
+ <!-- Negative DPIs are not valid -->
+ <xsd:minInclusive value="0" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="ydpi">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the actual density in Y of the device screen.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:decimal">
+ <!-- Negative DPIs are not valid -->
+ <xsd:minInclusive value="0" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="touch">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the touch properties of the device.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="multitouch">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the multitouch capabilities of the
+ device. This can be none if multitouch is
+ not supported, basic if the device can track
+ only basic two finger gestures, distinct if
+ the device can track two or more fingers
+ simultaneously, or jazz-hands if the device
+ can track 5 or more fingers simultaneously.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="none" />
+ <xsd:enumeration value="basic" />
+ <xsd:enumeration value="distinct" />
+ <xsd:enumeration value="jazz-hands" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="mechanism">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the mechanism the device was
+ created for.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="notouch" />
+ <xsd:enumeration value="stylus" />
+ <xsd:enumeration value="finger" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="screen-type">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the type of touch screen on the
+ device.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="notouch" />
+ <xsd:enumeration value="capacitive" />
+ <xsd:enumeration value="resistive" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:simpleType name="networkingType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the available networking hardware.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="NFC" />
+ <xsd:enumeration value="Bluetooth" />
+ <xsd:enumeration value="Wifi" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="sensorsType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the available sensors.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="Accelerometer" />
+ <xsd:enumeration value="Barometer" />
+ <xsd:enumeration value="Compass" />
+ <xsd:enumeration value="GPS" />
+ <xsd:enumeration value="Gyroscope" />
+ <xsd:enumeration value="LightSensor" />
+ <xsd:enumeration value="ProximitySensor" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="micType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies whether the device has a mic or not.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:boolean" />
+ </xsd:simpleType>
+
+ <xsd:complexType name="cameraType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the attributes of the camera.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="location">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the location of the camera.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="front" />
+ <xsd:enumeration value="back" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="autofocus" type="xsd:boolean">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies whether the camera can autofocus
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+
+ <xsd:element name="flash" type="xsd:boolean">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies whether the camera has flash.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:simpleType name="keyboardType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the type of keyboard on the device.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="qwerty" />
+ <xsd:enumeration value="12key" />
+ <xsd:enumeration value="nokeys" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="navType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the primary non-touchscreen navigation
+ hardware on the device.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="dpad" />
+ <xsd:enumeration value="trackball" />
+ <xsd:enumeration value="wheel" />
+ <xsd:enumeration value="nonav" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="ramType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the amount of RAM on the device in the unit provided.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:positiveInteger">
+ <xsd:attribute name="unit" type="c:storageUnitType" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:simpleType name="buttonsType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies whether the device has physical (hard) buttons
+ (Home, Search, etc.), or uses soft buttons.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="hard" />
+ <xsd:enumeration value="soft" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="internalStorageType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ A list specifying the sizes of internal storage in
+ the device, in the storage size unit provided.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="c:storageListType">
+ <xsd:attribute name="unit" type="c:storageUnitType"
+ use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="removableStorageType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the range of available removable storage sizes
+ in the unit provided. A positive value indicates the device is
+ available with that storage size included while a zero value
+ indicates an empty storage slot.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="c:storageListType">
+ <xsd:attribute name="unit" type="c:storageUnitType"
+ use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:simpleType name="storageListType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Defines a list for storage configurations such as internal or
+ removable storage. A positive value indicates the the device
+ has a storage unit of that size, while a zero value indicates
+ there is an empty location for a storage unit (such as an empty
+ SD card slot).
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:nonNegativeInteger" />
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+ <xsd:simpleType name="gpuType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the device's GPU.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:minLength value="1" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="cpuType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the device's CPU.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:minLength value="1" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="abiType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies which ABIs the device conforms to.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="armeabi" />
+ <xsd:enumeration value="armeabi-v7a" />
+ <xsd:enumeration value="x86" />
+ <xsd:enumeration value="mips" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="dockType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the official docks available for the device.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="desk" />
+ <xsd:enumeration value="tv" />
+ <xsd:enumeration value="car" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="pluggedInType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies when the device is plugged in.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="always" />
+ <xsd:enumeration value="charge" />
+ <xsd:enumeration value="never" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="storageUnitType">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the unit of storage. This can be MiB, GiB, etc.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="B" />
+ <xsd:enumeration value="KiB" />
+ <xsd:enumeration value="MiB" />
+ <xsd:enumeration value="GiB" />
+ <xsd:enumeration value="TiB" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/device_validator/dvlib/tests/Android.mk b/device_validator/dvlib/tests/Android.mk
new file mode 100644
index 0000000..5094d7a
--- /dev/null
+++ b/device_validator/dvlib/tests/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2012 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_JAVA_RESOURCE_DIRS := src
+
+LOCAL_MODULE := dvlib-tests
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_JAVA_LIBRARIES := \
+ dvlib \
+ junit
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/DeviceSchemaTest.java b/device_validator/dvlib/tests/src/com/android/dvlib/DeviceSchemaTest.java
new file mode 100644
index 0000000..174f27c
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/DeviceSchemaTest.java
@@ -0,0 +1,311 @@
+package com.android.dvlib;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class DeviceSchemaTest extends TestCase {
+
+ private void checkFailure(Map<String, String> replacements, String regex) throws Exception {
+ // Generate XML stream with replacements
+ InputStream xmlStream = getReplacedStream(replacements);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ URL location = DeviceSchemaTest.class.getResource(".");
+ File parent = new File(location.toURI());
+ assertFalse(
+ "Validation Assertion Failed, XML failed to validate when it was expected to pass\n",
+ DeviceSchema.validate(xmlStream, baos, parent));
+ assertTrue(String.format("Regex Assertion Failed:\nExpected: %s\nActual: %s\n", regex, baos
+ .toString().trim()), baos.toString().trim().matches(regex));
+ }
+
+ private void checkFailure(String resource, String regex) throws Exception {
+ URL location = DeviceSchemaTest.class.getResource(resource);
+ File xml = new File(location.toURI());
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ assertFalse("Validation Assertion Failed, XML validated when it was expected to fail\n",
+ DeviceSchema.validate(new FileInputStream(xml), baos, xml.getParentFile()));
+ assertTrue(String.format("Regex Assertion Failed:\nExpected: %s\nActual: %s\n", regex, baos
+ .toString().trim()), baos.toString().trim().matches(regex));
+ }
+
+ private void checkSuccess(Map<String, String> replacements) throws Exception {
+ InputStream xmlStream = getReplacedStream(replacements);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ URL location = DeviceSchemaTest.class.getResource(".");
+ File parent = new File(location.toURI());
+ assertTrue(DeviceSchema.validate(xmlStream, baos, parent));
+ assertTrue(baos.toString().trim().matches(""));
+ }
+
+ private InputStream getReplacedStream(Map<String, String> replacements) throws Exception {
+ URL location = DeviceSchema.class.getResource("devices_minimal.xml");
+ File xml = new File(location.toURI());
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ SAXParser parser = factory.newSAXParser();
+ ReplacementHandler replacer = new ReplacementHandler(replacements);
+ parser.parse(xml, replacer);
+ Document doc = replacer.getGeneratedDocument();
+ Transformer tf = TransformerFactory.newInstance().newTransformer();
+ // Add indents so we're closer to user generated output
+ tf.setOutputProperty(OutputKeys.INDENT, "yes");
+ DOMSource source = new DOMSource(doc);
+ StringWriter out = new StringWriter();
+ StreamResult result = new StreamResult(out);
+ tf.transform(source, result);
+ return new ByteArrayInputStream(out.toString().getBytes("UTF-8"));
+ }
+
+ public void testValidXml() throws Exception {
+ URL location = DeviceSchemaTest.class.getResource("devices.xml");
+ File xml = new File(location.toURI());
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ boolean result = DeviceSchema.validate(new FileInputStream(xml), baos, xml.getParentFile());
+ String output = baos.toString().trim();
+ assertTrue(
+ String.format(
+ "Validation Assertion Failed, XML failed to validate when it was expected to pass\n%s\n",output), result);
+ assertTrue(String.format("Regex Assertion Failed\nExpected No Output\nActual: %s\n", baos
+ .toString().trim()), baos.toString().trim().matches(""));
+ }
+
+ public void testNoHardware() throws Exception {
+ String regex = "Error: cvc-complex-type.2.4.a: Invalid content was found starting with "
+ + "element 'd:software'.*";
+ checkFailure("devices_no_hardware.xml", regex);
+ }
+
+ public void testNoSoftware() throws Exception {
+ String regex = "Error: cvc-complex-type.2.4.a: Invalid content was found starting with "
+ + "element 'd:state'.*";
+ checkFailure("devices_no_software.xml", regex);
+ }
+
+ public void testNoDefault() throws Exception {
+ String regex = "Error: No default state for device Galaxy Nexus.*";
+ checkFailure("devices_no_default.xml", regex);
+ }
+
+ public void testTooManyDefaults() throws Exception {
+ String regex = "Error: More than one default state for device Galaxy Nexus.*";
+ checkFailure("devices_too_many_defaults.xml", regex);
+ }
+
+ public void testNoStates() throws Exception {
+ String regex = "Error: cvc-complex-type.2.4.b: The content of element 'd:device' is not "
+ + "complete.*\nError: No default state for device Galaxy Nexus.*";
+ checkFailure("devices_no_states.xml", regex);
+ }
+
+ public void testBadMechanism() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_MECHANISM, "fanger");
+ checkFailure(replacements, "Error: cvc-enumeration-valid: Value 'fanger' is not "
+ + "facet-valid.*\nError: cvc-type.3.1.3: The value 'fanger' of element "
+ + "'d:mechanism' is not valid.*");
+ }
+
+ public void testNegativeXdpi() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_XDPI, "-1.0");
+ checkFailure(replacements, "Error: cvc-minInclusive-valid: Value '-1.0'.*\n"
+ + "Error: cvc-type.3.1.3: The value '-1.0' of element 'd:xdpi' is not valid.*");
+ }
+
+ public void testNegativeYdpi() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_YDPI, "-1");
+ checkFailure(replacements, "Error: cvc-minInclusive-valid: Value '-1'.*\n"
+ + "Error: cvc-type.3.1.3: The value '-1' of element 'd:ydpi' is not valid.*");
+
+ }
+
+ public void testNegativeDiagonalLength() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_DIAGONAL_LENGTH, "-1.0");
+
+ checkFailure(replacements, "Error: cvc-minInclusive-valid: Value '-1.0'.*\n"
+ + "Error: cvc-type.3.1.3: The value '-1.0' of element 'd:diagonal-length'.*");
+
+ }
+
+ public void testInvalidOpenGLVersion() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_GL_VERSION, "2");
+ checkFailure(replacements, "Error: cvc-pattern-valid: Value '2' is not facet-valid.*\n"
+ + "Error: cvc-type.3.1.3: The value '2' of element 'd:gl-version' is not valid.*");
+ }
+
+ public void testInvalidIconTypes() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_SIXTEEN, "extras/sixteen.jpeg");
+ replacements.put(DeviceSchema.NODE_SIXTY_FOUR, "extras/sixtyfour.jpeg");
+ replacements.put(DeviceSchema.NODE_PATH, "extras/frame.jpeg");
+ checkFailure(replacements, "Error: extras/sixtyfour.jpeg is not a valid file type.\n"
+ + "Error: extras/sixteen.jpeg is not a valid file type.\n"
+ + "Error: extras/frame.jpeg is not a valid file type.");
+ }
+
+ public void testMissingIcons() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_SIXTEEN, "extras/missing");
+ replacements.put(DeviceSchema.NODE_SIXTY_FOUR, "extras/missing");
+ replacements.put(DeviceSchema.NODE_PATH, "extras/missing");
+ checkFailure(replacements, "Error: extras/missing is not a valid path.\n"
+ + "Error: extras/missing is not a valid path.\n"
+ + "Error: extras/missing is not a valid path.");
+ }
+
+ public void testEmptyOpenGLExtensions() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_GL_EXTENSIONS, "");
+ checkSuccess(replacements);
+ }
+
+ public void testEmptySensors() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_SENSORS, "");
+ checkSuccess(replacements);
+ }
+
+ public void testEmptyNetworking() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_NETWORKING, "");
+ checkSuccess(replacements);
+ }
+
+ public void testEmptyCpu() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_CPU, "");
+ checkFailure(replacements, "Error: cvc-minLength-valid: Value '' with length = '0'.*\n"
+ + "Error: cvc-type.3.1.3: The value '' of element 'd:cpu' is not valid.*");
+ }
+
+ public void testEmptyGpu() throws Exception {
+ Map<String, String> replacements = new HashMap<String, String>();
+ replacements.put(DeviceSchema.NODE_GPU, "");
+ checkFailure(replacements, "Error: cvc-minLength-valid: Value '' with length = '0'.*\n"
+ + "Error: cvc-type.3.1.3: The value '' of element 'd:gpu' is not valid.*");
+ }
+
+ /**
+ * Reads in a valid devices XML file and if an element tag is in the
+ * replacements map, it replaces its text content with the corresponding
+ * value. Note this has no concept of namespaces or hierarchy, so it will
+ * replace the contents any and all elements with the specified tag name.
+ */
+ private static class ReplacementHandler extends DefaultHandler {
+ private Element mCurrElement = null;
+ private Document mDocument;
+ private final Stack<Element> mElementStack = new Stack<Element>();
+ private final Map<String, String> mPrefixes = new HashMap<String, String>();
+ private final Map<String, String> mReplacements;
+ private final StringBuilder mStringAccumulator = new StringBuilder();
+
+ public ReplacementHandler(Map<String, String> replacements) {
+ mReplacements = replacements;
+ }
+
+ @Override
+ public void startDocument() {
+ try {
+ mDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ } catch (ParserConfigurationException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String name, Attributes attributes) {
+ Element element = mDocument.createElement(name);
+ for (int i = 0; i < attributes.getLength(); i++) {
+ element.setAttribute(attributes.getQName(i), attributes.getValue(i));
+ }
+ for (String key : mPrefixes.keySet()) {
+ element.setAttribute(XMLConstants.XMLNS_ATTRIBUTE + ":" + key, mPrefixes.get(key));
+ }
+ mPrefixes.clear();
+ if (mCurrElement != null) {
+ mElementStack.push(mCurrElement);
+ }
+ mCurrElement = element;
+ }
+
+ @Override
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ mPrefixes.put(prefix, uri);
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) {
+ mStringAccumulator.append(ch, start, length);
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String name) throws SAXException {
+ if (mReplacements.containsKey(localName)) {
+ mCurrElement.appendChild(mDocument.createTextNode(mReplacements.get(localName)));
+ } else {
+ String content = mStringAccumulator.toString().trim();
+ if (!content.isEmpty()) {
+ mCurrElement.appendChild(mDocument.createTextNode(content));
+ }
+ }
+
+ if (mElementStack.empty()) {
+ mDocument.appendChild(mCurrElement);
+ mCurrElement = null;
+ } else {
+ Element parent = mElementStack.pop();
+ parent.appendChild(mCurrElement);
+ mCurrElement = parent;
+ }
+ mStringAccumulator.setLength(0);
+ }
+
+ @Override
+ public void error(SAXParseException e) {
+ fail(e.getMessage());
+ }
+
+ @Override
+ public void fatalError(SAXParseException e) {
+ fail(e.getMessage());
+ }
+
+ public Document getGeneratedDocument() {
+ return mDocument;
+ }
+
+ }
+}
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices.xml
new file mode 100644
index 0000000..aeb0f04
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices.xml
@@ -0,0 +1,290 @@
+<?xml version="1.0"?>
+<d:devices
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:d="http://schemas.android.com/sdk/devices/1">
+
+ <d:device>
+ <d:name>
+ Galaxy Nexus
+ </d:name>
+ <d:manufacturer>
+ Samsung
+ </d:manufacturer>
+ <d:meta>
+ <d:icons>
+ <d:sixty-four>
+ extras/sixtyfour.png
+ </d:sixty-four>
+ <d:sixteen>
+ extras/sixteen.png
+ </d:sixteen>
+ </d:icons>
+ <d:frame>
+ <d:path>
+ extras/frame.png
+ </d:path>
+ <d:portrait-x-offset>0</d:portrait-x-offset>
+ <d:portrait-y-offset>0</d:portrait-y-offset>
+ <d:landscape-x-offset>0</d:landscape-x-offset>
+ <d:landscape-y-offset>0</d:landscape-y-offset>
+ </d:frame>
+ </d:meta>
+ <d:hardware>
+ <d:screen>
+ <d:screen-size>normal</d:screen-size>
+ <d:diagonal-length>4.65</d:diagonal-length> <!-- In inches -->
+ <d:pixel-density>xhdpi</d:pixel-density>
+ <d:screen-ratio>long</d:screen-ratio>
+ <d:dimensions>
+ <d:x-dimension>720</d:x-dimension>
+ <d:y-dimension>1280</d:y-dimension>
+ </d:dimensions>
+ <d:xdpi>316</d:xdpi>
+ <d:ydpi>316</d:ydpi>
+ <d:touch>
+ <d:multitouch>jazz-hands</d:multitouch>
+ <d:mechanism>finger</d:mechanism>
+ <d:screen-type>capacitive</d:screen-type>
+ </d:touch>
+ </d:screen>
+ <d:networking>
+ Bluetooth
+ Wifi
+ NFC
+ </d:networking>
+ <d:sensors>
+ Accelerometer
+ Barometer
+ Gyroscope
+ Compass
+ GPS
+ ProximitySensor
+ </d:sensors>
+ <d:mic>true</d:mic>
+ <d:camera>
+ <d:location>front</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>false</d:flash>
+ </d:camera>
+ <d:camera>
+ <d:location>back</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>true</d:flash>
+ </d:camera>
+ <d:keyboard>nokeys</d:keyboard>
+ <d:nav>nonav</d:nav>
+ <d:ram unit="GiB">1</d:ram>
+ <d:buttons>soft</d:buttons>
+ <d:internal-storage unit="GiB">16</d:internal-storage>
+ <d:removable-storage unit="KiB"></d:removable-storage>
+ <d:cpu>OMAP 4460</d:cpu> <!-- cpu type (Tegra3) freeform -->
+ <d:gpu>PowerVR SGX540</d:gpu>
+ <d:abi>
+ armeabi
+ armeabi-v7a
+ </d:abi>
+ <!--dock (car, desk, tv, none)-->
+ <d:dock>
+ </d:dock>
+ <!-- plugged in (never, charge, always) -->
+ <d:plugged-in>charge</d:plugged-in>
+ </d:hardware>
+ <d:software>
+ <d:api-level>14-</d:api-level>
+ <d:live-wallpaper-support>true</d:live-wallpaper-support>
+ <d:bluetooth-profiles>
+ HSP
+ HFP
+ SPP
+ A2DP
+ AVRCP
+ OPP
+ PBAP
+ GAVDP
+ AVDTP
+ HID
+ HDP
+ PAN
+ </d:bluetooth-profiles>
+ <d:gl-version>2.0</d:gl-version>
+ <!--
+ These can be gotten via
+ javax.microedition.khronos.opengles.GL10.glGetString(GL10.GL_EXTENSIONS);
+ -->
+ <d:gl-extensions>
+ GL_EXT_discard_framebuffer
+ GL_EXT_multi_draw_arrays
+ GL_EXT_shader_texture_lod
+ GL_EXT_texture_format_BGRA8888
+ GL_IMG_multisampled_render_to_texture
+ GL_IMG_program_binary
+ GL_IMG_read_format
+ GL_IMG_shader_binary
+ GL_IMG_texture_compression_pvrtc
+ GL_IMG_texture_format_BGRA8888
+ GL_IMG_texture_npot
+ GL_OES_compressed_ETC1_RGB8_texture
+ GL_OES_depth_texture
+ GL_OES_depth24
+ GL_OES_EGL_image
+ GL_OES_EGL_image_external
+ GL_OES_egl_sync
+ GL_OES_element_index_uint
+ GL_OES_fragment_precision_high
+ GL_OES_get_program_binary
+ GL_OES_mapbuffer
+ GL_OES_packed_depth_stencil
+ GL_OES_required_internalformat
+ GL_OES_rgb8_rgba8
+ GL_OES_standard_derivatives
+ GL_OES_texture_float
+ GL_OES_texture_half_float
+ GL_OES_vertex_array_object
+ GL_OES_vertex_half_float
+ </d:gl-extensions>
+ </d:software>
+ <d:state name="Portrait" default="true">
+ <d:description>The phone in portrait view</d:description>
+ <d:screen-orientation>portrait</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ <d:state name="Landscape">
+ <d:description>The phone in landscape view</d:description>
+ <d:screen-orientation>landscape</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ </d:device>
+ <d:device>
+ <d:name>Droid</d:name>
+ <d:manufacturer>Motorola</d:manufacturer>
+ <d:hardware>
+ <d:screen>
+ <d:screen-size>normal</d:screen-size>
+ <d:diagonal-length>3.7</d:diagonal-length>
+ <d:pixel-density>hdpi</d:pixel-density>
+ <d:screen-ratio>long</d:screen-ratio>
+ <d:dimensions>
+ <d:x-dimension>480</d:x-dimension>
+ <d:y-dimension>854</d:y-dimension>
+ </d:dimensions>
+ <d:xdpi>265</d:xdpi>
+ <d:ydpi>265</d:ydpi>
+ <d:touch>
+ <d:multitouch>distinct</d:multitouch>
+ <d:mechanism>finger</d:mechanism>
+ <d:screen-type>capacitive</d:screen-type>
+ </d:touch>
+ </d:screen>
+ <d:networking>
+ Bluetooth
+ Wifi
+ NFC
+ </d:networking>
+ <d:sensors>
+ Accelerometer
+ Barometer
+ Compass
+ GPS
+ ProximitySensor
+ LightSensor
+ </d:sensors>
+ <d:mic>true</d:mic>
+ <d:camera>
+ <d:location>back</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>true</d:flash>
+ </d:camera>
+ <d:keyboard>qwerty</d:keyboard>
+ <d:nav>dpad</d:nav>
+ <d:ram unit="MiB">256</d:ram>
+ <d:buttons>hard</d:buttons>
+ <d:internal-storage unit="MiB">512</d:internal-storage>
+ <d:removable-storage unit="GiB">16</d:removable-storage>
+ <d:cpu>OMAP 3430</d:cpu>
+ <d:gpu>PowerVR SGX 53</d:gpu>
+ <d:abi>
+ armeabi
+ armeabi-v7a
+ </d:abi>
+ <d:dock>
+ car
+ desk
+ </d:dock>
+ <d:plugged-in>charge</d:plugged-in>
+ </d:hardware>
+ <d:software>
+ <d:api-level>5-8</d:api-level>
+ <d:live-wallpaper-support>false</d:live-wallpaper-support>
+ <d:bluetooth-profiles>
+ GAP
+ SPP
+ HSP
+ HFP
+ A2DP
+ AVRCP
+ SDAP
+ </d:bluetooth-profiles>
+ <d:gl-version>1.1</d:gl-version>
+ <!--
+ These can be gotten via
+ javax.microedition.khronos.opengles.GL10.glGetString(GL10.GL_EXTENSIONS);
+ -->
+ <d:gl-extensions>
+ GL_OES_byte_coordinates
+ GL_OES_fixed_point
+ GL_OES_single_precision
+ GL_OES_matrix_get
+ GL_OES_read_format
+ GL_OES_compressed_paletted_texture
+ GL_OES_point_sprite
+ GL_OES_point_size_array
+ GL_OES_matrix_palette
+ GL_OES_draw_texture
+ GL_OES_query_matrix
+ GL_OES_texture_env_crossbar
+ GL_OES_texture_mirrored_repeat
+ GL_OES_texture_cube_map
+ GL_OES_blend_subtract
+ GL_OES_blend_func_separate
+ GL_OES_blend_equation_separate
+ GL_OES_stencil_wrap
+ GL_OES_extended_matrix_palette
+ GL_OES_framebuffer_object
+ GL_OES_rgb8_rgba8
+ GL_OES_depth24
+ GL_OES_stencil8
+ GL_OES_compressed_ETC1_RGB8_texture
+ GL_OES_mapbuffer
+ GL_OES_EGL_image
+ GL_EXT_multi_draw_arrays
+ GL_OES_required_internalformat
+ GL_IMG_read_format
+ GL_IMG_texture_compression_pvrtc
+ GL_IMG_texture_format_BGRA8888
+ GL_EXT_texture_format_BGRA8888
+ GL_IMG_texture_stream
+ GL_IMG_vertex_program
+ </d:gl-extensions>
+ </d:software>
+ <d:state name="Portrait" default="true">
+ <d:description>The phone in portrait view</d:description>
+ <d:screen-orientation>portrait</d:screen-orientation>
+ <d:keyboard-state>keyshidden</d:keyboard-state>
+ <d:nav-state>navhidden</d:nav-state>
+ </d:state>
+ <d:state name="Landscape, closed">
+ <d:description>The phone in landscape view with the keyboard closed</d:description>
+ <d:screen-orientation>landscape</d:screen-orientation>
+ <d:keyboard-state>keyshidden</d:keyboard-state>
+ <d:nav-state>navhidden</d:nav-state>
+ </d:state>
+ <d:state name="Landscape, open">
+ <d:description>The phone in landscape view with the keyboard open</d:description>
+ <d:screen-orientation>landscape</d:screen-orientation>
+ <d:keyboard-state>keysexposed</d:keyboard-state>
+ <d:nav-state>navexposed</d:nav-state>
+ </d:state>
+ </d:device>
+</d:devices>
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_minimal.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_minimal.xml
new file mode 100644
index 0000000..71ab61a
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_minimal.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0"?>
+<d:devices
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:d="http://schemas.android.com/sdk/devices/1">
+
+ <d:device>
+ <d:name>
+ Galaxy Nexus
+ </d:name>
+ <d:manufacturer>
+ Samsung
+ </d:manufacturer>
+ <d:meta>
+ <d:icons>
+ <d:sixty-four>
+ extras/sixtyfour.png
+ </d:sixty-four>
+ <d:sixteen>
+ extras/sixteen.png
+ </d:sixteen>
+ </d:icons>
+ <d:frame>
+ <d:path>
+ extras/frame.png
+ </d:path>
+ <d:portrait-x-offset>0</d:portrait-x-offset>
+ <d:portrait-y-offset>0</d:portrait-y-offset>
+ <d:landscape-x-offset>0</d:landscape-x-offset>
+ <d:landscape-y-offset>0</d:landscape-y-offset>
+ </d:frame>
+ </d:meta>
+ <d:hardware>
+ <d:screen>
+ <d:screen-size>normal</d:screen-size>
+ <d:diagonal-length>4.65</d:diagonal-length> <!-- In inches -->
+ <d:pixel-density>xhdpi</d:pixel-density>
+ <d:screen-ratio>long</d:screen-ratio>
+ <d:dimensions>
+ <d:x-dimension>720</d:x-dimension>
+ <d:y-dimension>1280</d:y-dimension>
+ </d:dimensions>
+ <d:xdpi>316</d:xdpi>
+ <d:ydpi>316</d:ydpi>
+ <d:touch>
+ <d:multitouch>jazz-hands</d:multitouch>
+ <d:mechanism>finger</d:mechanism>
+ <d:screen-type>capacitive</d:screen-type>
+ </d:touch>
+ </d:screen>
+ <d:networking>
+ Bluetooth
+ Wifi
+ NFC
+ </d:networking>
+ <d:sensors>
+ Accelerometer
+ Barometer
+ Gyroscope
+ Compass
+ GPS
+ ProximitySensor
+ </d:sensors>
+ <d:mic>true</d:mic>
+ <d:camera>
+ <d:location>front</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>false</d:flash>
+ </d:camera>
+ <d:camera>
+ <d:location>back</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>true</d:flash>
+ </d:camera>
+ <d:keyboard>nokeys</d:keyboard>
+ <d:nav>nonav</d:nav>
+ <d:ram unit="GiB">1</d:ram>
+ <d:buttons>soft</d:buttons>
+ <d:internal-storage unit="GiB">16</d:internal-storage>
+ <d:removable-storage unit="KiB"></d:removable-storage>
+ <d:cpu>OMAP 4460</d:cpu> <!-- cpu type (Tegra3) freeform -->
+ <d:gpu>PowerVR SGX540</d:gpu>
+ <d:abi>
+ armeabi
+ armeabi-v7a
+ </d:abi>
+ <!--dock (car, desk, tv, none)-->
+ <d:dock>
+ </d:dock>
+ <!-- plugged in (never, charge, always) -->
+ <d:plugged-in>charge</d:plugged-in>
+ </d:hardware>
+ <d:software>
+ <d:api-level>15</d:api-level>
+ <d:live-wallpaper-support>true</d:live-wallpaper-support>
+ <d:bluetooth-profiles>
+ HSP
+ HFP
+ SPP
+ A2DP
+ AVRCP
+ OPP
+ PBAP
+ GAVDP
+ AVDTP
+ HID
+ HDP
+ PAN
+ </d:bluetooth-profiles>
+ <d:gl-version>2.0</d:gl-version>
+ <d:gl-extensions>
+ GL_EXT_discard_framebuffer
+ GL_EXT_multi_draw_arrays
+ GL_EXT_shader_texture_lod
+ GL_EXT_texture_format_BGRA8888
+ GL_IMG_multisampled_render_to_texture
+ GL_IMG_program_binary
+ GL_IMG_read_format
+ GL_IMG_shader_binary
+ GL_IMG_texture_compression_pvrtc
+ GL_IMG_texture_format_BGRA8888
+ GL_IMG_texture_npot
+ GL_OES_compressed_ETC1_RGB8_texture
+ GL_OES_depth_texture
+ GL_OES_depth24
+ GL_OES_EGL_image
+ GL_OES_EGL_image_external
+ GL_OES_egl_sync
+ GL_OES_element_index_uint
+ GL_OES_fragment_precision_high
+ GL_OES_get_program_binary
+ GL_OES_mapbuffer
+ GL_OES_packed_depth_stencil
+ GL_OES_required_internalformat
+ GL_OES_rgb8_rgba8
+ GL_OES_standard_derivatives
+ GL_OES_texture_float
+ GL_OES_texture_half_float
+ GL_OES_vertex_array_object
+ GL_OES_vertex_half_float
+ </d:gl-extensions>
+ </d:software>
+ <d:state name="Portrait" default="true">
+ <d:description>The phone in portrait view</d:description>
+ <d:screen-orientation>portrait</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ <d:state name="Landscape">
+ <d:description>The phone in landscape view</d:description>
+ <d:screen-orientation>landscape</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ </d:device>
+</d:devices>
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_default.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_default.xml
new file mode 100644
index 0000000..3ebcedb
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_default.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0"?>
+<d:devices
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:d="http://schemas.android.com/sdk/devices/1">
+
+ <d:device>
+ <d:name>
+ Galaxy Nexus
+ </d:name>
+ <d:manufacturer>
+ Samsung
+ </d:manufacturer>
+ <d:hardware>
+ <d:screen>
+ <d:screen-size>normal</d:screen-size>
+ <d:diagonal-length>4.65</d:diagonal-length> <!-- In inches -->
+ <d:pixel-density>xhdpi</d:pixel-density>
+ <d:screen-ratio>long</d:screen-ratio>
+ <d:dimensions>
+ <d:x-dimension>720</d:x-dimension>
+ <d:y-dimension>1280</d:y-dimension>
+ </d:dimensions>
+ <d:xdpi>316</d:xdpi>
+ <d:ydpi>316</d:ydpi>
+ <d:touch>
+ <d:multitouch>jazz-hands</d:multitouch>
+ <d:mechanism>finger</d:mechanism>
+ <d:screen-type>capacitive</d:screen-type>
+ </d:touch>
+ </d:screen>
+ <d:networking>
+ Bluetooth
+ Wifi
+ NFC
+ </d:networking>
+ <d:sensors>
+ Accelerometer
+ Barometer
+ Gyroscope
+ Compass
+ GPS
+ ProximitySensor
+ </d:sensors>
+ <d:mic>true</d:mic>
+ <d:camera>
+ <d:location>front</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>false</d:flash>
+ </d:camera>
+ <d:camera>
+ <d:location>back</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>true</d:flash>
+ </d:camera>
+ <d:keyboard>nokeys</d:keyboard>
+ <d:nav>nonav</d:nav>
+ <d:ram unit="GiB">1</d:ram>
+ <d:buttons>soft</d:buttons>
+ <d:internal-storage unit="GiB">16</d:internal-storage>
+ <d:removable-storage unit="KiB"></d:removable-storage>
+ <d:cpu>OMAP 4460</d:cpu> <!-- cpu type (Tegra3) freeform -->
+ <d:gpu>PowerVR SGX540</d:gpu>
+ <d:abi>
+ armeabi
+ armeabi-v7a
+ </d:abi>
+ <!--dock (car, desk, tv, none)-->
+ <d:dock>
+ </d:dock>
+ <!-- plugged in (never, charge, always) -->
+ <d:plugged-in>charge</d:plugged-in>
+ </d:hardware>
+ <d:software>
+ <d:api-level>14</d:api-level>
+ <d:live-wallpaper-support>true</d:live-wallpaper-support>
+ <d:bluetooth-profiles>
+ HSP
+ HFP
+ SPP
+ A2DP
+ AVRCP
+ OPP
+ PBAP
+ GAVDP
+ AVDTP
+ HID
+ HDP
+ PAN
+ </d:bluetooth-profiles>
+ <d:gl-version>2.0</d:gl-version>
+ <!--
+ These can be gotten via
+ javax.microedition.khronos.opengles.GL10.glGetString(GL10.GL_EXTENSIONS);
+ -->
+ <d:gl-extensions>
+ GL_EXT_discard_framebuffer
+ GL_EXT_multi_draw_arrays
+ GL_EXT_shader_texture_lod
+ GL_EXT_texture_format_BGRA8888
+ GL_IMG_multisampled_render_to_texture
+ GL_IMG_program_binary
+ GL_IMG_read_format
+ GL_IMG_shader_binary
+ GL_IMG_texture_compression_pvrtc
+ GL_IMG_texture_format_BGRA8888
+ GL_IMG_texture_npot
+ GL_OES_compressed_ETC1_RGB8_texture
+ GL_OES_depth_texture
+ GL_OES_depth24
+ GL_OES_EGL_image
+ GL_OES_EGL_image_external
+ GL_OES_egl_sync
+ GL_OES_element_index_uint
+ GL_OES_fragment_precision_high
+ GL_OES_get_program_binary
+ GL_OES_mapbuffer
+ GL_OES_packed_depth_stencil
+ GL_OES_required_internalformat
+ GL_OES_rgb8_rgba8
+ GL_OES_standard_derivatives
+ GL_OES_texture_float
+ GL_OES_texture_half_float
+ GL_OES_vertex_array_object
+ GL_OES_vertex_half_float
+ </d:gl-extensions>
+ </d:software>
+ <d:state name="Portrait">
+ <d:description>The phone in portrait view</d:description>
+ <d:screen-orientation>portrait</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ </d:device>
+</d:devices>
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_hardware.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_hardware.xml
new file mode 100644
index 0000000..a5c3da1
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_hardware.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<d:devices
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:d="http://schemas.android.com/sdk/devices/1">
+
+ <d:device>
+ <d:name>
+ Galaxy Nexus
+ </d:name>
+ <d:manufacturer>
+ Samsung
+ </d:manufacturer>
+ <d:software>
+ <d:api-level>14</d:api-level>
+ <d:live-wallpaper-support>true</d:live-wallpaper-support>
+ <d:bluetooth-profiles>
+ HSP
+ HFP
+ SPP
+ A2DP
+ AVRCP
+ OPP
+ PBAP
+ GAVDP
+ AVDTP
+ HID
+ HDP
+ PAN
+ </d:bluetooth-profiles>
+ <d:gl-version>2.0</d:gl-version>
+ <!--
+ These can be gotten via
+ javax.microedition.khronos.opengles.GL10.glGetString(GL10.GL_EXTENSIONS);
+ -->
+ <d:gl-extensions>
+ GL_EXT_discard_framebuffer
+ GL_EXT_multi_draw_arrays
+ GL_EXT_shader_texture_lod
+ GL_EXT_texture_format_BGRA8888
+ GL_IMG_multisampled_render_to_texture
+ GL_IMG_program_binary
+ GL_IMG_read_format
+ GL_IMG_shader_binary
+ GL_IMG_texture_compression_pvrtc
+ GL_IMG_texture_format_BGRA8888
+ GL_IMG_texture_npot
+ GL_OES_compressed_ETC1_RGB8_texture
+ GL_OES_depth_texture
+ GL_OES_depth24
+ GL_OES_EGL_image
+ GL_OES_EGL_image_external
+ GL_OES_egl_sync
+ GL_OES_element_index_uint
+ GL_OES_fragment_precision_high
+ GL_OES_get_program_binary
+ GL_OES_mapbuffer
+ GL_OES_packed_depth_stencil
+ GL_OES_required_internalformat
+ GL_OES_rgb8_rgba8
+ GL_OES_standard_derivatives
+ GL_OES_texture_float
+ GL_OES_texture_half_float
+ GL_OES_vertex_array_object
+ GL_OES_vertex_half_float
+ </d:gl-extensions>
+ </d:software>
+ <d:state name="Portrait" default="true">
+ <d:description>The phone in portrait view</d:description>
+ <d:screen-orientation>portrait</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ <d:state name="Landscape">
+ <d:description>The phone in landscape view</d:description>
+ <d:screen-orientation>landscape</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ </d:device>
+</d:devices>
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_software.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_software.xml
new file mode 100644
index 0000000..899110a
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_software.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<d:devices
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:d="http://schemas.android.com/sdk/devices/1">
+
+ <d:device>
+ <d:name>
+ Galaxy Nexus
+ </d:name>
+ <d:manufacturer>
+ Samsung
+ </d:manufacturer>
+ <d:hardware>
+ <d:screen>
+ <d:screen-size>normal</d:screen-size>
+ <d:diagonal-length>4.65</d:diagonal-length> <!-- In inches -->
+ <d:pixel-density>xhdpi</d:pixel-density>
+ <d:screen-ratio>long</d:screen-ratio>
+ <d:dimensions>
+ <d:x-dimension>720</d:x-dimension>
+ <d:y-dimension>1280</d:y-dimension>
+ </d:dimensions>
+ <d:xdpi>316</d:xdpi>
+ <d:ydpi>316</d:ydpi>
+ <d:touch>
+ <d:multitouch>jazz-hands</d:multitouch>
+ <d:mechanism>finger</d:mechanism>
+ <d:screen-type>capacitive</d:screen-type>
+ </d:touch>
+ </d:screen>
+ <d:networking>
+ Bluetooth
+ Wifi
+ NFC
+ </d:networking>
+ <d:sensors>
+ Accelerometer
+ Barometer
+ Gyroscope
+ Compass
+ GPS
+ ProximitySensor
+ </d:sensors>
+ <d:mic>true</d:mic>
+ <d:camera>
+ <d:location>front</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>false</d:flash>
+ </d:camera>
+ <d:camera>
+ <d:location>back</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>true</d:flash>
+ </d:camera>
+ <d:keyboard>nokeys</d:keyboard>
+ <d:nav>nonav</d:nav>
+ <d:ram unit="GiB">1</d:ram>
+ <d:buttons>soft</d:buttons>
+ <d:internal-storage unit="GiB">16</d:internal-storage>
+ <d:removable-storage unit="KiB"></d:removable-storage>
+ <d:cpu>OMAP 4460</d:cpu> <!-- cpu type (Tegra3) freeform -->
+ <d:gpu>PowerVR SGX540</d:gpu>
+ <d:abi>
+ armeabi
+ armeabi-v7a
+ </d:abi>
+ <!--dock (car, desk, tv, none)-->
+ <d:dock>
+ </d:dock>
+ <!-- plugged in (never, charge, always) -->
+ <d:plugged-in>charge</d:plugged-in>
+ </d:hardware>
+ <d:state name="Portrait" default="true">
+ <d:description>The phone in portrait view</d:description>
+ <d:screen-orientation>portrait</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ </d:device>
+</d:devices>
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_states.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_states.xml
new file mode 100644
index 0000000..c4955b4
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_states.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0"?>
+<d:devices
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:d="http://schemas.android.com/sdk/devices/1">
+
+ <d:device>
+ <d:name>
+ Galaxy Nexus
+ </d:name>
+ <d:manufacturer>
+ Samsung
+ </d:manufacturer>
+ <d:hardware>
+ <d:screen>
+ <d:screen-size>normal</d:screen-size>
+ <d:diagonal-length>4.65</d:diagonal-length> <!-- In inches -->
+ <d:pixel-density>xhdpi</d:pixel-density>
+ <d:screen-ratio>long</d:screen-ratio>
+ <d:dimensions>
+ <d:x-dimension>720</d:x-dimension>
+ <d:y-dimension>1280</d:y-dimension>
+ </d:dimensions>
+ <d:xdpi>316</d:xdpi>
+ <d:ydpi>316</d:ydpi>
+ <d:touch>
+ <d:multitouch>jazz-hands</d:multitouch>
+ <d:mechanism>finger</d:mechanism>
+ <d:screen-type>capacitive</d:screen-type>
+ </d:touch>
+ </d:screen>
+ <d:networking>
+ Bluetooth
+ Wifi
+ NFC
+ </d:networking>
+ <d:sensors>
+ Accelerometer
+ Barometer
+ Gyroscope
+ Compass
+ GPS
+ ProximitySensor
+ </d:sensors>
+ <d:mic>true</d:mic>
+ <d:camera>
+ <d:location>front</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>false</d:flash>
+ </d:camera>
+ <d:camera>
+ <d:location>back</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>true</d:flash>
+ </d:camera>
+ <d:keyboard>nokeys</d:keyboard>
+ <d:nav>nonav</d:nav>
+ <d:ram unit="GiB">1</d:ram>
+ <d:buttons>soft</d:buttons>
+ <d:internal-storage unit="GiB">16</d:internal-storage>
+ <d:removable-storage unit="KiB"></d:removable-storage>
+ <d:cpu>OMAP 4460</d:cpu> <!-- cpu type (Tegra3) freeform -->
+ <d:gpu>PowerVR SGX540</d:gpu>
+ <d:abi>
+ armeabi
+ armeabi-v7a
+ </d:abi>
+ <!--dock (car, desk, tv, none)-->
+ <d:dock>
+ </d:dock>
+ <!-- plugged in (never, charge, always) -->
+ <d:plugged-in>charge</d:plugged-in>
+ </d:hardware>
+ <d:software>
+ <d:api-level>14</d:api-level>
+ <d:live-wallpaper-support>true</d:live-wallpaper-support>
+ <d:bluetooth-profiles>
+ HSP
+ HFP
+ SPP
+ A2DP
+ AVRCP
+ OPP
+ PBAP
+ GAVDP
+ AVDTP
+ HID
+ HDP
+ PAN
+ </d:bluetooth-profiles>
+ <d:gl-version>2.0</d:gl-version>
+ <!--
+ These can be gotten via
+ javax.microedition.khronos.opengles.GL10.glGetString(GL10.GL_EXTENSIONS);
+ -->
+ <d:gl-extensions>
+ GL_EXT_discard_framebuffer
+ GL_EXT_multi_draw_arrays
+ GL_EXT_shader_texture_lod
+ GL_EXT_texture_format_BGRA8888
+ GL_IMG_multisampled_render_to_texture
+ GL_IMG_program_binary
+ GL_IMG_read_format
+ GL_IMG_shader_binary
+ GL_IMG_texture_compression_pvrtc
+ GL_IMG_texture_format_BGRA8888
+ GL_IMG_texture_npot
+ GL_OES_compressed_ETC1_RGB8_texture
+ GL_OES_depth_texture
+ GL_OES_depth24
+ GL_OES_EGL_image
+ GL_OES_EGL_image_external
+ GL_OES_egl_sync
+ GL_OES_element_index_uint
+ GL_OES_fragment_precision_high
+ GL_OES_get_program_binary
+ GL_OES_mapbuffer
+ GL_OES_packed_depth_stencil
+ GL_OES_required_internalformat
+ GL_OES_rgb8_rgba8
+ GL_OES_standard_derivatives
+ GL_OES_texture_float
+ GL_OES_texture_half_float
+ GL_OES_vertex_array_object
+ GL_OES_vertex_half_float
+ </d:gl-extensions>
+ </d:software>
+ </d:device>
+</d:devices>
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_too_many_defaults.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_too_many_defaults.xml
new file mode 100644
index 0000000..a4e464c
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_too_many_defaults.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0"?>
+<d:devices
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:d="http://schemas.android.com/sdk/devices/1">
+
+ <d:device>
+ <d:name>
+ Galaxy Nexus
+ </d:name>
+ <d:manufacturer>
+ Samsung
+ </d:manufacturer>
+ <d:hardware>
+ <d:screen>
+ <d:screen-size>normal</d:screen-size>
+ <d:diagonal-length>4.65</d:diagonal-length> <!-- In inches -->
+ <d:pixel-density>xhdpi</d:pixel-density>
+ <d:screen-ratio>long</d:screen-ratio>
+ <d:dimensions>
+ <d:x-dimension>720</d:x-dimension>
+ <d:y-dimension>1280</d:y-dimension>
+ </d:dimensions>
+ <d:xdpi>316</d:xdpi>
+ <d:ydpi>316</d:ydpi>
+ <d:touch>
+ <d:multitouch>jazz-hands</d:multitouch>
+ <d:mechanism>finger</d:mechanism>
+ <d:screen-type>capacitive</d:screen-type>
+ </d:touch>
+ </d:screen>
+ <d:networking>
+ Bluetooth
+ Wifi
+ NFC
+ </d:networking>
+ <d:sensors>
+ Accelerometer
+ Barometer
+ Gyroscope
+ Compass
+ GPS
+ ProximitySensor
+ </d:sensors>
+ <d:mic>true</d:mic>
+ <d:camera>
+ <d:location>front</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>false</d:flash>
+ </d:camera>
+ <d:camera>
+ <d:location>back</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>true</d:flash>
+ </d:camera>
+ <d:keyboard>nokeys</d:keyboard>
+ <d:nav>nonav</d:nav>
+ <d:ram unit="GiB">1</d:ram>
+ <d:buttons>soft</d:buttons>
+ <d:internal-storage unit="GiB">16</d:internal-storage>
+ <d:removable-storage unit="KiB"></d:removable-storage>
+ <d:cpu>OMAP 4460</d:cpu> <!-- cpu type (Tegra3) freeform -->
+ <d:gpu>PowerVR SGX540</d:gpu>
+ <d:abi>
+ armeabi
+ armeabi-v7a
+ </d:abi>
+ <!--dock (car, desk, tv, none)-->
+ <d:dock>
+ </d:dock>
+ <!-- plugged in (never, charge, always) -->
+ <d:plugged-in>charge</d:plugged-in>
+ </d:hardware>
+ <d:software>
+ <d:api-level>14</d:api-level>
+ <d:live-wallpaper-support>true</d:live-wallpaper-support>
+ <d:bluetooth-profiles>
+ HSP
+ HFP
+ SPP
+ A2DP
+ AVRCP
+ OPP
+ PBAP
+ GAVDP
+ AVDTP
+ HID
+ HDP
+ PAN
+ </d:bluetooth-profiles>
+ <d:gl-version>2.0</d:gl-version>
+ <!--
+ These can be gotten via
+ javax.microedition.khronos.opengles.GL10.glGetString(GL10.GL_EXTENSIONS);
+ -->
+ <d:gl-extensions>
+ GL_EXT_discard_framebuffer
+ GL_EXT_multi_draw_arrays
+ GL_EXT_shader_texture_lod
+ GL_EXT_texture_format_BGRA8888
+ GL_IMG_multisampled_render_to_texture
+ GL_IMG_program_binary
+ GL_IMG_read_format
+ GL_IMG_shader_binary
+ GL_IMG_texture_compression_pvrtc
+ GL_IMG_texture_format_BGRA8888
+ GL_IMG_texture_npot
+ GL_OES_compressed_ETC1_RGB8_texture
+ GL_OES_depth_texture
+ GL_OES_depth24
+ GL_OES_EGL_image
+ GL_OES_EGL_image_external
+ GL_OES_egl_sync
+ GL_OES_element_index_uint
+ GL_OES_fragment_precision_high
+ GL_OES_get_program_binary
+ GL_OES_mapbuffer
+ GL_OES_packed_depth_stencil
+ GL_OES_required_internalformat
+ GL_OES_rgb8_rgba8
+ GL_OES_standard_derivatives
+ GL_OES_texture_float
+ GL_OES_texture_half_float
+ GL_OES_vertex_array_object
+ GL_OES_vertex_half_float
+ </d:gl-extensions>
+ </d:software>
+ <d:state name="Portrait" default="true">
+ <d:description>The phone in portrait view</d:description>
+ <d:screen-orientation>portrait</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ <d:state name="Landscape" default="true">
+ <d:description>The phone in landscape view</d:description>
+ <d:screen-orientation>landscape</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ </d:device>
+</d:devices>
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/extras/frame.jpeg b/device_validator/dvlib/tests/src/com/android/dvlib/extras/frame.jpeg
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/extras/frame.jpeg
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/extras/frame.png b/device_validator/dvlib/tests/src/com/android/dvlib/extras/frame.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/extras/frame.png
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixteen.jpeg b/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixteen.jpeg
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixteen.jpeg
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixteen.png b/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixteen.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixteen.png
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixtyfour.jpeg b/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixtyfour.jpeg
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixtyfour.jpeg
diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixtyfour.png b/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixtyfour.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/device_validator/dvlib/tests/src/com/android/dvlib/extras/sixtyfour.png