diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java index ae0bb5be7..69bf18b09 100755 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java @@ -94,8 +94,13 @@ public class LayoutConfigsXsd { public static final String NODE_SCREEN_DIMENSION = "screen-dimension"; //$NON-NLS-1$ + /** The screen-dimension element has 2 size element children. */ public static final String NODE_SIZE = "size"; //$NON-NLS-1$ + public static final String NODE_XPDI = "xdpi"; //$NON-NLS-1$ + + public static final String NODE_YDPI = "ydpi"; //$NON-NLS-1$ + /** * The "name" attribute, used by both the "device" and the "config" * elements. It represents the user-interface name of these objects. diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd index 476fce78e..49131fba6 100755 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd @@ -24,7 +24,7 @@ - + The "layout-configs" element is the root element of this schema. It must contain one or more "device" elements that each define the configurations @@ -41,7 +41,7 @@ - + A device element must contain at most one "default" element followed by one or more "config" elements. @@ -78,10 +78,14 @@ --> - + The parametersType define all the parameters that can happen either in a "default" element or in a named "config" element. Each parameter element can appear once at most. + + Parameters here are the same as those used to specify alternate Android + resources, as documented by + http://d.android.com/guide/topics/resources/resources-i18n.html#AlternateResources @@ -89,6 +93,11 @@ + + + Specifies that the configuration is for a particular class of screen. + + @@ -99,6 +108,14 @@ + + + Specifies that the configuration is for a taller/wider than traditional + screen. This is based purely on the aspect ration 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. + + @@ -108,6 +125,12 @@ + + + Specifies that the configuration is for a screen that is tall (port) or + wide (land). + + @@ -118,6 +141,17 @@ + + + Specifies the screen density the configuration is defined for. 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 is mdpi and 16x16 in hdpi. + The special nodpi density that can be used in resource qualifiers is not + a valid keyword here. + + @@ -128,6 +162,11 @@ + + + Specifies the touch type the configuration is defined for. + + @@ -138,6 +177,12 @@ + + + If your configuration uses a soft keyboard, use the keyssoft value. + If it doesn't and has a real keyboard, use keysexposed or keyshidden. + + @@ -148,6 +193,11 @@ + + + Specifies the primary text input method the configuration is designed for. + + @@ -158,6 +208,12 @@ + + + Specifies the primary non-touchscreen navigation method the configuration + is designed for. + + @@ -169,6 +225,11 @@ + + + Specifies the device screen resolution, in pixels. + + @@ -181,6 +242,33 @@ + + + + + Specifies the actual density in X of the device screen. + + + + + + + + + + + + + Specifies the actual density in Y of the device screen. + + + + + + + + + diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java index 45332f243..43b0507e3 100755 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java @@ -104,6 +104,42 @@ public class TestLayoutConfisXsd extends TestCase { // --- Helpers ------------ + /** An helper that validates a string against an expected regexp. */ + private void assertRegex(String expectedRegexp, String actualString) { + assertNotNull(actualString); + assertTrue( + String.format("Regexp Assertion Failed:\nExpected: %s\nActual: %s\n", + expectedRegexp, actualString), + actualString.matches(expectedRegexp)); + } + + public void checkFailure(String document, String regexp) throws Exception { + Source source = new StreamSource(new StringReader(document)); + + // don't capture the validator errors, we want it to fail and catch the exception + Validator validator = LayoutConfigsXsd.getValidator(null); + try { + validator.validate(source); + } catch (SAXParseException e) { + // We expect a parse expression referring to this grammar rule + assertRegex(regexp, e.getMessage()); + return; + } + // If we get here, the validator has not failed as we expected it to. + fail(); + } + + public void checkSuccess(String document) throws Exception { + Source source = new StreamSource(new StringReader(document)); + + CaptureErrorHandler handler = new CaptureErrorHandler(); + Validator validator = LayoutConfigsXsd.getValidator(null); + validator.validate(source); + handler.verify(); + } + + // --- Tests ------------ + /** Validate a valid sample using an InputStream */ public void testValidateLocalRepositoryFile() throws Exception { @@ -117,171 +153,180 @@ public class TestLayoutConfisXsd extends TestCase { handler.verify(); } - /** An helper that validates a string against an expected regexp. */ - private void assertRegex(String expectedRegexp, String actualString) { - assertNotNull(actualString); - assertTrue( - String.format("Regexp Assertion Failed:\nExpected: %s\nActual: %s\n", - expectedRegexp, actualString), - actualString.matches(expectedRegexp)); - } - - // --- Tests ------------ - /** A document should at least have a root to be valid */ public void testEmptyXml() throws Exception { - String document = ""; + checkFailure( + // document + "", - Source source = new StreamSource(new StringReader(document)); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = LayoutConfigsXsd.getValidator(handler); - - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect to get this specific exception message - assertRegex("Premature end of file.*", e.getMessage()); - return; - } - // We shouldn't get here - handler.verify(); - fail(); + // expected failure + "Premature end of file.*"); } /** A document with an unknown element. */ public void testUnknownContentXml() throws Exception { - String document = "" + - "" + - "" + - ""; + checkFailure( + // document + "" + + "" + + "" + + "", - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = LayoutConfigsXsd.getValidator(null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse expression referring to this grammar rule - assertRegex("cvc-complex-type.2.4.a: Invalid content was found.*", e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); + // expected failure + "cvc-complex-type.2.4.a: Invalid content was found.*"); } /** A document with an missing attribute in a device element. */ public void testIncompleteContentXml() throws Exception { - String document = "" + - "" + - "" + - ""; + checkFailure( + // document + "" + + "" + + "" + + "", - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = LayoutConfigsXsd.getValidator(null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse error referring to this grammar rule - assertRegex("cvc-complex-type.4: Attribute 'name' must appear on element 'd:device'.", e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); + // expected failure + "cvc-complex-type.4: Attribute 'name' must appear on element 'd:device'."); } /** A document with a root element containing no device element is not valid. */ public void testEmptyRootXml() throws Exception { - String document = "" + - ""; + checkFailure( + // document + "" + + "", - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = LayoutConfigsXsd.getValidator(null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse expression referring to this grammar rule - assertRegex("cvc-complex-type.2.4.b: The content of element 'd:layout-configs' is not complete.*", e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); + // expected failure + "cvc-complex-type.2.4.b: The content of element 'd:layout-configs' is not complete.*"); } /** A document with an empty device element is not valid. */ public void testEmptyDeviceXml() throws Exception { - String document = "" + - "" + - "" + - ""; + checkFailure( + // document + "" + + "" + + "" + + "", - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = LayoutConfigsXsd.getValidator(null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse error referring to this grammar rule - assertRegex("cvc-complex-type.2.4.b: The content of element 'd:device' is not complete.*", e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); + // expected failure + "cvc-complex-type.2.4.b: The content of element 'd:device' is not complete.*"); } /** A document with two default elements in a device element is not valid. */ public void testTwoDefaultsXml() throws Exception { - String document = "" + - "" + - "" + - " " + - " " + - "" + - ""; + checkFailure( + // document + "" + + "" + + "" + + " " + + " " + + "" + + "", - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = LayoutConfigsXsd.getValidator(null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse error referring to this grammar rule - assertRegex("cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*", e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); + // expected failure + "cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*"); } /** The default elements must be defined before the config one. It's invalid if after. */ public void testDefaultConfigOrderXml() throws Exception { - String document = "" + - "" + - "" + - " " + - " " + - "" + - ""; + checkFailure( + // document + "" + + "" + + "" + + " " + + " " + + "" + + "", - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = LayoutConfigsXsd.getValidator(null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse error referring to this grammar rule - assertRegex("cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*", e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); + // expected failure + "cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*"); } + + /** Screen dimension cannot be 0. */ + public void testScreenDimZeroXml() throws Exception { + checkFailure( + // document + "" + + "" + + "" + + " " + + " 0 1 " + + " " + + "" + + "", + + // expected failure + "cvc-minInclusive-valid: Value '0' is not facet-valid with respect to minInclusive '1'.*"); + } + + /** Screen dimension cannot be negative. */ + public void testScreenDimNegativeXml() throws Exception { + checkFailure( + // document + "" + + "" + + "" + + " " + + " -5 1 " + + " " + + "" + + "", + + // expected failure + "cvc-minInclusive-valid: Value '-5' is not facet-valid with respect to minInclusive '1'.*"); + } + + /** X/Y dpi cannot be 0. */ + public void testXDpiZeroXml() throws Exception { + checkFailure( + // document + "" + + "" + + "" + + " " + + " 0" + + " " + + "" + + "", + + // expected failure + "cvc-minExclusive-valid: Value '0' is not facet-valid with respect to minExclusive '0.0E1'.*"); + } + + + /** X/Y dpi cannot be negative. */ + public void testXDpiNegativeXml() throws Exception { + checkFailure( + // document + "" + + "" + + "" + + " " + + " -3.1415926538" + + " " + + "" + + "", + + // expected failure + "cvc-minExclusive-valid: Value '-3.1415926538' is not facet-valid with respect to minExclusive '0.0E1'.*"); + } + + /** WHitespace around token is accepted by the schema. */ + public void testTokenWhitespaceXml() throws Exception { + checkSuccess( + // document + "" + + "" + + "" + + " " + + " \n long \r " + + " " + + "" + + ""); + } + } + diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml index 12c481d60..901dd71c8 100755 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml @@ -32,6 +32,8 @@ 240 480 + 180.81234 + 180.81234 @@ -117,8 +119,14 @@ nonav - + + 240 + + + 2800 + +