New xlarge screen size.

Not complete, only for experimentation at this point.

This includes a reworking of how screen size configurations are matched,
so that if you are on a larger screen we can select configurations for
smaller screens if there aren't any exactly matching the current screen.

The screen size at which we switch to xlarge has been arbitrarily
chosen; the compatibility behavior has not yet been defined.

Change-Id: I1a33b3818eeb51a68fb72397568c39ab040a07f5
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index fef74aa..d4a190f 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -252,16 +252,6 @@
     public static final int FLAG_RESTORE_ANY_VERSION = 1<<17;
 
     /**
-     * Value for {@link #flags}: this is true if the application has set
-     * its android:neverEncrypt to true, false otherwise. It is used to specify
-     * that this package specifically "opts-out" of a secured file system solution,
-     * and will always store its data in-the-clear.
-     *
-     * {@hide}
-     */
-    public static final int FLAG_NEVER_ENCRYPT = 1<<18;
-
-    /**
      * Value for {@link #flags}: Set to true if the application has been
      * installed using the forward lock option.
      *
@@ -275,12 +265,30 @@
     public static final int FLAG_EXTERNAL_STORAGE = 1<<18;
 
     /**
+     * Value for {@link #flags}: true when the application's window can be
+     * increased in size for extra large screens.  Corresponds to
+     * {@link android.R.styleable#AndroidManifestSupportsScreens_xlargeScreens
+     * android:smallScreens}.
+     */
+    public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 1<<19;
+    
+    /**
+     * Value for {@link #flags}: this is true if the application has set
+     * its android:neverEncrypt to true, false otherwise. It is used to specify
+     * that this package specifically "opts-out" of a secured file system solution,
+     * and will always store its data in-the-clear.
+     *
+     * {@hide}
+     */
+    public static final int FLAG_NEVER_ENCRYPT = 1<<30;
+
+    /**
      * Value for {@link #flags}: Set to true if the application has been
      * installed using the forward lock option.
      *
      * {@hide}
      */
-    public static final int FLAG_FORWARD_LOCK = 1<<20;
+    public static final int FLAG_FORWARD_LOCK = 1<<29;
 
     /**
      * Value for {@link #flags}: Set to true if the application is
@@ -288,7 +296,7 @@
      *
      * {@hide}
      */
-    public static final int FLAG_NATIVE_DEBUGGABLE = 1<<21;
+    public static final int FLAG_NATIVE_DEBUGGABLE = 1<<28;
 
     /**
      * Flags associated with the application.  Any combination of
@@ -298,7 +306,8 @@
      * {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
      * {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
      * {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
-     * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_RESIZEABLE_FOR_SCREENS},
+     * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_SUPPORTS_XLARGE_SCREENS},
+     * {@link #FLAG_RESIZEABLE_FOR_SCREENS},
      * {@link #FLAG_SUPPORTS_SCREEN_DENSITIES}, {@link #FLAG_VM_SAFE_MODE}
      */
     public int flags = 0;
@@ -530,7 +539,7 @@
     public void disableCompatibilityMode() {
         flags |= (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS |
                 FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS |
-                FLAG_SUPPORTS_SCREEN_DENSITIES);
+                FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
     }
     
     /**
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 6a4fefc..4ddc124 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -791,6 +791,7 @@
         int supportsSmallScreens = 1;
         int supportsNormalScreens = 1;
         int supportsLargeScreens = 1;
+        int supportsXLargeScreens = 1;
         int resizeable = 1;
         int anyDensity = 1;
         
@@ -998,9 +999,12 @@
                 supportsLargeScreens = sa.getInteger(
                         com.android.internal.R.styleable.AndroidManifestSupportsScreens_largeScreens,
                         supportsLargeScreens);
+                supportsXLargeScreens = sa.getInteger(
+                        com.android.internal.R.styleable.AndroidManifestSupportsScreens_xlargeScreens,
+                        supportsXLargeScreens);
                 resizeable = sa.getInteger(
                         com.android.internal.R.styleable.AndroidManifestSupportsScreens_resizeable,
-                        supportsLargeScreens);
+                        resizeable);
                 anyDensity = sa.getInteger(
                         com.android.internal.R.styleable.AndroidManifestSupportsScreens_anyDensity,
                         anyDensity);
@@ -1134,6 +1138,11 @@
                         >= android.os.Build.VERSION_CODES.DONUT)) {
             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
         }
+        if (supportsXLargeScreens < 0 || (supportsXLargeScreens > 0
+                && pkg.applicationInfo.targetSdkVersion
+                        >= android.os.Build.VERSION_CODES.GINGERBREAD)) {
+            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS;
+        }
         if (resizeable < 0 || (resizeable > 0
                 && pkg.applicationInfo.targetSdkVersion
                         >= android.os.Build.VERSION_CODES.DONUT)) {
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 11c67cc..d0ba590 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -99,7 +99,22 @@
      */
     private static final int CONFIGURED_LARGE_SCREENS = 16; 
 
