Merge "Call RefBase::destroy() when OBJECT_LIFETIME_* is not the default"
diff --git a/api/current.txt b/api/current.txt
index 3c8e551..7d87425 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5400,6 +5400,7 @@
     field public static final int CONFIG_ORIENTATION = 128; // 0x80
     field public static final int CONFIG_SCREEN_LAYOUT = 256; // 0x100
     field public static final int CONFIG_SCREEN_SIZE = 1024; // 0x400
+    field public static final int CONFIG_SMALLEST_SCREEN_SIZE = 2048; // 0x800
     field public static final int CONFIG_TOUCHSCREEN = 8; // 0x8
     field public static final int CONFIG_UI_MODE = 512; // 0x200
     field public static final android.os.Parcelable.Creator CREATOR;
@@ -5989,6 +5990,7 @@
     field public static final int SCREENLAYOUT_SIZE_XLARGE = 4; // 0x4
     field public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0; // 0x0
     field public static final int SCREEN_WIDTH_DP_UNDEFINED = 0; // 0x0
+    field public static final int SMALLEST_SCREEN_WIDTH_DP_UNDEFINED = 0; // 0x0
     field public static final int TOUCHSCREEN_FINGER = 3; // 0x3
     field public static final int TOUCHSCREEN_NOTOUCH = 1; // 0x1
     field public static final int TOUCHSCREEN_STYLUS = 2; // 0x2
@@ -6015,6 +6017,7 @@
     field public int screenHeightDp;
     field public int screenLayout;
     field public int screenWidthDp;
+    field public int smallestScreenWidthDp;
     field public int touchscreen;
     field public int uiMode;
   }
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index db8d5e9..9cb57be 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -29,12 +29,13 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.SystemClock;
 import android.speech.RecognizerIntent;
 import android.text.InputType;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.TypedValue;
+import android.view.ActionMode;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -50,9 +51,6 @@
 import android.widget.SearchView;
 import android.widget.TextView;
 
-import java.util.WeakHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-
 /**
  * Search dialog. This is controlled by the 
  * SearchManager and runs in the current foreground process.
@@ -110,13 +108,20 @@
         }
     };
 
+    static int resolveDialogTheme(Context context) {
+        TypedValue outValue = new TypedValue();
+        context.getTheme().resolveAttribute(com.android.internal.R.attr.searchDialogTheme,
+                outValue, true);
+        return outValue.resourceId;
+    }
+
     /**
      * Constructor - fires it up and makes it look like the search UI.
      * 
      * @param context Application Context we can use for system acess
      */
     public SearchDialog(Context context, SearchManager searchManager) {
-        super(context, com.android.internal.R.style.Theme_SearchBar);
+        super(context, resolveDialogTheme(context));
 
         // Save voice intent for later queries/launching
         mVoiceWebSearchIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
@@ -642,6 +647,14 @@
             }
             return super.dispatchKeyEventPreIme(event);
         }
+
+        /**
+         * Don't allow action modes in a SearchBar, it looks silly.
+         */
+        @Override
+        public ActionMode startActionModeForChild(View child, ActionMode.Callback callback) {
+            return null;
+        }
     }
 
     private boolean isEmpty(AutoCompleteTextView actv) {
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 64c437d..4285388 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -340,6 +340,12 @@
     public static final int CONFIG_SCREEN_SIZE = 0x0400;
     /**
      * Bit in {@link #configChanges} that indicates that the activity
+     * can itself handle the smallest screen size. Set from the
+     * {@link android.R.attr#configChanges} attribute.
+     */
+    public static final int CONFIG_SMALLEST_SCREEN_SIZE = 0x0800;
+    /**
+     * Bit in {@link #configChanges} that indicates that the activity
      * can itself handle changes to the font scaling factor.  Set from the
      * {@link android.R.attr#configChanges} attribute.  This is
      * not a core resource configutation, but a higher-level value, so its
@@ -364,6 +370,7 @@
         0x0800, // SCREEN LAYOUT
         0x1000, // UI MODE
         0x0200, // SCREEN SIZE
+        0x2000, // SMALLEST SCREEN SIZE
     };
     /** @hide
      * Convert Java change bits to native.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 18120ac..9ff324b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -396,7 +396,7 @@
             int cookie = assmgr.addAssetPath(mArchiveSourcePath);
             if (cookie != 0) {
                 res = new Resources(assmgr, metrics, null);
-                assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                         Build.VERSION.RESOURCES_SDK_INT);
                 parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
                 assetError = false;
@@ -596,7 +596,7 @@
         AssetManager assmgr = null;
         try {
             assmgr = new AssetManager();
-            assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     Build.VERSION.RESOURCES_SDK_INT);
             int cookie = assmgr.addAssetPath(packageFilePath);
             parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
@@ -1943,7 +1943,8 @@
                     0);
             if (owner.applicationInfo.targetSdkVersion
                         < android.os.Build.VERSION_CODES.HONEYCOMB_MR2) {
-                a.info.configChanges |= ActivityInfo.CONFIG_SCREEN_SIZE;
+                a.info.configChanges |= ActivityInfo.CONFIG_SCREEN_SIZE
+                        | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
             }
             a.info.softInputMode = sa.getInt(
                     com.android.internal.R.styleable.AndroidManifestActivity_windowSoftInputMode,
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index be67e96..931cb18 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -652,8 +652,8 @@
     public native final void setConfiguration(int mcc, int mnc, String locale,
             int orientation, int touchscreen, int density, int keyboard,
             int keyboardHidden, int navigation, int screenWidth, int screenHeight,
-            int screenWidthDp, int screenHeightDp, int screenLayout, int uiMode,
-            int majorVersion);
+            int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp,
+            int screenLayout, int uiMode, int majorVersion);
 
     /**
      * Retrieve the resource identifier for the given resource name.
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 0de08f2..12ec258 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -259,6 +259,15 @@
      */
     public int screenHeightDp;
 
+    public static final int SMALLEST_SCREEN_WIDTH_DP_UNDEFINED = 0;
+
+    /**
+     * The smallest screen size an application will see in normal operation.
+     * This is the smallest value of both screenWidthDp and screenHeightDp
+     * in both portrait and landscape.
+     */
+    public int smallestScreenWidthDp;
+
     /**
      * @hide Internal book-keeping.
      */
@@ -298,6 +307,7 @@
         uiMode = o.uiMode;
         screenWidthDp = o.screenWidthDp;
         screenHeightDp = o.screenHeightDp;
+        smallestScreenWidthDp = o.smallestScreenWidthDp;
         seq = o.seq;
     }
     
@@ -315,6 +325,56 @@
         } else {
             sb.append(" (no locale)");
         }
+        if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
+            sb.append(" sw"); sb.append(smallestScreenWidthDp); sb.append("dp");
+        } else {
+            sb.append("?swdp");
+        }
+        if (screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
+            sb.append(" w"); sb.append(screenWidthDp); sb.append("dp");
+        } else {
+            sb.append("?wdp");
+        }
+        if (screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
+            sb.append(" h"); sb.append(screenHeightDp); sb.append("dp");
+        } else {
+            sb.append("?hdp");
+        }
+        switch ((screenLayout&SCREENLAYOUT_SIZE_MASK)) {
+            case SCREENLAYOUT_SIZE_UNDEFINED: sb.append(" ?lsize"); break;
+            case SCREENLAYOUT_SIZE_SMALL: sb.append(" smll"); break;
+            case SCREENLAYOUT_SIZE_NORMAL: sb.append(" nrml"); break;
+            case SCREENLAYOUT_SIZE_LARGE: sb.append(" lrg"); break;
+            case SCREENLAYOUT_SIZE_XLARGE: sb.append(" xlrg"); break;
+            default: sb.append(" layoutSize=");
+                    sb.append(screenLayout&SCREENLAYOUT_SIZE_MASK); break;
+        }
+        switch ((screenLayout&SCREENLAYOUT_LONG_MASK)) {
+            case SCREENLAYOUT_LONG_UNDEFINED: sb.append(" ?long"); break;
+            case SCREENLAYOUT_LONG_NO: /* not-long is not interesting to print */ break;
+            case SCREENLAYOUT_LONG_YES: sb.append(" long"); break;
+            default: sb.append(" layoutLong=");
+                    sb.append(screenLayout&SCREENLAYOUT_LONG_MASK); break;
+        }
+        switch (orientation) {
+            case ORIENTATION_UNDEFINED: sb.append(" ?orien"); break;
+            case ORIENTATION_LANDSCAPE: sb.append(" land"); break;
+            case ORIENTATION_PORTRAIT: sb.append(" port"); break;
+            default: sb.append(" orien="); sb.append(orientation); break;
+        }
+        switch ((uiMode&UI_MODE_TYPE_MASK)) {
+            case UI_MODE_TYPE_UNDEFINED: sb.append(" ?uimode"); break;
+            case UI_MODE_TYPE_NORMAL: /* normal is not interesting to print */ break;
+            case UI_MODE_TYPE_DESK: sb.append(" desk"); break;
+            case UI_MODE_TYPE_CAR: sb.append(" car"); break;
+            default: sb.append(" uimode="); sb.append(uiMode&UI_MODE_TYPE_MASK); break;
+        }
+        switch ((uiMode&UI_MODE_NIGHT_MASK)) {
+            case UI_MODE_NIGHT_UNDEFINED: sb.append(" ?night"); break;
+            case UI_MODE_NIGHT_NO: /* not-night is not interesting to print */ break;
+            case UI_MODE_NIGHT_YES: sb.append(" night"); break;
+            default: sb.append(" night="); sb.append(uiMode&UI_MODE_NIGHT_MASK); break;
+        }
         switch (touchscreen) {
             case TOUCHSCREEN_UNDEFINED: sb.append(" ?touch"); break;
             case TOUCHSCREEN_NOTOUCH: sb.append(" -touch"); break;
@@ -356,51 +416,6 @@
             case NAVIGATIONHIDDEN_YES: sb.append("/h"); break;
             default: sb.append("/"); sb.append(navigationHidden); break;
         }
-        switch (orientation) {
-            case ORIENTATION_UNDEFINED: sb.append(" ?orien"); break;
-            case ORIENTATION_LANDSCAPE: sb.append(" land"); break;
-            case ORIENTATION_PORTRAIT: sb.append(" port"); break;
-            default: sb.append(" orien="); sb.append(orientation); break;
-        }
-        switch ((screenLayout&SCREENLAYOUT_SIZE_MASK)) {
-            case SCREENLAYOUT_SIZE_UNDEFINED: sb.append(" ?lsize"); break;
-            case SCREENLAYOUT_SIZE_SMALL: sb.append(" smll"); break;
-            case SCREENLAYOUT_SIZE_NORMAL: sb.append(" nrml"); break;
-            case SCREENLAYOUT_SIZE_LARGE: sb.append(" lrg"); break;
-            case SCREENLAYOUT_SIZE_XLARGE: sb.append(" xlrg"); break;
-            default: sb.append(" layoutSize=");
-                    sb.append(screenLayout&SCREENLAYOUT_SIZE_MASK); break;
-        }
-        switch ((screenLayout&SCREENLAYOUT_LONG_MASK)) {
-            case SCREENLAYOUT_LONG_UNDEFINED: sb.append(" ?long"); break;
-            case SCREENLAYOUT_LONG_NO: /* not-long is not interesting to print */ break;
-            case SCREENLAYOUT_LONG_YES: sb.append(" long"); break;
-            default: sb.append(" layoutLong=");
-                    sb.append(screenLayout&SCREENLAYOUT_LONG_MASK); break;
-        }
-        switch ((uiMode&UI_MODE_TYPE_MASK)) {
-            case UI_MODE_TYPE_UNDEFINED: sb.append(" ?uimode"); break;
-            case UI_MODE_TYPE_NORMAL: /* normal is not interesting to print */ break;
-            case UI_MODE_TYPE_DESK: sb.append(" desk"); break;
-            case UI_MODE_TYPE_CAR: sb.append(" car"); break;
-            default: sb.append(" uimode="); sb.append(uiMode&UI_MODE_TYPE_MASK); break;
-        }
-        switch ((uiMode&UI_MODE_NIGHT_MASK)) {
-            case UI_MODE_NIGHT_UNDEFINED: sb.append(" ?night"); break;
-            case UI_MODE_NIGHT_NO: /* not-night is not interesting to print */ break;
-            case UI_MODE_NIGHT_YES: sb.append(" night"); break;
-            default: sb.append(" night="); sb.append(uiMode&UI_MODE_NIGHT_MASK); break;
-        }
-        if (screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
-            sb.append(" w"); sb.append(screenWidthDp); sb.append("dp");
-        } else {
-            sb.append("?wdp");
-        }
-        if (screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
-            sb.append(" h"); sb.append(screenHeightDp); sb.append("dp");
-        } else {
-            sb.append("?hdp");
-        }
         if (seq != 0) {
             sb.append(" s.");
             sb.append(seq);
@@ -428,6 +443,7 @@
         uiMode = UI_MODE_TYPE_UNDEFINED;
         screenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
         screenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
+        smallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
         seq = 0;
     }
 
