Merge "Implement issue #3116702: New manifest tags for supported screen sizes  DO NOT MERGE" into gingerbread
diff --git a/api/current.xml b/api/current.xml
index d36fe69..626a5cc 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -6961,6 +6961,17 @@
  visibility="public"
 >
 </field>
+<field name="screenDensity"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843467"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="screenOrientation"
  type="int"
  transient="false"
@@ -6972,6 +6983,17 @@
  visibility="public"
 >
 </field>
+<field name="screenSize"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843466"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="scrollHorizontally"
  type="int"
  transient="false"
@@ -172683,6 +172705,17 @@
  visibility="public"
 >
 </field>
+<field name="DENSITY_XHIGH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="320"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="density"
  type="float"
  transient="false"
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 51f4202..ff3656c 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1080,6 +1080,16 @@
 
                 XmlUtils.skipCurrentTag(parser);
                 
+            } else if (tagName.equals("uses-gl-texture")) {
+                // Just skip this tag
+                XmlUtils.skipCurrentTag(parser);
+                continue;
+                
+            } else if (tagName.equals("compatible-screens")) {
+                // Just skip this tag
+                XmlUtils.skipCurrentTag(parser);
+                continue;
+                
             } else if (tagName.equals("eat-comment")) {
                 // Just skip this tag
                 XmlUtils.skipCurrentTag(parser);
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 76d8106..63baf14 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -45,6 +45,11 @@
     public static final int DENSITY_HIGH = 240;
 
     /**
+     * Standard quantized DPI for extra-high-density screens.
+     */
+    public static final int DENSITY_XHIGH = 320;
+
+    /**
      * The reference density used throughout the system.
      */
     public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 298463a..46a16fc 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1425,6 +1425,38 @@
         <attr name="functionalTest" />
     </declare-styleable>
     
+    <!-- Attributes that can be supplied in an AndroidManifest.xml
+         <code>screen</code> tag, a child of <code>compatible-screens</code>,
+         which is itseld a child of the root
+         {@link #AndroidManifest manifest} tag. -->
+    <declare-styleable name="AndroidManifestCompatibleScreensScreen">
+        <!-- Specifies a compatible screen size, as per the device
+             configuration screen size bins. -->
+        <attr name="screenSize">
+            <!-- A small screen configuration, at least 240x320db. -->
+            <enum name="small" value="200" />
+            <!-- A normal screen configuration, at least 320x480db. -->
+            <enum name="normal" value="300" />
+            <!-- A large screen configuration, at least 400x530db. -->
+            <enum name="large" value="400" />
+            <!-- An extra large screen configuration, at least 600x800db. -->
+            <enum name="xlarge" value="500" />
+        </attr>
+        <!-- Specifies a compatible screen density, as per the device
+             configuration screen density bins. -->
+        <attr name="screenDensity" format="integer">
+            <!-- A low density screen, approximately 120dpi. -->
+            <enum name="ldpi" value="120" />
+            <!-- A medium density screen, approximately 160dpi. -->
+            <enum name="mdpi" value="160" />
+            <!-- A high density screen, approximately 240dpi. -->
+            <enum name="hdpi" value="240" />
+            <!-- An extra high density screen, approximately 320dpi. -->
+            <enum name="xhdpi" value="320" />
+        </attr>
+    </declare-styleable>
+    
+    
     <!-- Declaration of an {@link android.content.Intent} object in XML.  May
          also include zero or more {@link #IntentCategory <category> and
          {@link #Extra <extra>} tags. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 5531d47..4005e96 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1260,6 +1260,8 @@
   <public type="attr" name="textSelectHandle" id="0x010102c7" />
   <public type="attr" name="textSelectHandleWindowStyle" id="0x010102c8" />
   <public type="attr" name="popupAnimationStyle" id="0x010102c9" />
+  <public type="attr" name="screenSize" id="0x010102ca" />
+  <public type="attr" name="screenDensity" id="0x010102cb" />
 
   <!-- presence drawables for videochat or audiochat capable contacts -->
   <public type="drawable" name="presence_video_away" id="0x010800ac" />
diff --git a/tests/DpiTest/AndroidManifest.xml b/tests/DpiTest/AndroidManifest.xml
index 68ecc6e..a4d8c79 100644
--- a/tests/DpiTest/AndroidManifest.xml
+++ b/tests/DpiTest/AndroidManifest.xml
@@ -18,6 +18,12 @@
     package="com.google.android.test.dpi">
     <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="3" />
     <supports-screens android:smallScreens="true" />
+    <compatible-screens>
+        <screen android:screenSize="small" android:screenDensity="ldpi" />
+        <screen android:screenSize="small" android:screenDensity="xhdpi" />
+        <screen android:screenSize="large" android:screenDensity="hdpi" />
+        <screen android:screenSize="xlarge" android:screenDensity="mdpi" />
+    </compatible-screens>
     <application android:label="DpiTest">
         <activity android:name="DpiTestActivity">
             <intent-filter>
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 873ebac..ad0465d 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -332,13 +332,15 @@
     REQ_FIVE_WAY_NAV_ATTR = 0x01010232,
     TARGET_SDK_VERSION_ATTR = 0x01010270,
     TEST_ONLY_ATTR = 0x01010272,
-    DENSITY_ATTR = 0x0101026c,
+    ANY_DENSITY_ATTR = 0x0101026c,
     GL_ES_VERSION_ATTR = 0x01010281,
     SMALL_SCREEN_ATTR = 0x01010284,
     NORMAL_SCREEN_ATTR = 0x01010285,
     LARGE_SCREEN_ATTR = 0x01010286,
     XLARGE_SCREEN_ATTR = 0x010102bf,
     REQUIRED_ATTR = 0x0101028e,
+    SCREEN_SIZE_ATTR = 0x010102ca,
+    SCREEN_DENSITY_ATTR = 0x010102cb,
 };
 
 const char *getComponentName(String8 &pkgName, String8 &componentName) {
@@ -355,6 +357,42 @@
     return retStr.string();
 }
 
+static void printCompatibleScreens(ResXMLTree& tree) {
+    size_t len;
+    ResXMLTree::event_code_t code;
+    int depth = 0;
+    bool first = true;
+    printf("compatible-screens:");
+    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
+        if (code == ResXMLTree::END_TAG) {
+            depth--;
+            if (depth < 0) {
+                break;
+            }
+            continue;
+        }
+        if (code != ResXMLTree::START_TAG) {
+            continue;
+        }
+        depth++;
+        String8 tag(tree.getElementName(&len));
+        if (tag == "screen") {
+            int32_t screenSize = getIntegerAttribute(tree,
+                    SCREEN_SIZE_ATTR, NULL, -1);
+            int32_t screenDensity = getIntegerAttribute(tree,
+                    SCREEN_DENSITY_ATTR, NULL, -1);
+            if (screenSize > 0 && screenDensity > 0) {
+                if (!first) {
+                    printf(",");
+                }
+                first = false;
+                printf("'%d/%d'", screenSize, screenDensity);
+            }
+        }
+    }
+    printf("\n");
+}
+
 /*
  * Handle the "dump" command, to extract select data from an archive.
  */
@@ -572,6 +610,7 @@
             int normalScreen = 1;
             int largeScreen = 1;
             int xlargeScreen = 1;
+            int anyDensity = 1;
             String8 pkg;
             String8 activityName;
             String8 activityLabel;
@@ -739,14 +778,6 @@
                             printf(" reqFiveWayNav='%d'", reqFiveWayNav);
                         }
                         printf("\n");
-                    } else if (tag == "supports-density") {
-                        int32_t dens = getIntegerAttribute(tree, DENSITY_ATTR, &error);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:density' attribute: %s\n",
-                                    error.string());
-                            goto bail;
-                        }
-                        printf("supports-density:'%d'\n", dens);
                     } else if (tag == "supports-screens") {
                         smallScreen = getIntegerAttribute(tree,
                                 SMALL_SCREEN_ATTR, NULL, 1);
@@ -756,6 +787,8 @@
                                 LARGE_SCREEN_ATTR, NULL, 1);
                         xlargeScreen = getIntegerAttribute(tree,
                                 XLARGE_SCREEN_ATTR, NULL, 1);
+                        anyDensity = getIntegerAttribute(tree,
+                                ANY_DENSITY_ATTR, NULL, 1);
                     } else if (tag == "uses-feature") {
                         String8 name = getAttribute(tree, NAME_ATTR, &error);
 
@@ -880,6 +913,9 @@
                                     error.string());
                                 goto bail;
                         }
+                    } else if (tag == "compatible-screens") {
+                        printCompatibleScreens(tree);
+                        depth--;
                     }
                 } else if (depth == 3 && withinApplication) {
                     withinActivity = false;
@@ -1106,6 +1142,9 @@
                 // Introduced in Honeycomb.
                 xlargeScreen = targetSdk >= 10 ? -1 : 0;
             }
+            if (anyDensity > 0) {
+                anyDensity = targetSdk >= 4 ? -1 : 0;
+            }
             printf("supports-screens:");
             if (smallScreen != 0) printf(" 'small'");
             if (normalScreen != 0) printf(" 'normal'");
@@ -1113,6 +1152,8 @@
             if (xlargeScreen != 0) printf(" 'xlarge'");
             printf("\n");
 
+            printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false");
+
             printf("locales:");
             Vector<String8> locales;
             res.getLocales(&locales);