-    private static final int SCALING_EXPANDABLE_MASK = SCALING_REQUIRED | EXPANDABLE | LARGE_SCREENS;
+    /**
+     * A flag mask to indicates that the application supports xlarge screens.
+     * The flag is set to true if
+     * 1) Application declares it supports xlarge screens in manifest file using <supports-screens> or
+     * 2) The screen size is not xlarge
+     * {@see compatibilityFlag}
+     */
+    private static final int XLARGE_SCREENS = 32;
+    
+    /**
+     * A flag mask to tell if the application supports xlarge screens. This differs
+     * from XLARGE_SCREENS in that the application that does not support xlarge
+     * screens will be marked as supporting them if the current screen is not
+     * xlarge.
+     */
+    private static final int CONFIGURED_XLARGE_SCREENS = 64;
 
     /**
      * The effective screen density we have selected for this application.
@@ -127,6 +142,9 @@
         if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
             mCompatibilityFlags |= LARGE_SCREENS | CONFIGURED_LARGE_SCREENS;
         }
+        if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
+            mCompatibilityFlags |= XLARGE_SCREENS | CONFIGURED_XLARGE_SCREENS;
+        }
         if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
             mCompatibilityFlags |= EXPANDABLE | CONFIGURED_EXPANDABLE;
         }
@@ -157,6 +175,7 @@
         this(ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS
                 | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
                 | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS
+                | ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS
                 | ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS,
                 EXPANDABLE | CONFIGURED_EXPANDABLE,
                 DisplayMetrics.DENSITY_DEVICE,
@@ -196,6 +215,17 @@
     }
 
     /**
+     * Sets large screen bit in the compatibility flag.
+     */
+    public void setXLargeScreens(boolean expandable) {
+        if (expandable) {
+            mCompatibilityFlags |= CompatibilityInfo.XLARGE_SCREENS;
+        } else {
+            mCompatibilityFlags &= ~CompatibilityInfo.XLARGE_SCREENS;
+        }
+    }
+
+    /**
      * @return true if the application is configured to be expandable.
      */
     public boolean isConfiguredExpandable() {
@@ -210,6 +240,13 @@
     }
 
     /**
+     * @return true if the application is configured to be expandable.
+     */
+    public boolean isConfiguredXLargeScreens() {
+        return (mCompatibilityFlags & CompatibilityInfo.CONFIGURED_XLARGE_SCREENS) != 0;
+    }
+
+    /**
      * @return true if the scaling is required
      */
     public boolean isScalingRequired() {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 1a0c867..02956ba 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -62,6 +62,7 @@
     public static final int SCREENLAYOUT_SIZE_SMALL = 0x01;
     public static final int SCREENLAYOUT_SIZE_NORMAL = 0x02;
     public static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
+    public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;
     
     public static final int SCREENLAYOUT_LONG_MASK = 0x30;
     public static final int SCREENLAYOUT_LONG_UNDEFINED = 0x00;
@@ -82,7 +83,7 @@
      * <p>The {@link #SCREENLAYOUT_SIZE_MASK} bits define the overall size
      * of the screen.  They may be one of
      * {@link #SCREENLAYOUT_SIZE_SMALL}, {@link #SCREENLAYOUT_SIZE_NORMAL},
-     * or {@link #SCREENLAYOUT_SIZE_LARGE}.
+     * {@link #SCREENLAYOUT_SIZE_LARGE}, or {@link #SCREENLAYOUT_SIZE_XLARGE}.
      * 
      * <p>The {@link #SCREENLAYOUT_LONG_MASK} defines whether the screen
      * is wider/taller than normal.  They may be one of
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 3e9fd42..9d1a634 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -180,6 +180,10 @@
         public static final int ECLAIR_MR1 = 7;
         
         public static final int FROYO = 8;
+        
+        public static final int KRAKEN = CUR_DEVELOPMENT;
+        
+        public static final int GINGERBREAD = CUR_DEVELOPMENT;
     }
     
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 2628eb4..76d8106 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -135,6 +135,7 @@
             int screenLayout) {
         boolean expandable = compatibilityInfo.isConfiguredExpandable();
         boolean largeScreens = compatibilityInfo.isConfiguredLargeScreens();
+        boolean xlargeScreens = compatibilityInfo.isConfiguredXLargeScreens();
         
         // Note: this assume that configuration is updated before calling
         // updateMetrics method.
@@ -157,8 +158,18 @@
                 compatibilityInfo.setLargeScreens(false);
             }
         }
+        if (!xlargeScreens) {
+            if ((screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK)
+                    != Configuration.SCREENLAYOUT_SIZE_XLARGE) {
+                xlargeScreens = true;
+                // the current screen size is not large.
+                compatibilityInfo.setXLargeScreens(true);
+            } else {
+                compatibilityInfo.setXLargeScreens(false);
+            }
+        }
         
-        if (!expandable || !largeScreens) {
+        if (!expandable || (!largeScreens && !xlargeScreens)) {
             // This is a larger screen device and the app is not 
             // compatible with large screens, so diddle it.
             
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f98445c..b4c4811 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -965,6 +965,8 @@
              screen, so that it retains the dimensions it was originally
              designed for. -->
         <attr name="largeScreens" format="boolean" />
+        <!-- Indicates whether the application supports extra large screen form-factors. -->
+        <attr name="xlargeScreens" format="boolean" />
         <!-- Indicates whether the application can resize itself to newer
              screen sizes.  This is mostly used to distinguish between old
              applications that may not be compatible with newly introduced