@@ -531,6 +547,11 @@
             changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
             screenHeightDp = delta.screenHeightDp;
         }
+        if (delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
+                && smallestScreenWidthDp != delta.smallestScreenWidthDp) {
+            changed |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+            smallestScreenWidthDp = delta.smallestScreenWidthDp;
+        }
         
         if (delta.seq != 0) {
             seq = delta.seq;
@@ -564,7 +585,9 @@
      * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
      * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}, or
      * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE
-     * PackageManager.ActivityInfo.CONFIG_SCREEN_SIZE}.
+     * PackageManager.ActivityInfo.CONFIG_SCREEN_SIZE}, or
+     * {@link android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE
+     * PackageManager.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE}.
      */
     public int diff(Configuration delta) {
         int changed = 0;
@@ -625,6 +648,10 @@
                 && screenHeightDp != delta.screenHeightDp) {
             changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
         }
+        if (delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
+                && smallestScreenWidthDp != delta.smallestScreenWidthDp) {
+            changed |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+        }
         
         return changed;
     }
@@ -708,6 +735,7 @@
         dest.writeInt(uiMode);
         dest.writeInt(screenWidthDp);
         dest.writeInt(screenHeightDp);
+        dest.writeInt(smallestScreenWidthDp);
         dest.writeInt(seq);
     }
 
@@ -731,6 +759,7 @@
         uiMode = source.readInt();
         screenWidthDp = source.readInt();
         screenHeightDp = source.readInt();
+        smallestScreenWidthDp = source.readInt();
         seq = source.readInt();
     }
     
@@ -795,6 +824,8 @@
         n = this.screenWidthDp - that.screenWidthDp;
         if (n != 0) return n;
         n = this.screenHeightDp - that.screenHeightDp;
+        if (n != 0) return n;
+        n = this.smallestScreenWidthDp - that.smallestScreenWidthDp;
         //if (n != 0) return n;
         return n;
     }
@@ -830,6 +861,7 @@
         result = 31 * result + uiMode;
         result = 31 * result + screenWidthDp;
         result = 31 * result + screenHeightDp;
+        result = 31 * result + smallestScreenWidthDp;
         return result;
     }
 }
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 540f704..a072e94 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1458,6 +1458,7 @@
                     mConfiguration.touchscreen,
                     (int)(mMetrics.density*160), mConfiguration.keyboard,
                     keyboardHidden, mConfiguration.navigation, width, height,
+                    mConfiguration.smallestScreenWidthDp,
                     mConfiguration.screenWidthDp, mConfiguration.screenHeightDp,
                     mConfiguration.screenLayout, mConfiguration.uiMode,
                     Build.VERSION.RESOURCES_SDK_INT);
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 5a418f3..4e52e40 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -466,16 +466,34 @@
     public int getMaxWallpaperLayer();
     
     /**
-     * Return the display width available after excluding the window
-     * decor.
+     * Return the display width available after excluding any screen
+     * decorations that can never be removed.  That is, system bar or
+     * button bar.
      */
-    public int getNonDecorDisplayWidth(int fullWidth);
+    public int getNonDecorDisplayWidth(int rotation, int fullWidth);
 
     /**
-     * Return the display height available after excluding the screen
-     * decor.
+     * Return the display height available after excluding any screen
+     * decorations that can never be removed.  That is, system bar or
+     * button bar.
      */
-    public int getNonDecorDisplayHeight(int fullHeight);
+    public int getNonDecorDisplayHeight(int rotation, int fullHeight);
+
+    /**
+     * Return the available screen width that we should report for the
+     * configuration.  This must be no larger than
+     * {@link #getNonDecorDisplayWidth(int, int)}; it may be smaller than
+     * that to account for more transient decoration like a status bar.
+     */
+    public int getConfigDisplayWidth(int rotation, int fullWidth);
+
+    /**
+     * Return the available screen height that we should report for the
+     * configuration.  This must be no larger than
+     * {@link #getNonDecorDisplayHeight(int, int)}; it may be smaller than
+     * that to account for more transient decoration like a status bar.
+     */
+    public int getConfigDisplayHeight(int rotation, int fullHeight);
 
     /**
      * Return whether the given window should forcibly hide everything
diff --git a/core/jni/android_content_res_Configuration.cpp b/core/jni/android_content_res_Configuration.cpp
index 95b18ea..246e3bd 100644
--- a/core/jni/android_content_res_Configuration.cpp
+++ b/core/jni/android_content_res_Configuration.cpp
@@ -38,6 +38,9 @@
     jfieldID navigationHidden;
     jfieldID orientation;
     jfieldID uiMode;
+    jfieldID screenWidthDp;
+    jfieldID screenHeightDp;
+    jfieldID smallestScreenWidthDp;
 } gConfigurationClassInfo;
 
 void android_Configuration_getFromJava(
@@ -60,6 +63,11 @@
 
     out->orientation = env->GetIntField(clazz, gConfigurationClassInfo.orientation);
     out->uiMode = env->GetIntField(clazz, gConfigurationClassInfo.uiMode);
+
+    out->screenWidthDp = env->GetIntField(clazz, gConfigurationClassInfo.screenWidthDp);
+    out->screenHeightDp = env->GetIntField(clazz, gConfigurationClassInfo.screenHeightDp);
+    out->smallestScreenWidthDp = env->GetIntField(clazz,
+            gConfigurationClassInfo.smallestScreenWidthDp);
 }
 
 /*
@@ -108,6 +116,12 @@
             "orientation", "I");
     GET_FIELD_ID(gConfigurationClassInfo.uiMode, clazz,
             "uiMode", "I");
+    GET_FIELD_ID(gConfigurationClassInfo.screenWidthDp, clazz,
+            "screenWidthDp", "I");
+    GET_FIELD_ID(gConfigurationClassInfo.screenHeightDp, clazz,
+            "screenHeightDp", "I");
+    GET_FIELD_ID(gConfigurationClassInfo.smallestScreenWidthDp, clazz,
+            "smallestScreenWidthDp", "I");
 
     return AndroidRuntime::registerNativeMethods(env, "android/content/res/Configuration", gMethods,
             NELEM(gMethods));
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index b0e92e4..4f8f1af 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -510,6 +510,7 @@
                                                           jint keyboard, jint keyboardHidden,
                                                           jint navigation,
                                                           jint screenWidth, jint screenHeight,
+                                                          jint smallestScreenWidthDp,
                                                           jint screenWidthDp, jint screenHeightDp,
                                                           jint screenLayout, jint uiMode,
                                                           jint sdkVersion)
@@ -534,6 +535,7 @@
     config.navigation = (uint8_t)navigation;
     config.screenWidth = (uint16_t)screenWidth;
     config.screenHeight = (uint16_t)screenHeight;
+    config.smallestScreenWidthDp = (uint16_t)smallestScreenWidthDp;
     config.screenWidthDp = (uint16_t)screenWidthDp;
     config.screenHeightDp = (uint16_t)screenHeightDp;
     config.screenLayout = (uint8_t)screenLayout;
@@ -1646,7 +1648,7 @@
         (void*) android_content_AssetManager_setLocale },
     { "getLocales",      "()[Ljava/lang/String;",
         (void*) android_content_AssetManager_getLocales },
-    { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIII)V",
+    { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIIII)V",
         (void*) android_content_AssetManager_setConfiguration },
     { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
         (void*) android_content_AssetManager_getResourceIdentifier },
diff --git a/core/res/res/drawable-hdpi/cab_background_dark.9.png b/core/res/res/drawable-hdpi/cab_background_dark.9.png
deleted file mode 100644
index bc5db49..0000000
--- a/core/res/res/drawable-hdpi/cab_background_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_background_light.9.png b/core/res/res/drawable-hdpi/cab_background_light.9.png
deleted file mode 100644
index 1f45bc9..0000000
--- a/core/res/res/drawable-hdpi/cab_background_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_background_opaque_holo_dark.9.png b/core/res/res/drawable-hdpi/cab_background_opaque_holo_dark.9.png
new file mode 100644
index 0000000..0f4c3c3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/cab_background_opaque_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_background_opaque_holo_light.9.png b/core/res/res/drawable-hdpi/cab_background_opaque_holo_light.9.png
new file mode 100644
index 0000000..fb9b831
--- /dev/null
+++ b/core/res/res/drawable-hdpi/cab_background_opaque_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_background_dark.9.png b/core/res/res/drawable-mdpi/cab_background_dark.9.png
deleted file mode 100644
index 253b12c..0000000
--- a/core/res/res/drawable-mdpi/cab_background_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_background_light.9.png b/core/res/res/drawable-mdpi/cab_background_light.9.png
deleted file mode 100644
index aaccdfb..0000000
--- a/core/res/res/drawable-mdpi/cab_background_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_background_opaque_holo_dark.9.png b/core/res/res/drawable-mdpi/cab_background_opaque_holo_dark.9.png
new file mode 100644
index 0000000..013319c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/cab_background_opaque_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_background_opaque_holo_light.9.png b/core/res/res/drawable-mdpi/cab_background_opaque_holo_light.9.png
new file mode 100644
index 0000000..6d8861a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/cab_background_opaque_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/cab_background_opaque_holo_dark.9.png b/core/res/res/drawable-xhdpi/cab_background_opaque_holo_dark.9.png
new file mode 100644
index 0000000..e2b604b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/cab_background_opaque_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/cab_background_opaque_holo_light.9.png b/core/res/res/drawable-xhdpi/cab_background_opaque_holo_light.9.png
new file mode 100644
index 0000000..0c1aeaa
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/cab_background_opaque_holo_light.9.png
Binary files differ
diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml
index 9cf08ea..7918a3f 100644
--- a/core/res/res/layout/search_bar.xml
+++ b/core/res/res/layout/search_bar.xml
@@ -25,7 +25,7 @@
     android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:focusable="true"
-    android:background="@drawable/cab_background_light"
+    android:background="?android:attr/actionModeBackground"
     android:descendantFocusability="afterDescendants">
 
     <RelativeLayout
diff --git a/core/res/res/values-large/dimens.xml b/core/res/res/values-large/dimens.xml
index da36b67..55eb145 100644
--- a/core/res/res/values-large/dimens.xml
+++ b/core/res/res/values-large/dimens.xml
@@ -24,10 +24,6 @@
     <!-- Size of the giant number (unread count) in the notifications -->
     <dimen name="status_bar_content_number_size">48sp</dimen>
 
-    <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
-    <!-- Margin for permanent screen decorations at the bottom. -->
-    <dimen name="screen_margin_bottom">48dip</dimen>
-
     <!-- Default height of a key in the password keyboard for alpha -->
     <dimen name="password_keyboard_key_height_alpha">75dip</dimen>
     <!-- Default height of a key in the password keyboard for numeric -->
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 9073531..810c3b2 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -233,7 +233,10 @@
        <item>@drawable/btn_cab_done_focused_holo</item>
        <item>@drawable/btn_cab_done_holo</item>
        <item>@drawable/btn_cab_done_pressed_holo</item>
-       <item>@drawable/cab_background_light</item>
+       <item>@drawable/cab_background_holo_dark</item>
+       <item>@drawable/cab_background_holo_light</item>
+       <item>@drawable/cab_background_opaque_holo_dark</item>
+       <item>@drawable/cab_background_opaque_holo_light</item>
        <item>@drawable/cab_ic_close_focused_holo</item>
        <item>@drawable/cab_ic_close_holo</item>
        <item>@drawable/cab_ic_close_normal_holo</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2bb3e83..6c18089 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -752,6 +752,9 @@
         <!-- SearchView text field background for the right section -->
         <attr name="searchViewTextFieldRight" format="reference" />
 
+        <!-- Theme to use for Search Dialogs -->
+        <attr name="searchDialogTheme" format="reference" />
+
         <!-- Specifies a drawable to use for the 'home as up' indicator. -->
         <attr name="homeAsUpIndicator" format="reference" />
 
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 625afff..6b7c2a6 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -590,11 +590,21 @@
         <!-- The global user interface mode has changed.  For example,
              going in or out of car mode, night mode changing, etc. -->
         <flag name="uiMode" value="0x0200" />
+        <!-- The current available screen size has changed.  If applications don't
+             target at least {@link android.os.Build.VERSION_CODES#HONEYCOMB_MR2}
+             then the activity will always handle this itself (the change
+             will not result in a restart).  This represents a change in the
+             currently available size, so will change when the user switches
+             between landscape and portrait. -->
+        <flag name="screenSize" value="0x0400" />
         <!-- The physical screen size has changed.  If applications don't
              target at least {@link android.os.Build.VERSION_CODES#HONEYCOMB_MR2}
              then the activity will always handle this itself (the change
-             will not result in a restart). -->
-        <flag name="screenSize" value="0x0400" />
+             will not result in a restart).  This represents a change in size
+             regardless of orientation, so will only change when the actual
+             physical screen size has changed such as switching to an external
+             display. -->
+        <flag name="smallestScreenSize" value="0x0800" />
         <!-- The font scaling factor has changed, that is the user has
              selected a new global font size. -->
         <flag name="fontScale" value="0x40000000" />
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index e405f20..3f4010b 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -38,8 +38,6 @@
     <dimen name="status_bar_content_number_size">48sp</dimen>
     <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
     <dimen name="status_bar_edge_ignore">5dp</dimen>
-    <!-- Margin for permanent screen decorations at the bottom. -->
-    <dimen name="screen_margin_bottom">0dip</dimen>
     <!-- Size of the fastscroll hint letter -->
     <dimen name="fastscroll_overlay_size">104dp</dimen>
     <!-- Width of the fastscroll thumb -->
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index cdfdd11..aa9ddff 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -262,7 +262,7 @@
         <item name="actionDropDownStyle">@android:style/Widget.Spinner.DropDown</item>
         <item name="actionButtonStyle">@android:style/Widget.ActionButton</item>
         <item name="actionOverflowButtonStyle">@android:style/Widget.ActionButton.Overflow</item>
-        <item name="actionModeBackground">@android:drawable/cab_background_dark</item>
+        <item name="actionModeBackground">@android:drawable/cab_background_opaque_holo_dark</item>
         <item name="actionModeCloseDrawable">@android:drawable/ic_menu_close_clear_cancel</item>
         <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_dark</item>
         <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_dark</item>
@@ -298,6 +298,8 @@
         <item name="searchViewEditQuery">@android:drawable/ic_commit</item>
         <item name="searchViewEditQueryBackground">?attr/selectableItemBackground</item>
 
+        <item name="searchDialogTheme">@style/Theme.SearchBar</item>
+
         <!-- PreferenceFrameLayout attributes -->
         <item name="preferenceFrameLayoutStyle">@android:style/Widget.PreferenceFrameLayout</item>
 
@@ -397,7 +399,7 @@
         <item name="actionModeShareDrawable">@android:drawable/ic_menu_share_holo_light</item>
         <item name="actionModeFindDrawable">@android:drawable/ic_menu_find_holo_light</item>
         <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_light</item>
-        <item name="actionModeBackground">@android:drawable/cab_background_light</item>
+        <item name="actionModeBackground">@android:drawable/cab_background_opaque_holo_light</item>
 
         <!-- SearchView attributes -->
         <item name="searchDropdownBackground">@android:drawable/search_dropdown_light</item>
@@ -687,12 +689,24 @@
     <!-- Theme for the search input bar. -->
     <style name="Theme.SearchBar" parent="Theme.Holo.Light.Panel">
         <item name="windowContentOverlay">@null</item>        
+        <item name="actionModeBackground">@android:drawable/cab_background_opaque_holo_light</item>
     </style>
-    
+
+    <style name="Theme.Holo.SearchBar" parent="Theme.Holo.Panel">
+        <item name="windowContentOverlay">@null</item>
+        <item name="actionModeBackground">@android:drawable/cab_background_opaque_holo_dark</item>
+    </style>
+
+    <style name="Theme.Holo.Light.SearchBar" parent="Theme.Holo.Light.Panel">
+        <item name="windowContentOverlay">@null</item>
+        <item name="actionModeBackground">@android:drawable/cab_background_opaque_holo_light</item>
+    </style>
+
     <!-- Theme for the search input bar when doing global search. The only
          difference from non-global search is that we do not dim the background. -->
     <style name="Theme.GlobalSearchBar" parent="Theme.Panel">
         <item name="windowContentOverlay">@null</item>
+        <item name="actionModeBackground">@android:drawable/cab_background_opaque_holo_light</item>
     </style>
 
     <!-- Menu Themes -->
@@ -1028,6 +1042,8 @@
         <!-- SearchView attributes -->
         <item name="searchDropdownBackground">@android:drawable/search_dropdown_dark</item>
 
+        <item name="searchDialogTheme">@style/Theme.Holo.SearchBar</item>
+
         <!-- PreferenceFrameLayout attributes -->
         <item name="preferenceFrameLayoutStyle">@android:style/Widget.Holo.PreferenceFrameLayout</item>
 
@@ -1313,6 +1329,8 @@
         <!-- SearchView attributes -->
         <item name="searchDropdownBackground">@android:drawable/search_dropdown_light</item>
 
+        <item name="searchDialogTheme">@style/Theme.Holo.Light.SearchBar</item>
+
         <!-- NumberPicker attributes and styles-->
         <item name="numberPickerUpButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerUpButton</item>
         <item name="numberPickerDownButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerDownButton</item>
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 173412e..9e4e132 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -966,8 +966,7 @@
         struct {
             uint8_t screenLayout;
             uint8_t uiMode;
-            uint8_t screenConfigPad1;
-            uint8_t screenConfigPad2;
+            uint16_t smallestScreenWidthDp;
         };
         uint32_t screenConfig;
     };
@@ -1000,6 +999,7 @@
         screenHeight = dtohs(screenHeight);
         sdkVersion = dtohs(sdkVersion);
         minorVersion = dtohs(minorVersion);
+        smallestScreenWidthDp = dtohs(smallestScreenWidthDp);
         screenWidthDp = dtohs(screenWidthDp);
         screenHeightDp = dtohs(screenHeightDp);
     }
@@ -1013,6 +1013,7 @@
         screenHeight = htods(screenHeight);
         sdkVersion = htods(sdkVersion);
         minorVersion = htods(minorVersion);
+        smallestScreenWidthDp = htods(smallestScreenWidthDp);
         screenWidthDp = htods(screenWidthDp);
         screenHeightDp = htods(screenHeightDp);
     }
@@ -1034,6 +1035,8 @@
         if (diff != 0) return diff;
         diff = (int32_t)(uiMode - o.uiMode);
         if (diff != 0) return diff;
+        diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp);
+        if (diff != 0) return diff;
         diff = (int32_t)(screenSizeDp - o.screenSizeDp);
         return (int)diff;
     }
@@ -1052,6 +1055,7 @@
         CONFIG_ORIENTATION = ACONFIGURATION_ORIENTATION,
         CONFIG_DENSITY = ACONFIGURATION_DENSITY,
         CONFIG_SCREEN_SIZE = ACONFIGURATION_SCREEN_SIZE,
+        CONFIG_SMALLEST_SCREEN_SIZE = ACONFIGURATION_SMALLEST_SCREEN_SIZE,
         CONFIG_VERSION = ACONFIGURATION_VERSION,
         CONFIG_SCREEN_LAYOUT = ACONFIGURATION_SCREEN_LAYOUT,
         CONFIG_UI_MODE = ACONFIGURATION_UI_MODE
@@ -1075,6 +1079,7 @@
         if (version != o.version) diffs |= CONFIG_VERSION;
         if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
         if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
+        if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE;
         if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;
         return diffs;
     }
@@ -1109,14 +1114,10 @@
             }
         }
 
-        if (screenLayout || o.screenLayout) {
-            if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {
-                if (!(screenLayout & MASK_SCREENSIZE)) return false;
-                if (!(o.screenLayout & MASK_SCREENSIZE)) return true;
-            }
-            if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {
-                if (!(screenLayout & MASK_SCREENLONG)) return false;
-                if (!(o.screenLayout & MASK_SCREENLONG)) return true;
+        if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
+            if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
+                if (!smallestScreenWidthDp) return false;
+                if (!o.smallestScreenWidthDp) return true;
             }
         }
 
@@ -1132,6 +1133,17 @@
             }
         }
 
+        if (screenLayout || o.screenLayout) {
+            if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {
+                if (!(screenLayout & MASK_SCREENSIZE)) return false;
+                if (!(o.screenLayout & MASK_SCREENSIZE)) return true;
+            }
+            if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {
+                if (!(screenLayout & MASK_SCREENLONG)) return false;
+                if (!(o.screenLayout & MASK_SCREENLONG)) return true;
+            }
+        }
+
         if (orientation != o.orientation) {
             if (!orientation) return false;
             if (!o.orientation) return true;
@@ -1238,6 +1250,37 @@
                 }
             }
 
+            if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
+                // The configuration closest to the actual size is best.
+                // We assume that larger configs have already been filtered
+                // out at this point.  That means we just want the largest one.
+                return smallestScreenWidthDp >= o.smallestScreenWidthDp;
+            }
+
+            if (screenSizeDp || o.screenSizeDp) {
+                // "Better" is based on the sum of the difference between both
+                // width and height from the requested dimensions.  We are
+                // assuming the invalid configs (with smaller dimens) have
+                // already been filtered.  Note that if a particular dimension
+                // is unspecified, we will end up with a large value (the
+                // difference between 0 and the requested dimension), which is
+                // good since we will prefer a config that has specified a
+                // dimension value.
+                int myDelta = 0, otherDelta = 0;
+                if (requested->screenWidthDp) {
+                    myDelta += requested->screenWidthDp - screenWidthDp;
+                    otherDelta += requested->screenWidthDp - o.screenWidthDp;
+                }
+                if (requested->screenHeightDp) {
+                    myDelta += requested->screenHeightDp - screenHeightDp;
+                    otherDelta += requested->screenHeightDp - o.screenHeightDp;
+                }
+                //LOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
+                //    screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
+                //    requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
+                return (myDelta <= otherDelta);
+            }
+
             if (screenLayout || o.screenLayout) {
                 if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
                         && (requested->screenLayout & MASK_SCREENSIZE)) {
@@ -1270,30 +1313,6 @@
                 }
             }
 
-            if (screenSizeDp || o.screenSizeDp) {
-                // Better is based on the sum of the difference between both
-                // width and height from the requested dimensions.  We are
-                // assuming the invalid configs (with smaller dimens) have
-                // already been filtered.  Note that if a particular dimension
-                // is unspecified, we will end up with a large value (the
-                // difference between 0 and the requested dimension), which is
-                // good since we will prefer a config that has specified a
-                // dimension value.
-                int myDelta = 0, otherDelta = 0;
-                if (requested->screenWidthDp) {
-                    myDelta += requested->screenWidthDp - screenWidthDp;
-                    otherDelta += requested->screenWidthDp - o.screenWidthDp;
-                }
-                if (requested->screenHeightDp) {
-                    myDelta += requested->screenHeightDp - screenHeightDp;
-                    otherDelta += requested->screenHeightDp - o.screenHeightDp;
-                }
-                //LOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
-                //    screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
-                //    requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
-                return (myDelta <= otherDelta);
-            }
-
             if ((orientation != o.orientation) && requested->orientation) {
                 return (orientation);
             }
@@ -1388,14 +1407,24 @@
             }
 
             if (screenSize || o.screenSize) {
-                if ((screenWidth != o.screenWidth) && requested->screenWidth) {
-                    return (screenWidth);
+                // "Better" is based on the sum of the difference between both
+                // width and height from the requested dimensions.  We are
+                // assuming the invalid configs (with smaller sizes) have
+                // already been filtered.  Note that if a particular dimension
+                // is unspecified, we will end up with a large value (the
+                // difference between 0 and the requested dimension), which is
+                // good since we will prefer a config that has specified a
+                // size value.
+                int myDelta = 0, otherDelta = 0;
+                if (requested->screenWidth) {
+                    myDelta += requested->screenWidth - screenWidth;
+                    otherDelta += requested->screenWidth - o.screenWidth;
                 }
-
-                if ((screenHeight != o.screenHeight) &&
-                        requested->screenHeight) {
-                    return (screenHeight);
+                if (requested->screenHeight) {
+                    myDelta += requested->screenHeight - screenHeight;
+                    otherDelta += requested->screenHeight - o.screenHeight;
                 }
+                return (myDelta <= otherDelta);
             }
 
             if (version || o.version) {
@@ -1476,15 +1505,20 @@
                     && uiModeNight != setUiModeNight) {
                 return false;
             }
+
+            if (settings.smallestScreenWidthDp != 0 && smallestScreenWidthDp != 0
+                    && smallestScreenWidthDp > settings.smallestScreenWidthDp) {
+                return false;
+            }
         }
         if (screenSizeDp != 0) {
             if (settings.screenWidthDp != 0 && screenWidthDp != 0
-                && screenWidthDp > settings.screenWidthDp) {
+                    && screenWidthDp > settings.screenWidthDp) {
                 //LOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp);
                 return false;
             }
             if (settings.screenHeightDp != 0 && screenHeightDp != 0
-                && screenHeightDp > settings.screenHeightDp) {
+                    && screenHeightDp > settings.screenHeightDp) {
                 //LOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp);
                 return false;
             }
@@ -1531,11 +1565,11 @@
         }
         if (screenSize != 0) {
             if (settings.screenWidth != 0 && screenWidth != 0
-                && screenWidth != settings.screenWidth) {
+                && screenWidth > settings.screenWidth) {
                 return false;
             }
             if (settings.screenHeight != 0 && screenHeight != 0
-                && screenHeight != settings.screenHeight) {
+                && screenHeight > settings.screenHeight) {
                 return false;
             }
         }
@@ -1568,13 +1602,13 @@
     String8 toString() const {
         char buf[200];
         sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d "
-                "kbd=%d nav=%d input=%d ssz=%dx%d %ddp x %ddp sz=%d long=%d "
+                "kbd=%d nav=%d input=%d ssz=%dx%d sw%ddp w%ddp h%ddp sz=%d long=%d "
                 "ui=%d night=%d vers=%d.%d",
                 mcc, mnc,
                 language[0] ? language[0] : '-', language[1] ? language[1] : '-',
                 country[0] ? country[0] : '-', country[1] ? country[1] : '-',
                 orientation, touchscreen, density, keyboard, navigation, inputFlags,
-                screenWidth, screenHeight, screenWidthDp, screenHeightDp,
+                screenWidth, screenHeight, smallestScreenWidthDp, screenWidthDp, screenHeightDp,
                 screenLayout&MASK_SCREENSIZE, screenLayout&MASK_SCREENLONG,
                 uiMode&MASK_UI_MODE_TYPE, uiMode&MASK_UI_MODE_NIGHT,
                 sdkVersion, minorVersion);
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index aa9b40e..1ca0a19 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -35,6 +35,9 @@
 #define DEFAULT_TEXT_CACHE_WIDTH 1024
 #define DEFAULT_TEXT_CACHE_HEIGHT 256
 
+#define MAX_TEXT_CACHE_WIDTH 2048
+#define MAX_TEXT_CACHE_HEIGHT 2048
+
 ///////////////////////////////////////////////////////////////////////////////
 // Font
 ///////////////////////////////////////////////////////////////////////////////
@@ -386,9 +389,17 @@
 bool FontRenderer::cacheBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_t* retOriginY) {
     // If the glyph is too tall, don't cache it
     if (glyph.fHeight > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
-        LOGE("Font size to large to fit in cache. width, height = %i, %i",
-                (int) glyph.fWidth, (int) glyph.fHeight);
-        return false;
+        if (mCacheHeight < MAX_TEXT_CACHE_HEIGHT) {
+            // Default cache not large enough for large glyphs - resize cache to
+            // max size and try again
+            flushAllAndInvalidate();
+            initTextTexture(true);
+        }
+        if (glyph.fHeight > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
+            LOGE("Font size to large to fit in cache. width, height = %i, %i",
+                    (int) glyph.fWidth, (int) glyph.fHeight);
+            return false;
+        }
     }
 
     // Now copy the bitmap into the cache texture
@@ -446,16 +457,25 @@
     return true;
 }
 
-void FontRenderer::initTextTexture() {
+void FontRenderer::initTextTexture(bool largeFonts) {
+    mCacheLines.clear();
+    if (largeFonts) {
+        mCacheWidth = MAX_TEXT_CACHE_WIDTH;
+        mCacheHeight = MAX_TEXT_CACHE_HEIGHT;
+    }
+
     mTextTexture = new uint8_t[mCacheWidth * mCacheHeight];
     memset(mTextTexture, 0, mCacheWidth * mCacheHeight * sizeof(uint8_t));
 
     mUploadTexture = false;
 
+    if (mTextureId != 0) {
+        glDeleteTextures(1, &mTextureId);
+    }
     glGenTextures(1, &mTextureId);
     glBindTexture(GL_TEXTURE_2D, mTextureId);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    // Initialize texture dimentions
+    // Initialize texture dimensions
     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, mCacheWidth, mCacheHeight, 0,
             GL_ALPHA, GL_UNSIGNED_BYTE, 0);
 
@@ -480,6 +500,15 @@
     nextLine += mCacheLines.top()->mMaxHeight;
     mCacheLines.push(new CacheTextureLine(mCacheWidth, 42, nextLine, 0));
     nextLine += mCacheLines.top()->mMaxHeight;
+    if (largeFonts) {
+        int nextSize = 76;
+        // Make several new lines with increasing font sizes
+        while (nextSize < (int)(mCacheHeight - nextLine - (2 * nextSize))) {
+            mCacheLines.push(new CacheTextureLine(mCacheWidth, nextSize, nextLine, 0));
+            nextLine += mCacheLines.top()->mMaxHeight;
+            nextSize += 50;
+        }
+    }
     mCacheLines.push(new CacheTextureLine(mCacheWidth, mCacheHeight - nextLine, nextLine, 0));
 }
 
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index f685d5f..95f714f 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -229,7 +229,7 @@
         }
     };
 
-    void initTextTexture();
+    void initTextTexture(bool largeFonts = false);
     bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY);
 
     void flushAllAndInvalidate();
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 784c9d2..4a6a3db 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -2588,7 +2588,7 @@
 {
     mLock.lock();
     TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
-                        "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
+                        "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d sw%ddp w%ddp h%ddp\n",
                        params->mcc, params->mnc,
                        params->language[0] ? params->language[0] : '-',
                        params->language[1] ? params->language[1] : '-',
@@ -2602,6 +2602,7 @@
                        params->navigation,
                        params->screenWidth,
                        params->screenHeight,
+                       params->smallestScreenWidthDp,
                        params->screenWidthDp,
                        params->screenHeightDp));
     mParams = *params;
@@ -3927,7 +3928,7 @@
         TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d "
                             "lang:%c%c=%c%c cnt:%c%c=%c%c orien:%d=%d touch:%d=%d "
                             "density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d "
-                            "wdp:%d=%d hdp:%d=%d\n",
+                            "swdp:%d=%d wdp:%d=%d hdp:%d=%d\n",
                            entryIndex, typeIndex+1, dtohl(thisType->config.size),
                            thisConfig.mcc, thisConfig.mnc,
                            config ? config->mcc : 0, config ? config->mnc : 0,
@@ -3955,6 +3956,8 @@
                            config ? config->screenWidth : 0,
                            thisConfig.screenHeight,
                            config ? config->screenHeight : 0,
+                           thisConfig.smallestScreenWidthDp,
+                           config ? config->smallestScreenWidthDp : 0,
                            thisConfig.screenWidthDp,
                            config ? config->screenWidthDp : 0,
                            thisConfig.screenHeightDp,
@@ -4244,7 +4247,7 @@
                 thisConfig.copyFromDtoH(type->config);
                 LOGI("Adding config to type %d: imsi:%d/%d lang:%c%c cnt:%c%c "
                      "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d "
-                     "wdp:%d hdp:%d\n",
+                     "swdp:%d wdp:%d hdp:%d\n",
                       type->id,
                       thisConfig.mcc, thisConfig.mnc,
                       thisConfig.language[0] ? thisConfig.language[0] : '-',
@@ -4259,6 +4262,7 @@
                       thisConfig.navigation,
                       thisConfig.screenWidth,
                       thisConfig.screenHeight,
+                      thisConfig.smallestScreenWidthDp,
                       thisConfig.screenWidthDp,
                       thisConfig.screenHeightDp));
             t->configs.add(type);
@@ -4753,6 +4757,9 @@
                     if (type->config.screenHeight != 0) {
                         printf(" h=%d", dtohs(type->config.screenHeight));
                     }
+                    if (type->config.smallestScreenWidthDp != 0) {
+                        printf(" swdp=%d", dtohs(type->config.smallestScreenWidthDp));
+                    }
                     if (type->config.screenWidthDp != 0) {
                         printf(" wdp=%d", dtohs(type->config.screenWidthDp));
                     }
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index 821ba9b..ce30fc8 100644
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ b/media/libstagefright/NuHTTPDataSource.cpp
@@ -392,6 +392,13 @@
 
     Mutex::Autolock autoLock(mLock);
 
+    // if it's a DRM container based streaming, call pread() of the DRM plugin
+    // to get the decrypted data
+    if (mDecryptHandle != NULL && DecryptApiType::CONTAINER_BASED
+            == mDecryptHandle->decryptApiType) {
+        return mDrmManagerClient->pread(mDecryptHandle, data, size, offset);
+    }
+
     if (offset != mOffset) {
         String8 host = mHost;
         String8 path = mPath;
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
index af2f6ac..3e4e493 100644
--- a/media/libstagefright/chromium_http/support.cpp
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -24,6 +24,7 @@
 
 #include "android/net/android_network_library_impl.h"
 #include "base/thread.h"
+#include "net/base/cert_verifier.h"
 #include "net/base/host_resolver.h"
 #include "net/base/ssl_config_service.h"
 #include "net/http/http_auth_handler_factory.h"
@@ -127,6 +128,7 @@
 
     http_transaction_factory_ = new net::HttpCache(
             host_resolver_,
+            new net::CertVerifier(),
             dnsrr_resolver_,
             dns_cert_checker_.get(),
             proxy_service_.get(),
@@ -174,44 +176,44 @@
 }
 
 void SfDelegate::OnReceivedRedirect(
-            URLRequest *request, const GURL &new_url, bool *defer_redirect) {
+            net::URLRequest *request, const GURL &new_url, bool *defer_redirect) {
     MY_LOGI("OnReceivedRedirect");
 }
 
 void SfDelegate::OnAuthRequired(
-            URLRequest *request, net::AuthChallengeInfo *auth_info) {
+            net::URLRequest *request, net::AuthChallengeInfo *auth_info) {
     MY_LOGI("OnAuthRequired");
 
     inherited::OnAuthRequired(request, auth_info);
 }
 
 void SfDelegate::OnCertificateRequested(
-            URLRequest *request, net::SSLCertRequestInfo *cert_request_info) {
+            net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info) {
     MY_LOGI("OnCertificateRequested");
 
     inherited::OnCertificateRequested(request, cert_request_info);
 }
 
 void SfDelegate::OnSSLCertificateError(
-            URLRequest *request, int cert_error, net::X509Certificate *cert) {
+            net::URLRequest *request, int cert_error, net::X509Certificate *cert) {
     fprintf(stderr, "OnSSLCertificateError cert_error=%d\n", cert_error);
 
     inherited::OnSSLCertificateError(request, cert_error, cert);
 }
 
-void SfDelegate::OnGetCookies(URLRequest *request, bool blocked_by_policy) {
+void SfDelegate::OnGetCookies(net::URLRequest *request, bool blocked_by_policy) {
     MY_LOGI("OnGetCookies");
 }
 
 void SfDelegate::OnSetCookie(
-        URLRequest *request,
+        net::URLRequest *request,
         const std::string &cookie_line,
         const net::CookieOptions &options,
         bool blocked_by_policy) {
     MY_LOGI("OnSetCookie");
 }
 
-void SfDelegate::OnResponseStarted(URLRequest *request) {
+void SfDelegate::OnResponseStarted(net::URLRequest *request) {
     if (request->status().status() != URLRequestStatus::SUCCESS) {
         MY_LOGI(StringPrintf(
                     "Request failed with status %d and os_error %d",
@@ -260,7 +262,7 @@
             request->GetExpectedContentSize(), contentType.c_str());
 }
 
-void SfDelegate::OnReadCompleted(URLRequest *request, int bytes_read) {
+void SfDelegate::OnReadCompleted(net::URLRequest *request, int bytes_read) {
     if (bytes_read == -1) {
         MY_LOGI(StringPrintf(
                     "OnReadCompleted, read failed, status %d",
@@ -297,7 +299,7 @@
     readMore(request);
 }
 
-void SfDelegate::readMore(URLRequest *request) {
+void SfDelegate::readMore(net::URLRequest *request) {
     while (mNumBytesRead < mNumBytesTotal) {
         size_t copy = mNumBytesTotal - mNumBytesRead;
         if (copy > mReadBuffer->size()) {
@@ -371,7 +373,7 @@
         off64_t offset) {
     CHECK(mURLRequest == NULL);
 
-    mURLRequest = new URLRequest(url, this);
+    mURLRequest = new net::URLRequest(url, this);
     mAtEOS = false;
 
     mRangeRequested = false;
diff --git a/media/libstagefright/chromium_http/support.h b/media/libstagefright/chromium_http/support.h
index 634ac93..4d03493 100644
--- a/media/libstagefright/chromium_http/support.h
+++ b/media/libstagefright/chromium_http/support.h
@@ -77,7 +77,7 @@
 
 struct ChromiumHTTPDataSource;
 
-struct SfDelegate : public URLRequest::Delegate {
+struct SfDelegate : public net::URLRequest::Delegate {
     SfDelegate();
     virtual ~SfDelegate();
 
@@ -92,35 +92,35 @@
     void setOwner(ChromiumHTTPDataSource *mOwner);
 
     virtual void OnReceivedRedirect(
-            URLRequest *request, const GURL &new_url, bool *defer_redirect);
+            net::URLRequest *request, const GURL &new_url, bool *defer_redirect);
 
     virtual void OnAuthRequired(
-            URLRequest *request, net::AuthChallengeInfo *auth_info);
+            net::URLRequest *request, net::AuthChallengeInfo *auth_info);
 
     virtual void OnCertificateRequested(
-            URLRequest *request, net::SSLCertRequestInfo *cert_request_info);
+            net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info);
 
     virtual void OnSSLCertificateError(
-            URLRequest *request, int cert_error, net::X509Certificate *cert);
+            net::URLRequest *request, int cert_error, net::X509Certificate *cert);
 
-    virtual void OnGetCookies(URLRequest *request, bool blocked_by_policy);
+    virtual void OnGetCookies(net::URLRequest *request, bool blocked_by_policy);
 
     virtual void OnSetCookie(
-            URLRequest *request,
+            net::URLRequest *request,
             const std::string &cookie_line,
             const net::CookieOptions &options,
             bool blocked_by_policy);
 
-    virtual void OnResponseStarted(URLRequest *request);
+    virtual void OnResponseStarted(net::URLRequest *request);
 
-    virtual void OnReadCompleted(URLRequest *request, int bytes_read);
+    virtual void OnReadCompleted(net::URLRequest *request, int bytes_read);
 
 private:
     typedef Delegate inherited;
 
     ChromiumHTTPDataSource *mOwner;
 
-    URLRequest *mURLRequest;
+    net::URLRequest *mURLRequest;
     scoped_refptr<net::IOBufferWithSize> mReadBuffer;
 
     size_t mNumBytesRead;
@@ -130,7 +130,7 @@
     bool mRangeRequested;
     bool mAtEOS;
 
-    void readMore(URLRequest *request);
+    void readMore(net::URLRequest *request);
 
     static void OnInitiateConnectionWrapper(
             SfDelegate *me,
diff --git a/native/android/configuration.cpp b/native/android/configuration.cpp
index d76164f..687924b 100644
--- a/native/android/configuration.cpp
+++ b/native/android/configuration.cpp
@@ -111,6 +111,18 @@
 
 }
 
+int32_t AConfiguration_getScreenWidthDp(AConfiguration* config) {
+    return config->screenWidthDp;
+}
+
+int32_t AConfiguration_getScreenHeightDp(AConfiguration* config) {
+    return config->screenHeightDp;
+}
+
+int32_t AConfiguration_getSmallestScreenWidthDp(AConfiguration* config) {
+    return config->smallestScreenWidthDp;
+}
+
 // ----------------------------------------------------------------------
 
 void AConfiguration_setMcc(AConfiguration* config, int32_t mcc) {
@@ -186,6 +198,18 @@
 
 }
 
+void AConfiguration_setScreenWidthDp(AConfiguration* config, int32_t value) {
+    config->screenWidthDp = value;
+}
+
+void AConfiguration_setScreenHeightDp(AConfiguration* config, int32_t value) {
+    config->screenHeightDp = value;
+}
+
+void AConfiguration_setSmallestScreenWidthDp(AConfiguration* config, int32_t value) {
+    config->smallestScreenWidthDp = value;
+}
+
 // ----------------------------------------------------------------------
 
 int32_t AConfiguration_diff(AConfiguration* config1, AConfiguration* config2) {
diff --git a/native/include/android/configuration.h b/native/include/android/configuration.h
index 99e8f97..91533c8 100644
--- a/native/include/android/configuration.h
+++ b/native/include/android/configuration.h
@@ -82,6 +82,12 @@
     ACONFIGURATION_UI_MODE_NIGHT_NO = 0x1,
     ACONFIGURATION_UI_MODE_NIGHT_YES = 0x2,
 
+    ACONFIGURATION_SCREEN_WIDTH_DP_ANY = 0x0000,
+
+    ACONFIGURATION_SCREEN_HEIGHT_DP_ANY = 0x0000,
+
+    ACONFIGURATION_SMALLEST_SCREEN_WIDTH_DP_ANY = 0x0000,
+
     ACONFIGURATION_MCC = 0x0001,
     ACONFIGURATION_MNC = 0x0002,
     ACONFIGURATION_LOCALE = 0x0004,
@@ -95,6 +101,7 @@
     ACONFIGURATION_VERSION = 0x0400,
     ACONFIGURATION_SCREEN_LAYOUT = 0x0800,
     ACONFIGURATION_UI_MODE = 0x1000,
+    ACONFIGURATION_SMALLEST_SCREEN_SIZE = 0x2000,
 };
 
 /**
@@ -286,6 +293,39 @@
 void AConfiguration_setUiModeNight(AConfiguration* config, int32_t uiModeNight);
 
 /**
+ * Return the current configuration screen width in dp units, or
+ * ACONFIGURATION_SCREEN_WIDTH_DP_ANY if not set.
+ */
+int32_t AConfiguration_getScreenWidthDp(AConfiguration* config);
+
+/**
+ * Set the configuration's current screen width in dp units.
+ */
+void AConfiguration_setScreenWidthDp(AConfiguration* config, int32_t value);
+
+/**
+ * Return the current configuration screen height in dp units, or
+ * ACONFIGURATION_SCREEN_HEIGHT_DP_ANY if not set.
+ */
+int32_t AConfiguration_getScreenHeightDp(AConfiguration* config);
+
+/**
+ * Set the configuration's current screen width in dp units.
+ */
+void AConfiguration_setScreenHeightDp(AConfiguration* config, int32_t value);
+
+/**
+ * Return the configuration's smallest screen width in dp units, or
+ * ACONFIGURATION_SMALLEST_SCREEN_WIDTH_DP_ANY if not set.
+ */
+int32_t AConfiguration_getSmallestScreenWidthDp(AConfiguration* config);
+
+/**
+ * Set the configuration's smallest screen width in dp units.
+ */
+void AConfiguration_setSmallestScreenWidthDp(AConfiguration* config, int32_t value);
+
+/**
  * Perform a diff between two configurations.  Returns a bit mask of
  * ACONFIGURATION_* constants, each bit set meaning that configuration element
  * is different between them.
diff --git a/obex/javax/obex/PrivateOutputStream.java b/obex/javax/obex/PrivateOutputStream.java
index ca420af..713f4ae 100644
--- a/obex/javax/obex/PrivateOutputStream.java
+++ b/obex/javax/obex/PrivateOutputStream.java
@@ -107,18 +107,15 @@
 
         ensureOpen();
         mParent.ensureNotDone();
-        if (count < mMaxPacketSize) {
-            mArray.write(buffer, offset, count);
-        } else {
-            while (remainLength >= mMaxPacketSize) {
-                mArray.write(buffer, offset1, mMaxPacketSize);
-                offset1 += mMaxPacketSize;
-                remainLength = count - offset1;
-                mParent.continueOperation(true, false);
-            }
-            if (remainLength > 0) {
-                mArray.write(buffer, offset1, remainLength);
-            }
+        while ((mArray.size() + remainLength) >= mMaxPacketSize) {
+            int bufferLeft = mMaxPacketSize - mArray.size();
+            mArray.write(buffer, offset1, bufferLeft);
+            offset1 += bufferLeft;
+            remainLength -= bufferLeft;
+            mParent.continueOperation(true, false);
+        }
+        if (remainLength > 0) {
+            mArray.write(buffer, offset1, remainLength);
         }
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 03afc82..e5abeac 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -230,7 +230,7 @@
     boolean mSafeMode;
     WindowState mStatusBar = null;
     boolean mStatusBarCanHide;
-    int mScreenMarginBottom;
+    int mStatusBarHeight;
     final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>();
     WindowState mNavigationBar = null;
 
@@ -1071,12 +1071,20 @@
         return STATUS_BAR_LAYER;
     }
 
-    public int getNonDecorDisplayWidth(int fullWidth) {
+    public int getNonDecorDisplayWidth(int rotation, int fullWidth) {
         return fullWidth;
     }
 
-    public int getNonDecorDisplayHeight(int fullHeight) {
-        return fullHeight - mScreenMarginBottom;
+    public int getNonDecorDisplayHeight(int rotation, int fullHeight) {
+        return mStatusBarCanHide ? fullHeight : (fullHeight - mStatusBarHeight);
+    }
+
+    public int getConfigDisplayWidth(int rotation, int fullWidth) {
+        return fullWidth;
+    }
+
+    public int getConfigDisplayHeight(int rotation, int fullHeight) {
+        return fullHeight - mStatusBarHeight;
     }
 
     public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
@@ -1228,8 +1236,8 @@
                 // The Configuration will be stable by now, so we can load this
                 mStatusBarCanHide = mContext.getResources().getBoolean(
                         com.android.internal.R.bool.config_statusBarCanHide);
-                mScreenMarginBottom = mContext.getResources().getDimensionPixelSize(
-                        com.android.internal.R.dimen.screen_margin_bottom);
+                mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
+                        com.android.internal.R.dimen.status_bar_height);
 
                 break;
             case TYPE_NAVIGATION_BAR:
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 7028772..c365af5 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1371,31 +1371,70 @@
         }
     }
 
+    @Override
     public boolean switchToLastInputMethod(IBinder token) {
         synchronized (mMethodMap) {
             final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
-            if (lastIme == null) return false;
-            final InputMethodInfo lastImi = mMethodMap.get(lastIme.first);
-            if (lastImi == null) return false;
-
-            final boolean imiIdIsSame = lastImi.getId().equals(mCurMethodId);
-            final int lastSubtypeHash = Integer.valueOf(lastIme.second);
-            // If the last IME is the same as the current IME and the last subtype is not defined,
-            // there is no need to switch to the last IME.
-            if (imiIdIsSame && lastSubtypeHash == NOT_A_SUBTYPE_ID) return false;
-
-            int currentSubtypeHash = mCurrentSubtype == null ? NOT_A_SUBTYPE_ID
-                    : mCurrentSubtype.hashCode();
-            if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second + ", from: "
-                            + mCurMethodId + ", " + currentSubtypeHash);
-                }
-                setInputMethodWithSubtypeId(token, lastIme.first, getSubtypeIdFromHashCode(
-                        lastImi, lastSubtypeHash));
-                return true;
+            final InputMethodInfo lastImi;
+            if (lastIme != null) {
+                lastImi = mMethodMap.get(lastIme.first);
+            } else {
+                lastImi = null;
             }
-            return false;
+            String targetLastImiId = null;
+            int subtypeId = NOT_A_SUBTYPE_ID;
+            if (lastIme != null && lastImi != null) {
+                final boolean imiIdIsSame = lastImi.getId().equals(mCurMethodId);
+                final int lastSubtypeHash = Integer.valueOf(lastIme.second);
+                final int currentSubtypeHash = mCurrentSubtype == null ? NOT_A_SUBTYPE_ID
+                        : mCurrentSubtype.hashCode();
+                // If the last IME is the same as the current IME and the last subtype is not
+                // defined, there is no need to switch to the last IME.
+                if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) {
+                    targetLastImiId = lastIme.first;
+                    subtypeId = getSubtypeIdFromHashCode(lastImi, lastSubtypeHash);
+                }
+            }
+
+            if (TextUtils.isEmpty(targetLastImiId) && !canAddToLastInputMethod(mCurrentSubtype)) {
+                // This is a safety net. If the currentSubtype can't be added to the history
+                // and the framework couldn't find the last ime, we will make the last ime be
+                // the most applicable enabled keyboard subtype of the system imes.
+                final List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked();
+                if (enabled != null) {
+                    final int N = enabled.size();
+                    final String locale = mCurrentSubtype == null
+                            ? mRes.getConfiguration().locale.toString()
+                            : mCurrentSubtype.getLocale();
+                    for (int i = 0; i < N; ++i) {
+                        final InputMethodInfo imi = enabled.get(i);
+                        if (imi.getSubtypeCount() > 0 && isSystemIme(imi)) {
+                            InputMethodSubtype keyboardSubtype =
+                                    findLastResortApplicableSubtypeLocked(mRes, getSubtypes(imi),
+                                            SUBTYPE_MODE_KEYBOARD, locale, true);
+                            if (keyboardSubtype != null) {
+                                targetLastImiId = imi.getId();
+                                subtypeId = getSubtypeIdFromHashCode(
+                                        imi, keyboardSubtype.hashCode());
+                                if(keyboardSubtype.getLocale().equals(locale)) {
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (!TextUtils.isEmpty(targetLastImiId)) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second
+                            + ", from: " + mCurMethodId + ", " + subtypeId);
+                }
+                setInputMethodWithSubtypeId(token, targetLastImiId, subtypeId);
+                return true;
+            } else {
+                return false;
+            }
         }
     }
 
@@ -2619,7 +2658,7 @@
             List<Pair<String, ArrayList<String>>> enabledImes =
                     getEnabledInputMethodsAndSubtypeListLocked();
             List<Pair<String, String>> subtypeHistory = loadInputMethodAndSubtypeHistoryLocked();
-            for (Pair<String, String> imeAndSubtype: subtypeHistory) {
+            for (Pair<String, String> imeAndSubtype : subtypeHistory) {
                 final String imeInTheHistory = imeAndSubtype.first;
                 // If imeId is empty, returns the first IME and subtype in the history
                 if (TextUtils.isEmpty(imeId) || imeInTheHistory.equals(imeId)) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 9890bec..92c490e 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -4783,8 +4783,8 @@
         synchronized(mWindowMap) {
             long ident = Binder.clearCallingIdentity();
 
-            dw = mPolicy.getNonDecorDisplayWidth(mCurDisplayWidth);
-            dh = mPolicy.getNonDecorDisplayHeight(mCurDisplayHeight);
+            dw = mPolicy.getNonDecorDisplayWidth(mRotation, mCurDisplayWidth);
+            dh = mPolicy.getNonDecorDisplayHeight(mRotation, mCurDisplayHeight);
 
             int aboveAppLayer = mPolicy.windowTypeToLayerLw(
                     WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
@@ -5501,6 +5501,14 @@
         return config;
     }
 
+    private int reduceConfigWidthSize(int curSize, int rotation, float density, int dw) {
+        int size = (int)(mPolicy.getConfigDisplayWidth(rotation, dw) / density);
+        if (size < curSize) {
+            curSize = size;
+        }
+        return curSize;
+    }
+
     boolean computeNewConfigurationLocked(Configuration config) {
         if (mDisplay == null) {
             return false;
@@ -5551,14 +5559,37 @@
 
         // Override display width and height with what we are computing,
         // to be sure they remain consistent.
-        dm.widthPixels = dm.realWidthPixels = mPolicy.getNonDecorDisplayWidth(dw);
-        dm.heightPixels = dm.realHeightPixels = mPolicy.getNonDecorDisplayHeight(dh);
+        dm.widthPixels = dm.realWidthPixels = mPolicy.getNonDecorDisplayWidth(
+                mRotation, dw);
+        dm.heightPixels = dm.realHeightPixels = mPolicy.getNonDecorDisplayHeight(
+                mRotation, dh);
 
         mCompatibleScreenScale = CompatibilityInfo.updateCompatibleScreenFrame(
                 dm, mCompatibleScreenFrame, null);
 
-        config.screenWidthDp = (int)(dm.widthPixels / dm.density);
-        config.screenHeightDp = (int)(dm.heightPixels / dm.density);
+        config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(mRotation, dw) / dm.density);
+        config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(mRotation, dh) / dm.density);
+
+        // We need to determine the smallest width that will occur under normal
+        // operation.  To this, start with the base screen size and compute the
+        // width under the different possible rotations.  We need to un-rotate
+        // the current screen dimensions before doing this.
+        int unrotDw, unrotDh;
+        if (rotated) {
+            unrotDw = dh;
+            unrotDh = dw;
+        } else {
+            unrotDw = dw;
+            unrotDh = dh;
+        }
+        config.smallestScreenWidthDp = reduceConfigWidthSize(unrotDw,
+                Surface.ROTATION_0, dm.density, unrotDw);
+        config.smallestScreenWidthDp = reduceConfigWidthSize(config.smallestScreenWidthDp,
+                Surface.ROTATION_90, dm.density, unrotDh);
+        config.smallestScreenWidthDp = reduceConfigWidthSize(config.smallestScreenWidthDp,
+                Surface.ROTATION_180, dm.density, unrotDw);
+        config.smallestScreenWidthDp = reduceConfigWidthSize(config.smallestScreenWidthDp,
+                Surface.ROTATION_270, dm.density, unrotDh);
 
         // Compute the screen layout size class.
         int screenLayout;
@@ -6810,9 +6841,6 @@
         final int dw = mCurDisplayWidth;
         final int dh = mCurDisplayHeight;
 
-        final int innerDw = mPolicy.getNonDecorDisplayWidth(dw);
-        final int innerDh = mPolicy.getNonDecorDisplayHeight(dh);
-
         final int N = mWindows.size();
         int i;
 
@@ -6933,8 +6961,8 @@
         final int dw = mCurDisplayWidth;
         final int dh = mCurDisplayHeight;
 
-        final int innerDw = mPolicy.getNonDecorDisplayWidth(dw);
-        final int innerDh = mPolicy.getNonDecorDisplayHeight(dh);
+        final int innerDw = mPolicy.getNonDecorDisplayWidth(mRotation, dw);
+        final int innerDh = mPolicy.getNonDecorDisplayHeight(mRotation, dh);
 
         int i;
 
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
index 3c8432e..7bf25cf 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
@@ -38,6 +38,7 @@
         private final Paint mStrikePaint;
         private final Paint mScaledPaint;
         private final Paint mSkewPaint;
+        private final Paint mHugePaint;
 
         CustomTextView(Context c) {
             super(c);
@@ -64,6 +65,11 @@
             mSkewPaint.setAntiAlias(true);
             mSkewPaint.setTextSize(16.0f);
             mSkewPaint.setShadowLayer(3.0f, 3.0f, 3.0f, 0xff000000);
+
+            mHugePaint = new Paint();
+            mHugePaint.setAntiAlias(true);
+            mHugePaint.setColor(0xff000000);
+            mHugePaint.setTextSize(300f);
         }
 
         @Override
@@ -98,7 +104,9 @@
             mLargePaint.setAlpha(255);
             mLargePaint.setColor(0xff000000);
             mLargePaint.clearShadowLayer();
-            
+
+            canvas.drawText("Hello!", 500, 600, mHugePaint);
+
             canvas.drawText("Hello OpenGL renderer!", 500, 40, mStrikePaint);
             mStrikePaint.setStrikeThruText(true);
             canvas.drawText("Hello OpenGL renderer!", 500, 70, mStrikePaint);
@@ -106,7 +114,7 @@
             canvas.drawText("Hello OpenGL renderer!", 500, 100, mStrikePaint);
             mStrikePaint.setStrikeThruText(false);
             mStrikePaint.setUnderlineText(true);
-            
+
             mSkewPaint.setTextSkewX(-0.25f);
             canvas.drawText("Hello OpenGL renderer!", 980, 200, mSkewPaint);
             mSkewPaint.setTextSkewX(0.5f);
@@ -120,11 +128,12 @@
             canvas.drawText("Hello OpenGL renderer!", 500, 230, mScaledPaint);
             mScaledPaint.setTextScaleX(2.0f);
             canvas.drawText("Hello OpenGL renderer!", 500, 260, mScaledPaint);
-            
+
             canvas.save();
             canvas.clipRect(150.0f, 220.0f, 450.0f, 320.0f);
             canvas.drawText("Hello OpenGL renderer!", 100, 300, mLargePaint);
             canvas.restore();
+
         }
     }
 }
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
index 7cd55fa..5377f12 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
@@ -81,8 +81,6 @@
     private Sampler mLinearWrap;
     private Sampler mMipLinearWrap;
     private Sampler mNearestClamp;
-    private Sampler mMipLinearAniso8;
-    private Sampler mMipLinearAniso15;
 
     private ProgramStore mProgStoreBlendNoneDepth;
     private ProgramStore mProgStoreBlendNone;
@@ -123,10 +121,6 @@
 
     Font mFontSans;
     Font mFontSerif;
-    Font mFontSerifBold;
-    Font mFontSerifItalic;
-    Font mFontSerifBoldItalic;
-    Font mFontMono;
     private Allocation mTextAlloc;
 
     private ScriptC_rsbench mScript;
@@ -410,20 +404,11 @@
         mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
         mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
         // Create fonts by family and style
-        mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
-        mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
-        mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
-        mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
 
         mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
 
         mScript.set_gFontSans(mFontSans);
         mScript.set_gFontSerif(mFontSerif);
-        mScript.set_gFontSerifBold(mFontSerifBold);
-        mScript.set_gFontSerifItalic(mFontSerifItalic);
-        mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic);
-        mScript.set_gFontMono(mFontMono);
-        mScript.set_gTextAlloc(mTextAlloc);
     }
 
     private void initMesh() {
@@ -456,21 +441,9 @@
         mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
         mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
 
-        bs = new Sampler.Builder(mRS);
-        bs.setMinification(Sampler.Value.LINEAR_MIP_LINEAR);
-        bs.setMagnification(Sampler.Value.LINEAR);
-        bs.setWrapS(Sampler.Value.WRAP);
-        bs.setWrapT(Sampler.Value.WRAP);
-        bs.setAnisotropy(8.0f);
-        mMipLinearAniso8 = bs.create();
-        bs.setAnisotropy(15.0f);
-        mMipLinearAniso15 = bs.create();
-
         mScript.set_gLinearClamp(mLinearClamp);
         mScript.set_gLinearWrap(mLinearWrap);
         mScript.set_gMipLinearWrap(mMipLinearWrap);
-        mScript.set_gMipLinearAniso8(mMipLinearAniso8);
-        mScript.set_gMipLinearAniso15(mMipLinearAniso15);
         mScript.set_gNearestClamp(mNearestClamp);
     }
 
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
index 198e3f8..e7f5cd4 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
@@ -52,19 +52,12 @@
 
 rs_font gFontSans;
 rs_font gFontSerif;
-rs_font gFontSerifBold;
-rs_font gFontSerifItalic;
-rs_font gFontSerifBoldItalic;
-rs_font gFontMono;
-rs_allocation gTextAlloc;
 
 int gDisplayMode;
 
 rs_sampler gLinearClamp;
 rs_sampler gLinearWrap;
 rs_sampler gMipLinearWrap;
-rs_sampler gMipLinearAniso8;
-rs_sampler gMipLinearAniso15;
 rs_sampler gNearestClamp;
 
 rs_program_raster gCullBack;
@@ -117,8 +110,8 @@
     rs_font fonts[5];
     fonts[0] = gFontSans;
     fonts[1] = gFontSerif;
-    fonts[2] = gFontSerifBold;
-    fonts[3] = gFontSerifBoldItalic;
+    fonts[2] = gFontSans;
+    fonts[3] = gFontSerif;
     fonts[4] = gFontSans;
 
     uint width = gRenderSurfaceW;
@@ -183,52 +176,6 @@
     }
 }
 
-static void displayBlendingSamples() {
-    int i;
-
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    rsgBindProgramFragment(gProgFragmentColor);
-
-    rsgBindProgramStore(gProgStoreBlendNone);
-    for (i = 0; i < 3; i ++) {
-        float iPlusOne = (float)(i + 1);
-        rsgProgramFragmentConstantColor(gProgFragmentColor,
-                                        0.1f*iPlusOne, 0.2f*iPlusOne, 0.3f*iPlusOne, 1);
-        float yPos = 150 * (float)i;
-        rsgDrawRect(0, yPos, 200, yPos + 200, 0);
-    }
-
-    rsgBindProgramStore(gProgStoreBlendAlpha);
-    for (i = 0; i < 3; i ++) {
-        float iPlusOne = (float)(i + 1);
-        rsgProgramFragmentConstantColor(gProgFragmentColor,
-                                        0.2f*iPlusOne, 0.3f*iPlusOne, 0.1f*iPlusOne, 0.5);
-        float yPos = 150 * (float)i;
-        rsgDrawRect(150, yPos, 350, yPos + 200, 0);
-    }
-
-    rsgBindProgramStore(gProgStoreBlendAdd);
-    for (i = 0; i < 3; i ++) {
-        float iPlusOne = (float)(i + 1);
-        rsgProgramFragmentConstantColor(gProgFragmentColor,
-                                        0.3f*iPlusOne, 0.1f*iPlusOne, 0.2f*iPlusOne, 0.5);
-        float yPos = 150 * (float)i;
-        rsgDrawRect(300, yPos, 500, yPos + 200, 0);
-    }
-
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("No Blending", 10, 50);
-    rsgDrawText("Alpha Blending", 160, 150);
-    rsgDrawText("Additive Blending", 320, 250);
-
-}
-
 static void displayMeshSamples(int meshNum) {
 
     bindProgramVertexOrtho();
@@ -251,61 +198,6 @@
     }
 }
 
-static void displayTextureSamplers() {
-
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNone);
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
-
-    // Linear clamp
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
-    float startX = 0, startY = 0;
-    float width = 300, height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.1,
-                         startX + width, startY + height, 0, 1.1, 1.1,
-                         startX + width, startY, 0, 1.1, 0);
-
-    // Linear Wrap
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap);
-    startX = 0; startY = 300;
-    width = 300; height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.1,
-                         startX + width, startY + height, 0, 1.1, 1.1,
-                         startX + width, startY, 0, 1.1, 0);
-
-    // Nearest
-    rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp);
-    startX = 300; startY = 0;
-    width = 300; height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.1,
-                         startX + width, startY + height, 0, 1.1, 1.1,
-                         startX + width, startY, 0, 1.1, 0);
-
-    rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
-    startX = 300; startY = 300;
-    width = 300; height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.5,
-                         startX + width, startY + height, 0, 1.5, 1.5,
-                         startX + width, startY, 0, 1.5, 0);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("Filtering: linear clamp", 10, 290);
-    rsgDrawText("Filtering: linear wrap", 10, 590);
-    rsgDrawText("Filtering: nearest clamp", 310, 290);
-    rsgDrawText("Filtering: miplinear wrap", 310, 590);
-}
-
 static float gTorusRotation = 0;
 static void updateModelMatrix(rs_matrix4x4 *matrix, void *buffer) {
     if (buffer == 0) {
@@ -354,7 +246,6 @@
     }
 }
 
-
 // Quick hack to get some geometry numbers
 static void displaySimpleGeoSamples(bool useTexture, int numMeshes) {
     rsgBindProgramVertex(gProgVertex);
@@ -545,66 +436,6 @@
     }
 }
 
-static float gAnisoTime = 0.0f;
-static uint anisoMode = 0;
-static void displayAnisoSample() {
-
-    gAnisoTime += gDt;
-
-    rsgBindProgramVertex(gProgVertex);
-    float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH;
-    rs_matrix4x4 proj;
-    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
-    rsgProgramVertexLoadProjectionMatrix(&proj);
-
-    rs_matrix4x4 matrix;
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNone);
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -10.0f);
-    rsMatrixRotate(&matrix, -80, 1.0f, 0.0f, 0.0f);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    rsgBindProgramRaster(gCullNone);
-
-    rsgBindTexture(gProgFragmentTexture, 0, gTexChecker);
-
-    if (gAnisoTime >= 5.0f) {
-        gAnisoTime = 0.0f;
-        anisoMode ++;
-        anisoMode = anisoMode % 3;
-    }
-
-    if (anisoMode == 0) {
-        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso8);
-    } else if (anisoMode == 1) {
-        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso15);
-    } else {
-        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
-    }
-
-    float startX = -15;
-    float startY = -15;
-    float width = 30;
-    float height = 30;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 10,
-                         startX + width, startY + height, 0, 10, 10,
-                         startX + width, startY, 0, 10, 0);
-
-    rsgBindProgramRaster(gCullBack);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    if (anisoMode == 0) {
-        rsgDrawText("Anisotropic filtering 8", 10, 40);
-    } else if (anisoMode == 1) {
-        rsgDrawText("Anisotropic filtering 15", 10, 40);
-    } else {
-        rsgDrawText("Miplinear filtering", 10, 40);
-    }
-}
-
 static bool checkInit() {
 
     static int countdown = 5;
@@ -613,20 +444,17 @@
     if(countdown > 1) {
         displayFontSamples(5);
         displaySingletexFill(true, 3);
-        displayBlendingSamples();
         displayMeshSamples(0);
         displayMeshSamples(1);
         displayMeshSamples(2);
-        displayTextureSamplers();
         displayMultitextureSample(true, 5);
-        displayAnisoSample();
         displayPixelLightSamples(1, false);
         displayPixelLightSamples(1, true);
         countdown --;
         rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
 
         rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
-        rsgBindFont(gFontSerifBoldItalic);
+        rsgBindFont(gFontSerif);
         if (countdown == 1) {
             rsgDrawText("Rendering", 50, 50);
         } else {
@@ -831,7 +659,7 @@
     uint width = rsgGetWidth();
     uint height = rsgGetHeight();
     rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
-    rsgBindFont(gFontSerifBoldItalic);
+    rsgBindFont(gFontSerif);
     rsgMeasureText(text, &left, &right, &top, &bottom);
     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
     rsgDrawText(text, 2 -left, height - 2 + bottom);
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh
index 1d77ea9..648359c 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh
@@ -30,15 +30,6 @@
     float light1_CosinePower;
 } VertexShaderConstants;
 
-typedef struct VertexShaderConstants2_s {
-    rs_matrix4x4 model[2];
-    rs_matrix4x4 proj;
-    float4 light_Posision[2];
-    float light_Diffuse[2];
-    float light_Specular[2];
-    float light_CosinePower[2];
-} VertexShaderConstants2;
-
 typedef struct VertexShaderConstants3_s {
     rs_matrix4x4 model;
     rs_matrix4x4 proj;
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index a2271d9..75535f8 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -142,17 +142,10 @@
         return 0;
     }
 
-    // screen layout size
-    if (getScreenLayoutSizeName(part.string(), &config)) {
-        *axis = AXIS_SCREENLAYOUTSIZE;
-        *value = (config.screenLayout&ResTable_config::MASK_SCREENSIZE);
-        return 0;
-    }
-
-    // screen layout long
-    if (getScreenLayoutLongName(part.string(), &config)) {
-        *axis = AXIS_SCREENLAYOUTLONG;
-        *value = (config.screenLayout&ResTable_config::MASK_SCREENLONG);
+    // smallest screen dp width
+    if (getSmallestScreenWidthDpName(part.string(), &config)) {
+        *axis = AXIS_SMALLESTSCREENWIDTHDP;
+        *value = config.smallestScreenWidthDp;
         return 0;
     }
 
@@ -170,6 +163,20 @@
         return 0;
     }
 
+    // screen layout size
+    if (getScreenLayoutSizeName(part.string(), &config)) {
+        *axis = AXIS_SCREENLAYOUTSIZE;
+        *value = (config.screenLayout&ResTable_config::MASK_SCREENSIZE);
+        return 0;
+    }
+
+    // screen layout long
+    if (getScreenLayoutLongName(part.string(), &config)) {
+        *axis = AXIS_SCREENLAYOUTLONG;
+        *value = (config.screenLayout&ResTable_config::MASK_SCREENLONG);
+        return 0;
+    }
+
     // orientation
     if (getOrientationName(part.string(), &config)) {
         *axis = AXIS_ORIENTATION;
@@ -257,7 +264,7 @@
 
     String8 mcc, mnc, loc, layoutsize, layoutlong, orient, den;
     String8 touch, key, keysHidden, nav, navHidden, size, vers;
-    String8 uiModeType, uiModeNight, widthdp, heightdp;
+    String8 uiModeType, uiModeNight, smallestwidthdp, widthdp, heightdp;
 
     const char *p = dir;
     const char *q;
@@ -344,8 +351,8 @@
         //printf("not region: %s\n", part.string());
     }
 
-    if (getScreenLayoutSizeName(part.string())) {
-        layoutsize = part;
+    if (getSmallestScreenWidthDpName(part.string())) {
+        smallestwidthdp = part;
 
         index++;
         if (index == N) {
@@ -353,19 +360,7 @@
         }
         part = parts[index];
     } else {
-        //printf("not screen layout size: %s\n", part.string());
-    }
-
-    if (getScreenLayoutLongName(part.string())) {
-        layoutlong = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not screen layout long: %s\n", part.string());
+        //printf("not smallest screen width dp: %s\n", part.string());
     }
 
     if (getScreenWidthDpName(part.string())) {
@@ -392,6 +387,30 @@
         //printf("not screen height dp: %s\n", part.string());
     }
 
+    if (getScreenLayoutSizeName(part.string())) {
+        layoutsize = part;
+
+        index++;
+        if (index == N) {
+            goto success;
+        }
+        part = parts[index];
+    } else {
+        //printf("not screen layout size: %s\n", part.string());
+    }
+
+    if (getScreenLayoutLongName(part.string())) {
+        layoutlong = part;
+
+        index++;
+        if (index == N) {
+            goto success;
+        }
+        part = parts[index];
+    } else {
+        //printf("not screen layout long: %s\n", part.string());
+    }
+
     // orientation
     if (getOrientationName(part.string())) {
         orient = part;
@@ -541,6 +560,7 @@
     this->locale = loc;
     this->screenLayoutSize = layoutsize;
     this->screenLayoutLong = layoutlong;
+    this->smallestScreenWidthDp = smallestwidthdp;
     this->screenWidthDp = widthdp;
     this->screenHeightDp = heightdp;
     this->orientation = orient;
@@ -570,14 +590,16 @@
     s += ",";
     s += this->locale;
     s += ",";
-    s += screenLayoutSize;
-    s += ",";
-    s += screenLayoutLong;
+    s += smallestScreenWidthDp;
     s += ",";
     s += screenWidthDp;
     s += ",";
     s += screenHeightDp;
     s += ",";
+    s += screenLayoutSize;
+    s += ",";
+    s += screenLayoutLong;
+    s += ",";
     s += this->orientation;
     s += ",";
     s += uiModeType;
@@ -618,13 +640,9 @@
         s += "-";
         s += locale;
     }
-    if (this->screenLayoutSize != "") {
+    if (this->smallestScreenWidthDp != "") {
         s += "-";
-        s += screenLayoutSize;
-    }
-    if (this->screenLayoutLong != "") {
-        s += "-";
-        s += screenLayoutLong;
+        s += smallestScreenWidthDp;
     }
     if (this->screenWidthDp != "") {
         s += "-";
@@ -634,6 +652,14 @@
         s += "-";
         s += screenHeightDp;
     }
+    if (this->screenLayoutSize != "") {
+        s += "-";
+        s += screenLayoutSize;
+    }
+    if (this->screenLayoutLong != "") {
+        s += "-";
+        s += screenLayoutLong;
+    }
     if (this->orientation != "") {
         s += "-";
         s += orientation;
@@ -1126,6 +1152,31 @@
     return true;
 }
 
+bool AaptGroupEntry::getSmallestScreenWidthDpName(const char* name, ResTable_config* out)
+{
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) {
+            out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
+        }
+        return true;
+    }
+
+    if (*name != 's') return false;
+    name++;
+    if (*name != 'w') return false;
+    name++;
+    const char* x = name;
+    while (*x >= '0' && *x <= '9') x++;
+    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+    String8 xName(name, x-name);
+
+    if (out) {
+        out->smallestScreenWidthDp = (uint16_t)atoi(xName.string());
+    }
+
+    return true;
+}
+
 bool AaptGroupEntry::getScreenWidthDpName(const char* name, ResTable_config* out)
 {
     if (strcmp(name, kWildcardName) == 0) {
@@ -1206,10 +1257,11 @@
     if (v == 0) v = mnc.compare(o.mnc);
     if (v == 0) v = locale.compare(o.locale);
     if (v == 0) v = vendor.compare(o.vendor);
-    if (v == 0) v = screenLayoutSize.compare(o.screenLayoutSize);
-    if (v == 0) v = screenLayoutLong.compare(o.screenLayoutLong);
+    if (v == 0) v = smallestScreenWidthDp.compare(o.smallestScreenWidthDp);
     if (v == 0) v = screenWidthDp.compare(o.screenWidthDp);
     if (v == 0) v = screenHeightDp.compare(o.screenHeightDp);
+    if (v == 0) v = screenLayoutSize.compare(o.screenLayoutSize);
+    if (v == 0) v = screenLayoutLong.compare(o.screenLayoutLong);
     if (v == 0) v = orientation.compare(o.orientation);
     if (v == 0) v = uiModeType.compare(o.uiModeType);
     if (v == 0) v = uiModeNight.compare(o.uiModeNight);
@@ -1231,10 +1283,11 @@
     getMccName(mcc.string(), &params);
     getMncName(mnc.string(), &params);
     getLocaleName(locale.string(), &params);
-    getScreenLayoutSizeName(screenLayoutSize.string(), &params);
-    getScreenLayoutLongName(screenLayoutLong.string(), &params);
+    getSmallestScreenWidthDpName(smallestScreenWidthDp.string(), &params);
     getScreenWidthDpName(screenWidthDp.string(), &params);
     getScreenHeightDpName(screenHeightDp.string(), &params);
+    getScreenLayoutSizeName(screenLayoutSize.string(), &params);
+    getScreenLayoutLongName(screenLayoutLong.string(), &params);
     getOrientationName(orientation.string(), &params);
     getUiModeTypeName(uiModeType.string(), &params);
     getUiModeNightName(uiModeNight.string(), &params);
@@ -1249,9 +1302,10 @@
     
     // Fix up version number based on specified parameters.
     int minSdk = 0;
-    if (params.screenWidthDp != ResTable_config::SCREENWIDTH_ANY
+    if (params.smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY
+            || params.screenWidthDp != ResTable_config::SCREENWIDTH_ANY
             || params.screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
-        minSdk = SDK_ICS;
+        minSdk = SDK_HONEYCOMB_MR2;
     } else if ((params.uiMode&ResTable_config::MASK_UI_MODE_TYPE)
                 != ResTable_config::UI_MODE_TYPE_ANY
             ||  (params.uiMode&ResTable_config::MASK_UI_MODE_NIGHT)
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index e5afd1b..65743d8 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -42,6 +42,7 @@
     AXIS_NAVHIDDEN,
     AXIS_NAVIGATION,
     AXIS_SCREENSIZE,
+    AXIS_SMALLESTSCREENWIDTHDP,
     AXIS_SCREENWIDTHDP,
     AXIS_SCREENHEIGHTDP,
     AXIS_VERSION
@@ -54,7 +55,7 @@
     SDK_ECLAIR_0_1 = 6,
     SDK_MR1 = 7,
     SDK_FROYO = 8,
-    SDK_ICS = 13,
+    SDK_HONEYCOMB_MR2 = 13,
 };
 
 /**
@@ -72,10 +73,11 @@
     String8 mnc;
     String8 locale;
     String8 vendor;
-    String8 screenLayoutSize;
-    String8 screenLayoutLong;
+    String8 smallestScreenWidthDp;
     String8 screenWidthDp;
     String8 screenHeightDp;
+    String8 screenLayoutSize;
+    String8 screenLayoutLong;
     String8 orientation;
     String8 uiModeType;
     String8 uiModeNight;
@@ -107,6 +109,7 @@
     static bool getNavigationName(const char* name, ResTable_config* out = NULL);
     static bool getNavHiddenName(const char* name, ResTable_config* out = NULL);
     static bool getScreenSizeName(const char* name, ResTable_config* out = NULL);
+    static bool getSmallestScreenWidthDpName(const char* name, ResTable_config* out = NULL);
     static bool getScreenWidthDpName(const char* name, ResTable_config* out = NULL);
     static bool getScreenHeightDpName(const char* name, ResTable_config* out = NULL);
     static bool getVersionName(const char* name, ResTable_config* out = NULL);
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index a88476e..5c5b4fd 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2607,6 +2607,9 @@
     if (!match(AXIS_SCREENSIZE, config.screenSize)) {
         return false;
     }
+    if (!match(AXIS_SMALLESTSCREENWIDTHDP, config.smallestScreenWidthDp)) {
+        return false;
+    }
     if (!match(AXIS_SCREENWIDTHDP, config.screenWidthDp)) {
         return false;
     }
@@ -2809,7 +2812,8 @@
                 ConfigDescription config = t->getUniqueConfigs().itemAt(ci);
 
                 NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
-                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
+                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
+                     "sw%ddp w%ddp h%ddp\n",
                       ti+1,
                       config.mcc, config.mnc,
                       config.language[0] ? config.language[0] : '-',
@@ -2825,6 +2829,7 @@
                       config.navigation,
                       config.screenWidth,
                       config.screenHeight,
+                      config.smallestScreenWidthDp,
                       config.screenWidthDp,
                       config.screenHeightDp));
                       
@@ -2849,7 +2854,8 @@
                 tHeader->entriesStart = htodl(typeSize);
                 tHeader->config = config;
                 NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
-                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
+                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
+                     "sw%ddp w%ddp h%ddp\n",
                       ti+1,
                       tHeader->config.mcc, tHeader->config.mnc,
                       tHeader->config.language[0] ? tHeader->config.language[0] : '-',
@@ -2865,6 +2871,7 @@
                       tHeader->config.navigation,
                       tHeader->config.screenWidth,
                       tHeader->config.screenHeight,
+                      tHeader->config.smallestScreenWidthDp,
                       tHeader->config.screenWidthDp,
                       tHeader->config.screenHeightDp));
                 tHeader->config.swapHtoD();
@@ -3448,7 +3455,8 @@
     if (e == NULL) {
         if (config != NULL) {
             NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
-                    "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
+                    "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
+                    "sw%ddp w%ddp h%ddp\n",
                       sourcePos.file.string(), sourcePos.line,
                       config->mcc, config->mnc,
                       config->language[0] ? config->language[0] : '-',
@@ -3463,6 +3471,7 @@
                       config->navigation,
                       config->screenWidth,
                       config->screenHeight,
+                      config->smallestScreenWidthDp,
                       config->screenWidthDp,
                       config->screenHeightDp));
         } else {