Merge change 5595 into donut

* changes:
  We might try to close the Vorbis file twice under certain circumstances. This fix nulls the mFile member so we don't try to close it twice. Bug 1904783.
diff --git a/api/current.xml b/api/current.xml
index 66bdb28..673d053 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3452,39 +3452,6 @@
  visibility="public"
 >
 </field>
-<field name="donut_resource_pad26"
- type="int"
- transient="false"
- volatile="false"
- value="16843398"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad27"
- type="int"
- transient="false"
- volatile="false"
- value="16843397"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad28"
- type="int"
- transient="false"
- volatile="false"
- value="16843396"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="donut_resource_pad3"
  type="int"
  transient="false"
@@ -5311,6 +5278,17 @@
  visibility="public"
 >
 </field>
+<field name="largeScreens"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843398"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="launchMode"
  type="int"
  transient="false"
@@ -6191,6 +6169,17 @@
  visibility="public"
 >
 </field>
+<field name="normalScreens"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843397"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="numColumns"
  type="int"
  transient="false"
@@ -7577,6 +7566,17 @@
  visibility="public"
 >
 </field>
+<field name="smallScreens"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843396"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="smoothScrollbar"
  type="int"
  transient="false"
@@ -34821,6 +34821,17 @@
  visibility="public"
 >
 </field>
+<field name="CONFIG_SCREEN_LAYOUT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="256"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="CONFIG_TOUCHSCREEN"
  type="int"
  transient="false"
@@ -35289,6 +35300,28 @@
  type="int"
  transient="false"
  volatile="false"
+ value="2048"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_SUPPORTS_NORMAL_SCREENS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1024"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_SUPPORTS_SMALL_SCREENS"
+ type="int"
+ transient="false"
+ volatile="false"
  value="512"
  static="true"
  final="true"
@@ -39488,6 +39521,50 @@
  visibility="public"
 >
 </field>
+<field name="SCREENLAYOUT_LARGE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCREENLAYOUT_NORMAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCREENLAYOUT_SMALL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCREENLAYOUT_UNDEFINED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TOUCHSCREEN_FINGER"
  type="int"
  transient="false"
@@ -39622,6 +39699,16 @@
  visibility="public"
 >
 </field>
+<field name="screenLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="touchscreen"
  type="int"
  transient="false"
@@ -139401,6 +139488,19 @@
  visibility="public"
 >
 </method>
+<method name="buildDrawingCache"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="autoScale" type="boolean">
+</parameter>
+</method>
 <method name="cancelLongPress"
  return="void"
  abstract="false"
@@ -139977,6 +140077,19 @@
  visibility="public"
 >
 </method>
+<method name="getDrawingCache"
+ return="android.graphics.Bitmap"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="autoScale" type="boolean">
+</parameter>
+</method>
 <method name="getDrawingCacheBackgroundColor"
  return="int"
  abstract="false"
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 01083f1..c299bff 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -171,9 +171,7 @@
             if (sets == null || sets.length == 0) {
                 System.out.println("No restore sets available");
             } else {
-                for (RestoreSet s : sets) {
-                    System.out.println("  " + s.token + " : " + s.name);
-                }
+                printRestoreSets(sets);
             }
         } catch (RemoteException e) {
             System.err.println(e.toString());
@@ -181,6 +179,12 @@
         }
     }
 
+    private void printRestoreSets(RestoreSet[] sets) {
+        for (RestoreSet s : sets) {
+            System.out.println("  " + s.token + " : " + s.name);
+        }
+    }
+
     class RestoreObserver extends IRestoreObserver.Stub {
         boolean done;
         public void restoreStarting(int numPackages) {
@@ -201,9 +205,9 @@
     }
 
     private void doRestore() {
-        int token;
+        long token;
         try {
-            token = Integer.parseInt(nextArg());
+            token = Long.parseLong(nextArg());
         } catch (NumberFormatException e) {
             showUsage();
             return;
@@ -212,6 +216,7 @@
         RestoreObserver observer = new RestoreObserver();
 
         try {
+            boolean didRestore = false;
             int curTransport = mBmgr.getCurrentTransport();
             mRestore = mBmgr.beginRestoreSession(curTransport);
             if (mRestore == null) {
@@ -223,9 +228,18 @@
                 if (s.token == token) {
                     System.out.println("Scheduling restore: " + s.name);
                     mRestore.performRestore(token, observer);
+                    didRestore = true;
                     break;
                 }
             }
+            if (!didRestore) {
+                if (sets == null || sets.length == 0) {
+                    System.out.println("No available restore sets; no restore performed");
+                } else {
+                    System.out.println("No matching restore set token.  Available sets:");
+                    printRestoreSets(sets);
+                }
+            }
             mRestore.endRestoreSession();
         } catch (RemoteException e) {
             System.err.println(e.toString());
diff --git a/core/java/android/backup/BackupManager.java b/core/java/android/backup/BackupManager.java
index 8df7eae..79e2c03 100644
--- a/core/java/android/backup/BackupManager.java
+++ b/core/java/android/backup/BackupManager.java
@@ -68,9 +68,11 @@
      * {@link android.app.BackupAgent} subclass will be scheduled when you call this method.
      */
     public void dataChanged() {
-        try {
-            mService.dataChanged(mContext.getPackageName());
-        } catch (RemoteException e) {
+        if (mService != null) {
+            try {
+                mService.dataChanged(mContext.getPackageName());
+            } catch (RemoteException e) {
+            }
         }
     }
 
@@ -83,9 +85,11 @@
      */
     public IRestoreSession beginRestoreSession(int transportID) {
         IRestoreSession binder = null;
-        try {
-            binder = mService.beginRestoreSession(transportID);
-        } catch (RemoteException e) {
+        if (mService != null) {
+            try {
+                binder = mService.beginRestoreSession(transportID);
+            } catch (RemoteException e) {
+            }
         }
         return binder;
     }
diff --git a/core/java/android/backup/IRestoreSession.aidl b/core/java/android/backup/IRestoreSession.aidl
index ac01c2d..2a1fbc1 100644
--- a/core/java/android/backup/IRestoreSession.aidl
+++ b/core/java/android/backup/IRestoreSession.aidl
@@ -45,7 +45,7 @@
      * @param observer If non-null, this binder points to an object that will receive
      *   progress callbacks during the restore operation.
      */
-    int performRestore(int token, IRestoreObserver observer);
+    int performRestore(long token, IRestoreObserver observer);
 
     /**
      * End this restore session.  After this method is called, the IRestoreSession binder
diff --git a/core/java/android/backup/SharedPreferencesBackupHelper.java b/core/java/android/backup/SharedPreferencesBackupHelper.java
index f492629..4a7b399 100644
--- a/core/java/android/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/backup/SharedPreferencesBackupHelper.java
@@ -30,7 +30,7 @@
     private Context mContext;
     private String[] mPrefGroups;
 
-    public SharedPreferencesBackupHelper(Context context, String[] prefGroups) {
+    public SharedPreferencesBackupHelper(Context context, String... prefGroups) {
         super(context);
 
         mContext = context;
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 85d877a..27783ef 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -235,6 +235,12 @@
     public static final int CONFIG_ORIENTATION = 0x0080;
     /**
      * Bit in {@link #configChanges} that indicates that the activity
+     * can itself handle changes to the screen layout.  Set from the
+     * {@link android.R.attr#configChanges} attribute.
+     */
+    public static final int CONFIG_SCREEN_LAYOUT = 0x0100;
+    /**
+     * 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
@@ -248,8 +254,8 @@
      * Contains any combination of {@link #CONFIG_FONT_SCALE},
      * {@link #CONFIG_MCC}, {@link #CONFIG_MNC},
      * {@link #CONFIG_LOCALE}, {@link #CONFIG_TOUCHSCREEN},
-     * {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION}, and
-     * {@link #CONFIG_ORIENTATION}.  Set from the
+     * {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION},
+     * {@link #CONFIG_ORIENTATION}, and {@link #CONFIG_SCREEN_LAYOUT}.  Set from the
      * {@link android.R.attr#configChanges} attribute.
      */
     public int configChanges;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 2a2cf93..bcf95b6 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -138,10 +138,27 @@
 
     /**
      * Value for {@link #flags}: true when the application's window can be
-     * expanded over default window size in target density (320x480 for
-     * 1.0 density, 480x720 for 1.5 density etc)
+     * reduced in size for smaller screens.  Corresponds to
+     * {@link android.R.styleable#AndroidManifestSupportsScreens_smallScreens
+     * android:smallScreens}.
      */
-    public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<9;
+    public static final int FLAG_SUPPORTS_SMALL_SCREENS = 1<<9;
+    
+    /**
+     * Value for {@link #flags}: true when the application's window can be
+     * displayed on normal screens.  Corresponds to
+     * {@link android.R.styleable#AndroidManifestSupportsScreens_normalScreens
+     * android:normalScreens}.
+     */
+    public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1<<10; 
+    
+    /**
+     * Value for {@link #flags}: true when the application's window can be
+     * increased in size for larger screens.  Corresponds to
+     * {@link android.R.styleable#AndroidManifestSupportsScreens_largeScreens
+     * android:smallScreens}.
+     */
+    public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<11;
     
     /**
      * Value for {@link #flags}: this is false if the application has set
@@ -149,7 +166,7 @@
      * 
      * {@hide}
      */
-    public static final int FLAG_ALLOW_BACKUP = 1<<10;
+    public static final int FLAG_ALLOW_BACKUP = 1<<12;
     
     /**
      * Indicates that the application supports any densities;
@@ -164,7 +181,9 @@
      * {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
      * {@link #FLAG_ALLOW_TASK_REPARENTING}
      * {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
-     * {@link #FLAG_TEST_ONLY}.
+     * {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
+     * {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
+     * {@link #FLAG_SUPPORTS_LARGE_SCREENS}.
      */
     public int flags = 0;
     
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ab9518e..558b0c3 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -668,6 +668,11 @@
         }
         sa.recycle();
 
+        // Resource boolean are -1, so 1 means we don't know the value.
+        int supportsSmallScreens = 1;
+        int supportsNormalScreens = 1;
+        int supportsLargeScreens = 1;
+        
         int outerDepth = parser.getDepth();
         while ((type=parser.next()) != parser.END_DOCUMENT
                && (type != parser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -876,8 +881,24 @@
 
                 XmlUtils.skipCurrentTag(parser);
 
-            } else if (tagName.equals("expandable")) {
-                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
+            } else if (tagName.equals("supports-screens")) {
+                sa = res.obtainAttributes(attrs,
+                        com.android.internal.R.styleable.AndroidManifestSupportsScreens);
+
+                // This is a trick to get a boolean and still able to detect
+                // if a value was actually set.
+                supportsSmallScreens = sa.getInteger(
+                        com.android.internal.R.styleable.AndroidManifestSupportsScreens_smallScreens,
+                        supportsSmallScreens);
+                supportsNormalScreens = sa.getInteger(
+                        com.android.internal.R.styleable.AndroidManifestSupportsScreens_normalScreens,
+                        supportsNormalScreens);
+                supportsLargeScreens = sa.getInteger(
+                        com.android.internal.R.styleable.AndroidManifestSupportsScreens_largeScreens,
+                        supportsLargeScreens);
+
+                sa.recycle();
+                
                 XmlUtils.skipCurrentTag(parser);
             } else {
                 Log.w(TAG, "Bad element under <manifest>: "
@@ -910,7 +931,20 @@
             pkg.usesLibraryFiles = new String[pkg.usesLibraries.size()];
             pkg.usesLibraries.toArray(pkg.usesLibraryFiles);
         }
-        // TODO: enable all density & expandable if target sdk is higher than donut 
+        
+        if (supportsSmallScreens < 0 || (supportsSmallScreens > 0
+                && pkg.applicationInfo.targetSdkVersion
+                        >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
+            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
+        }
+        if (supportsNormalScreens != 0) {
+            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS;
+        }
+        if (supportsLargeScreens < 0 || (supportsLargeScreens > 0
+                && pkg.applicationInfo.targetSdkVersion
+                        >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
+            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
+        }
         
         int size = pkg.supportsDensityList.size();
         if (size > 0) {
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 1c91736..5c7b01f 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -601,7 +601,7 @@
     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 majorVersion);
+            int screenLayout, int majorVersion);
 
     /**
      * Retrieve the resource identifier for the given resource name.
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 179b9bd..4e6fe07 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -65,7 +65,7 @@
     /**
      *  A compatibility flags
      */
-    private int compatibilityFlags;
+    private int mCompatibilityFlags;
     
     /**
      * A flag mask to tell if the application needs scaling (when mApplicationScale != 1.0f)
@@ -101,7 +101,11 @@
      */
     public final float applicationInvertedScale;
 
-
+    /**
+     * The flags from ApplicationInfo.
+     */
+    public final int appFlags;
+    
     /**
      * Window size in Compatibility Mode, in real pixels. This is updated by
      * {@link DisplayMetrics#updateMetrics}.
@@ -117,8 +121,10 @@
     private int mXOffset;
 
     public CompatibilityInfo(ApplicationInfo appInfo) {
+        appFlags = appInfo.flags;
+        
         if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
-            compatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
+            mCompatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
         }
         
         float packageDensityScale = -1.0f;
@@ -149,13 +155,16 @@
         }
         applicationInvertedScale = 1.0f / applicationScale;
         if (applicationScale != 1.0f) {
-            compatibilityFlags |= SCALING_REQUIRED;
+            mCompatibilityFlags |= SCALING_REQUIRED;
         }
     }
 
     private CompatibilityInfo() {
+        appFlags = ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS
+                | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
+                | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
         applicationScale = applicationInvertedScale = 1.0f;
-        compatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
+        mCompatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
     }
 
     /**
@@ -175,9 +184,9 @@
      */
     public void setExpandable(boolean expandable) {
         if (expandable) {
-            compatibilityFlags |= CompatibilityInfo.EXPANDABLE;
+            mCompatibilityFlags |= CompatibilityInfo.EXPANDABLE;
         } else {
-            compatibilityFlags &= ~CompatibilityInfo.EXPANDABLE;
+            mCompatibilityFlags &= ~CompatibilityInfo.EXPANDABLE;
         }
     }
 
@@ -185,20 +194,20 @@
      * @return true if the application is configured to be expandable.
      */
     public boolean isConfiguredExpandable() {
-        return (compatibilityFlags & CompatibilityInfo.CONFIGURED_EXPANDABLE) != 0;
+        return (mCompatibilityFlags & CompatibilityInfo.CONFIGURED_EXPANDABLE) != 0;
     }
 
     /**
      * @return true if the scaling is required
      */
     public boolean isScalingRequired() {
-        return (compatibilityFlags & SCALING_REQUIRED) != 0;
+        return (mCompatibilityFlags & SCALING_REQUIRED) != 0;
     }
     
     @Override
     public String toString() {
         return "CompatibilityInfo{scale=" + applicationScale +
-                ", compatibility flag=" + compatibilityFlags + "}"; 
+                ", compatibility flag=" + mCompatibilityFlags + "}"; 
     }
 
     /**
@@ -222,13 +231,13 @@
      * @param params the window's parameter
      */
     public Translator getTranslator(WindowManager.LayoutParams params) {
-        if ( (compatibilityFlags & CompatibilityInfo.SCALING_EXPANDABLE_MASK)
+        if ( (mCompatibilityFlags & CompatibilityInfo.SCALING_EXPANDABLE_MASK)
                 == CompatibilityInfo.EXPANDABLE) {
             if (DBG) Log.d(TAG, "no translation required");
             return null;
         }
         
-        if ((compatibilityFlags & CompatibilityInfo.EXPANDABLE) == 0) {
+        if ((mCompatibilityFlags & CompatibilityInfo.EXPANDABLE) == 0) {
             if ((params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 0) {
                 if (DBG) Log.d(TAG, "translation for surface view selected");
                 return new Translator(X_SHIFT_WINDOW, false, 1.0f, 1.0f);
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index bb3486c..577aa60 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -116,6 +116,18 @@
      */
     public int orientation;
     
+    public static final int SCREENLAYOUT_UNDEFINED = 0;
+    public static final int SCREENLAYOUT_SMALL = 1;
+    public static final int SCREENLAYOUT_NORMAL = 2;
+    public static final int SCREENLAYOUT_LARGE = 3;
+    
+    /**
+     * Overall layout of the screen.  May be one of
+     * {@link #SCREENLAYOUT_SMALL}, {@link #SCREENLAYOUT_NORMAL},
+     * or {@link #SCREENLAYOUT_LARGE}.
+     */
+    public int screenLayout;
+    
     /**
      * Construct an invalid Configuration.  You must call {@link #setToDefaults}
      * for this object to be valid.  {@more}
@@ -141,6 +153,7 @@
         hardKeyboardHidden = o.hardKeyboardHidden;
         navigation = o.navigation;
         orientation = o.orientation;
+        screenLayout = o.screenLayout;
     }
 
     public String toString() {
@@ -165,6 +178,8 @@
         sb.append(navigation);
         sb.append(" orien=");
         sb.append(orientation);
+        sb.append(" layout=");
+        sb.append(screenLayout);
         sb.append('}');
         return sb.toString();
     }
@@ -183,6 +198,7 @@
         hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
         navigation = NAVIGATION_UNDEFINED;
         orientation = ORIENTATION_UNDEFINED;
+        screenLayout = SCREENLAYOUT_UNDEFINED;
     }
 
     /** {@hide} */
@@ -253,6 +269,11 @@
             changed |= ActivityInfo.CONFIG_ORIENTATION;
             orientation = delta.orientation;
         }
+        if (delta.screenLayout != SCREENLAYOUT_UNDEFINED
+                && screenLayout != delta.screenLayout) {
+            changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
+            screenLayout = delta.screenLayout;
+        }
         
         return changed;
     }
@@ -276,9 +297,11 @@
      * {@link android.content.pm.ActivityInfo#CONFIG_KEYBOARD
      * PackageManager.ActivityInfo.CONFIG_KEYBOARD},
      * {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION
-     * PackageManager.ActivityInfo.CONFIG_NAVIGATION}, or
+     * PackageManager.ActivityInfo.CONFIG_NAVIGATION},
      * {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION
-     * PackageManager.ActivityInfo.CONFIG_ORIENTATION}.
+     * PackageManager.ActivityInfo.CONFIG_ORIENTATION}, or
+     * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
+     * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}.
      */
     public int diff(Configuration delta) {
         int changed = 0;
@@ -319,6 +342,10 @@
                 && orientation != delta.orientation) {
             changed |= ActivityInfo.CONFIG_ORIENTATION;
         }
+        if (delta.screenLayout != SCREENLAYOUT_UNDEFINED
+                && screenLayout != delta.screenLayout) {
+            changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
+        }
         
         return changed;
     }
@@ -368,6 +395,7 @@
         dest.writeInt(hardKeyboardHidden);
         dest.writeInt(navigation);
         dest.writeInt(orientation);
+        dest.writeInt(screenLayout);
     }
 
     public static final Parcelable.Creator<Configuration> CREATOR
@@ -399,6 +427,7 @@
         hardKeyboardHidden = source.readInt();
         navigation = source.readInt();
         orientation = source.readInt();
+        screenLayout = source.readInt();
     }
 
     public int compareTo(Configuration that) {
@@ -428,6 +457,8 @@
         n = this.navigation - that.navigation;
         if (n != 0) return n;
         n = this.orientation - that.orientation;
+        if (n != 0) return n;
+        n = this.screenLayout - that.screenLayout;
         //if (n != 0) return n;
         return n;
     }
@@ -450,6 +481,6 @@
         return ((int)this.fontScale) + this.mcc + this.mnc
                 + this.locale.hashCode() + this.touchscreen
                 + this.keyboard + this.keyboardHidden + this.hardKeyboardHidden
-                + this.navigation + this.orientation;
+                + this.navigation + this.orientation + this.screenLayout;
     }
 }
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index cb9d46e..d7512bb 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1267,7 +1267,8 @@
             }
             if (metrics != null) {
                 mMetrics.setTo(metrics);
-                mMetrics.updateMetrics(mCompatibilityInfo, mConfiguration.orientation);
+                mMetrics.updateMetrics(mCompatibilityInfo,
+                        mConfiguration.orientation, mConfiguration.screenLayout);
             }
             mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
 
@@ -1299,7 +1300,7 @@
                     mConfiguration.touchscreen,
                     (int)(mMetrics.density*160), mConfiguration.keyboard,
                     keyboardHidden, mConfiguration.navigation, width, height,
-                    sSdkVersion);
+                    mConfiguration.screenLayout, sSdkVersion);
             int N = mDrawableCache.size();
             if (DEBUG_CONFIG) {
                 Log.d(TAG, "Cleaning up drawables config changes: 0x"
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index ca579b6..09fbc97 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -39,13 +39,16 @@
 public class Camera {
     private static final String TAG = "Camera";
     
-    // These match the enum in libs/android_runtime/android_hardware_Camera.cpp
-    private static final int SHUTTER_CALLBACK = 0;
-    private static final int RAW_PICTURE_CALLBACK = 1;
-    private static final int JPEG_PICTURE_CALLBACK = 2;
-    private static final int PREVIEW_CALLBACK = 3;
-    private static final int AUTOFOCUS_CALLBACK = 4;
-    private static final int ERROR_CALLBACK = 5;
+    // These match the enums in frameworks/base/include/ui/Camera.h
+    private static final int CAMERA_MSG_ERROR = 0;
+    private static final int CAMERA_MSG_SHUTTER = 1;
+    private static final int CAMERA_MSG_FOCUS = 2;
+    private static final int CAMERA_MSG_ZOOM = 3;
+    private static final int CAMERA_MSG_PREVIEW_FRAME = 4;
+    private static final int CAMERA_MSG_VIDEO_FRAME = 5;
+    private static final int CAMERA_MSG_POSTVIEW_FRAME = 6;
+    private static final int CAMERA_MSG_RAW_IMAGE = 7;
+    private static final int CAMERA_MSG_COMPRESSED_IMAGE = 8;
 
     private int mNativeContext; // accessed by native methods
     private EventHandler mEventHandler;
@@ -231,22 +234,23 @@
         @Override
         public void handleMessage(Message msg) {
             switch(msg.what) {
-            case SHUTTER_CALLBACK:
+            case CAMERA_MSG_SHUTTER:
                 if (mShutterCallback != null) {
                     mShutterCallback.onShutter();
                 }
                 return;
-            case RAW_PICTURE_CALLBACK:
+
+            case CAMERA_MSG_RAW_IMAGE:
                 if (mRawImageCallback != null)
                     mRawImageCallback.onPictureTaken((byte[])msg.obj, mCamera);
                 return;
 
-            case JPEG_PICTURE_CALLBACK:
+            case CAMERA_MSG_COMPRESSED_IMAGE:
                 if (mJpegCallback != null)
                     mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera);
                 return;
             
-            case PREVIEW_CALLBACK:
+            case CAMERA_MSG_PREVIEW_FRAME:
                 if (mPreviewCallback != null) {
                     mPreviewCallback.onPreviewFrame((byte[])msg.obj, mCamera);
                     if (mOneShot) {
@@ -255,12 +259,12 @@
                 }
                 return;
 
-            case AUTOFOCUS_CALLBACK:
+            case CAMERA_MSG_FOCUS:
                 if (mAutoFocusCallback != null)
                     mAutoFocusCallback.onAutoFocus(msg.arg1 == 0 ? false : true, mCamera);
                 return;
 
-            case ERROR_CALLBACK:
+            case CAMERA_MSG_ERROR :
                 Log.e(TAG, "Error " + msg.arg1);
                 if (mErrorCallback != null)
                     mErrorCallback.onError(msg.arg1, mCamera);
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 6c13582..abfb274 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -127,12 +127,12 @@
 public abstract class AsyncTask<Params, Progress, Result> {
     private static final String LOG_TAG = "AsyncTask";
 
-    private static final int CORE_POOL_SIZE = 1;
-    private static final int MAXIMUM_POOL_SIZE = 10;
+    private static final int CORE_POOL_SIZE = 5;
+    private static final int MAXIMUM_POOL_SIZE = 128;
     private static final int KEEP_ALIVE = 10;
 
     private static final BlockingQueue<Runnable> sWorkQueue =
-            new LinkedBlockingQueue<Runnable>(MAXIMUM_POOL_SIZE);
+            new LinkedBlockingQueue<Runnable>(10);
 
     private static final ThreadFactory sThreadFactory = new ThreadFactory() {
         private final AtomicInteger mCount = new AtomicInteger(1);
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index 6ea2528..95e54324 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -150,7 +150,7 @@
 
         // Set the title bar if title is available, else no title bar
         final CharSequence title = getTitle();
-        Dialog dialog = mDialog = new Dialog(context, !TextUtils.isEmpty(title)
+        Dialog dialog = mDialog = new Dialog(context, TextUtils.isEmpty(title)
                 ? com.android.internal.R.style.Theme_NoTitleBar
                 : com.android.internal.R.style.Theme);
         dialog.setContentView(listView);
diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java
index 789fdff..1ba5e25e 100644
--- a/core/java/android/provider/Browser.java
+++ b/core/java/android/provider/Browser.java
@@ -91,6 +91,17 @@
      */
     public static final String EXTRA_APPEND_LOCATION = "com.android.browser.append_location";
 
+    /**
+     * The name of the extra data in the VIEW intent. The data is in the format of
+     * a byte array.
+     * <p>
+     * Any value sent here will be passed in the http request to the provided url as post data.
+     * <p>
+     * pending api approval
+     * @hide
+     */
+    public static final String EXTRA_POST_DATA = "com.android.browser.post_data";
+
     /* if you change column order you must also change indices
        below */
     public static final String[] HISTORY_PROJECTION = new String[] {
diff --git a/core/java/android/speech/tts/ITts.aidl b/core/java/android/speech/tts/ITts.aidl
index 75c3b30..47976e5 100755
--- a/core/java/android/speech/tts/ITts.aidl
+++ b/core/java/android/speech/tts/ITts.aidl
@@ -33,6 +33,8 @@
 

     void speak(in String text, in int queueMode, in String[] params);

 

+    void speakIpa(in String ipaText, in int queueMode, in String[] params);

+

     boolean isSpeaking();

 

     void stop();

@@ -43,7 +45,9 @@
 

     void setLanguage(in String language, in String country, in String variant);

 

-    boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);

+    boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);
+

+    boolean synthesizeIpaToFile(in String ipaText, in String[] params, in String outputDirectory);

 

     void playEarcon(in String earcon, in int queueMode, in String[] params);

 

diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 1502d98..8fa06fa 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -369,7 +369,28 @@
      */
     public void speakIpa(String ipaText, int queueMode, HashMap<String,String> params)
     {
-        //TODO: Implement speakIpa
+        synchronized (mStartLock) {
+            Log.i("TTS received: ", ipaText);
+            if (!mStarted) {
+                return;
+            }
+            try {
+                // TODO support extra parameters, passing cache of current parameters for the moment
+                mITts.speakIpa(ipaText, queueMode, mCachedParams);
+            } catch (RemoteException e) {
+                // TTS died; restart it.
+                mStarted = false;
+                initTts();
+            } catch (NullPointerException e) {
+                // TTS died; restart it.
+                mStarted = false;
+                initTts();
+            } catch (IllegalStateException e) {
+                // TTS died; restart it.
+                mStarted = false;
+                initTts();
+            }
+        }
     }
 
 
@@ -410,7 +431,27 @@
 
 
     public void playSilence(long durationInMs, int queueMode) {
-        // TODO implement, already present in TTS service
+        synchronized (mStartLock) {
+            if (!mStarted) {
+                return;
+            }
+            try {
+                // TODO support extra parameters, passing cache of current parameters for the moment
+                mITts.playSilence(durationInMs, queueMode, mCachedParams);
+            } catch (RemoteException e) {
+                // TTS died; restart it.
+                mStarted = false;
+                initTts();
+            } catch (NullPointerException e) {
+                // TTS died; restart it.
+                mStarted = false;
+                initTts();
+            } catch (IllegalStateException e) {
+                // TTS died; restart it.
+                mStarted = false;
+                initTts();
+            }
+        }
     }
 
 
@@ -580,7 +621,7 @@
 
 
     /**
-     * Speaks the given text using the specified queueing mode and parameters.
+     * Synthesizes the given text to a file using the specified parameters.
      *
      * @param text
      *            The String of text that should be synthesized
@@ -617,5 +658,42 @@
         }
     }
 
+    /**
+     * Synthesizes the given IPA text to a file using the specified parameters.
+     *
+     * @param text
+     *            The String of text that should be synthesized
+     * @param params
+     *            A hashmap of parameters.
+     * @param filename
+     *            The string that gives the full output filename; it should be
+     *            something like "/sdcard/myappsounds/mysound.wav".
+     * @return A boolean that indicates if the synthesis succeeded
+     */
+    public boolean synthesizeIpaToFile(String ipaText,
+            HashMap<String,String> params, String filename) {
+        synchronized (mStartLock) {
+            if (!mStarted) {
+                return false;
+            }
+            try {
+                // TODO support extra parameters, passing null for the moment
+                return mITts.synthesizeIpaToFile(ipaText, null, filename);
+            } catch (RemoteException e) {
+                // TTS died; restart it.
+                mStarted = false;
+                initTts();
+            } catch (NullPointerException e) {
+                // TTS died; restart it.
+                mStarted = false;
+                initTts();
+            } catch (IllegalStateException e) {
+                // TTS died; restart it.
+                mStarted = false;
+                initTts();
+            }
+            return false;
+        }
+    }
 
 }
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index d89ada0..4179edb 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -103,40 +103,43 @@
 
     /**
      * Update the display metrics based on the compatibility info and orientation
+     * NOTE: DO NOT EXPOSE THIS API!  It is introducing a circular dependency
+     * with the higher-level android.res package.
      * {@hide}
      */
-    public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation) {
+    public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation,
+            int screenLayout) {
         int xOffset = 0;
         if (!compatibilityInfo.isConfiguredExpandable()) {
             // Note: this assume that configuration is updated before calling
             // updateMetrics method.
-            int defaultWidth;
-            int defaultHeight;
-            switch (orientation) {
-                case Configuration.ORIENTATION_LANDSCAPE: {
-                    defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
-                    defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
-                    break;
-                }
-                case Configuration.ORIENTATION_PORTRAIT:
-                case Configuration.ORIENTATION_SQUARE:
-                default: {
-                    defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
-                    defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
-                    break;
-                }
-                case Configuration.ORIENTATION_UNDEFINED: {
-                    // don't change
-                    return;
-                }
-            }
-            
-            if (defaultWidth == widthPixels && defaultHeight == heightPixels) {
-                // the screen size is same as expected size. make it expandable
-                compatibilityInfo.setExpandable(true);
-            } else {
+            if (screenLayout == Configuration.SCREENLAYOUT_LARGE) {
+                // This is a large screen device and the app is not 
+                // compatible with large screens, to diddle it.
+                
                 compatibilityInfo.setExpandable(false);
-                // adjust the size only when the device's screen is bigger.
+                // Figure out the compatibility width and height of the screen.
+                int defaultWidth;
+                int defaultHeight;
+                switch (orientation) {
+                    case Configuration.ORIENTATION_LANDSCAPE: {
+                        defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
+                        defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
+                        break;
+                    }
+                    case Configuration.ORIENTATION_PORTRAIT:
+                    case Configuration.ORIENTATION_SQUARE:
+                    default: {
+                        defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
+                        defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
+                        break;
+                    }
+                    case Configuration.ORIENTATION_UNDEFINED: {
+                        // don't change
+                        return;
+                    }
+                }
+                
                 if (defaultWidth < widthPixels) {
                     // content/window's x offset in original pixels
                     xOffset = ((widthPixels - defaultWidth) / 2);
@@ -145,6 +148,10 @@
                 if (defaultHeight < heightPixels) {
                     heightPixels = defaultHeight;
                 }
+                
+            } else {
+                // the screen size is same as expected size. make it expandable
+                compatibilityInfo.setExpandable(true);
             }
         }
         compatibilityInfo.setVisibleRect(xOffset, widthPixels, heightPixels);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3bfdde8..c9a785c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1690,6 +1690,7 @@
     private int[] mDrawableState = null;
 
     private SoftReference<Bitmap> mDrawingCache;
+    private SoftReference<Bitmap> mUnscaledDrawingCache;
 
     /**
      * When this view has focus and the next focus is {@link #FOCUS_LEFT},
@@ -5783,28 +5784,52 @@
     }
 
     /**
+     * <p>Calling this method is equivalent to calling <code>getDrawingCache(false)</code>.</p>
+     * 
+     * @return A non-scaled bitmap representing this view or null if cache is disabled.
+     * 
+     * @see #getDrawingCache(boolean)
+     */
+    public Bitmap getDrawingCache() {
+        return getDrawingCache(false);
+    }
+
+    /**
      * <p>Returns the bitmap in which this view drawing is cached. The returned bitmap
      * is null when caching is disabled. If caching is enabled and the cache is not ready,
      * this method will create it. Calling {@link #draw(android.graphics.Canvas)} will not
      * draw from the cache when the cache is enabled. To benefit from the cache, you must
      * request the drawing cache by calling this method and draw it on screen if the
      * returned bitmap is not null.</p>
+     * 
+     * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
+     * this method will create a bitmap of the same size as this view. Because this bitmap
+     * will be drawn scaled by the parent ViewGroup, the result on screen might show
+     * scaling artifacts. To avoid such artifacts, you should call this method by setting
+     * the auto scaling to true. Doing so, however, will generate a bitmap of a different
+     * size than the view. This implies that your application must be able to handle this
+     * size.</p>
+     * 
+     * @param autoScale Indicates whether the generated bitmap should be scaled based on
+     *        the current density of the screen when the application is in compatibility
+     *        mode.
      *
-     * @return a bitmap representing this view or null if cache is disabled
-     *
+     * @return A bitmap representing this view or null if cache is disabled.
+     * 
      * @see #setDrawingCacheEnabled(boolean)
      * @see #isDrawingCacheEnabled()
-     * @see #buildDrawingCache()
+     * @see #buildDrawingCache(boolean)
      * @see #destroyDrawingCache()
      */
-    public Bitmap getDrawingCache() {
+    public Bitmap getDrawingCache(boolean autoScale) {
         if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
             return null;
         }
         if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED) {
-            buildDrawingCache();
+            buildDrawingCache(autoScale);
         }
-        return mDrawingCache == null ? null : mDrawingCache.get();
+        return autoScale ? (mDrawingCache == null ? null : mDrawingCache.get()) :
+                (mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());
     }
 
     /**
@@ -5823,6 +5848,11 @@
             if (bitmap != null) bitmap.recycle();
             mDrawingCache = null;
         }
+        if (mUnscaledDrawingCache != null) {
+            final Bitmap bitmap = mUnscaledDrawingCache.get();
+            if (bitmap != null) bitmap.recycle();
+            mUnscaledDrawingCache = null;
+        }
     }
 
     /**
@@ -5850,18 +5880,36 @@
     }
 
     /**
+     * <p>Calling this method is equivalent to calling <code>buildDrawingCache(false)</code>.</p>
+     * 
+     * @see #buildDrawingCache(boolean)
+     */
+    public void buildDrawingCache() {
+        buildDrawingCache(false);
+    }
+
+    /**
      * <p>Forces the drawing cache to be built if the drawing cache is invalid.</p>
      *
      * <p>If you call {@link #buildDrawingCache()} manually without calling
      * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
      * should cleanup the cache by calling {@link #destroyDrawingCache()} afterwards.</p>
+     * 
+     * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
+     * this method will create a bitmap of the same size as this view. Because this bitmap
+     * will be drawn scaled by the parent ViewGroup, the result on screen might show
+     * scaling artifacts. To avoid such artifacts, you should call this method by setting
+     * the auto scaling to true. Doing so, however, will generate a bitmap of a different
+     * size than the view. This implies that your application must be able to handle this
+     * size.</p>
      *
      * @see #getDrawingCache()
      * @see #destroyDrawingCache()
      */
-    public void buildDrawingCache() {
-        if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || mDrawingCache == null ||
-                mDrawingCache.get() == null) {
+    public void buildDrawingCache(boolean autoScale) {
+        if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || (autoScale ?
+                (mDrawingCache == null || mDrawingCache.get() == null) :
+                (mUnscaledDrawingCache == null || mUnscaledDrawingCache.get() == null))) {
 
             if (ViewDebug.TRACE_HIERARCHY) {
                 ViewDebug.trace(this, ViewDebug.HierarchyTraceType.BUILD_CACHE);
@@ -5874,12 +5922,10 @@
             int height = mBottom - mTop;
 
             final AttachInfo attachInfo = mAttachInfo;
-            if (attachInfo != null) {
-                final boolean scalingRequired = attachInfo.mScalingRequired;
-                if (scalingRequired) {
-                    width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
-                    height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
-                }
+
+            if (autoScale && attachInfo != null && attachInfo.mScalingRequired) {
+                width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
+                height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
             }
 
             final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
@@ -5894,7 +5940,8 @@
             }
 
             boolean clear = true;
-            Bitmap bitmap = mDrawingCache == null ? null : mDrawingCache.get();
+            Bitmap bitmap = autoScale ? (mDrawingCache == null ? null : mDrawingCache.get()) :
+                    (mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());
 
             if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
 
@@ -5923,12 +5970,20 @@
 
                 try {
                     bitmap = Bitmap.createBitmap(width, height, quality);
-                    mDrawingCache = new SoftReference<Bitmap>(bitmap);
+                    if (autoScale) {
+                        mDrawingCache = new SoftReference<Bitmap>(bitmap);
+                    } else {
+                        mUnscaledDrawingCache = new SoftReference<Bitmap>(bitmap);
+                    }
                 } catch (OutOfMemoryError e) {
                     // If there is not enough memory to create the bitmap cache, just
                     // ignore the issue as bitmap caches are not required to draw the
                     // view hierarchy
-                    mDrawingCache = null;
+                    if (autoScale) {
+                        mDrawingCache = null;
+                    } else {
+                        mUnscaledDrawingCache = null;
+                    }
                     return;
                 }
 
@@ -5940,13 +5995,6 @@
                 canvas = attachInfo.mCanvas;
                 if (canvas == null) {
                     canvas = new Canvas();
-
-                    // NOTE: This should have to happen only once since compatibility
-                    //       mode should not change at runtime
-                    if (attachInfo.mScalingRequired) {
-                        final float scale = attachInfo.mApplicationScale;
-                        canvas.scale(scale, scale);
-                    }
                 }
                 canvas.setBitmap(bitmap);
                 // Temporarily clobber the cached Canvas in case one of our children
@@ -5965,6 +6013,12 @@
 
             computeScroll();
             final int restoreCount = canvas.save();
+            
+            if (autoScale && attachInfo.mScalingRequired) {
+                final float scale = attachInfo.mApplicationScale;
+                canvas.scale(scale, scale);
+            }
+            
             canvas.translate(-mScrollX, -mScrollY);
 
             mPrivateFlags |= DRAWN;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index f803b5a..f7b7f02 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1166,7 +1166,7 @@
                 final View child = children[i];
                 if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
                     child.setDrawingCacheEnabled(true);
-                    child.buildDrawingCache();
+                    child.buildDrawingCache(true);
                 }
             }
 
@@ -1208,7 +1208,7 @@
                     bindLayoutAnimation(child);
                     if (cache) {
                         child.setDrawingCacheEnabled(true);
-                        child.buildDrawingCache();
+                        child.buildDrawingCache(true);
                     }
                 }
             }
@@ -1448,7 +1448,7 @@
         Bitmap cache = null;
         if ((flags & FLAG_CHILDREN_DRAWN_WITH_CACHE) == FLAG_CHILDREN_DRAWN_WITH_CACHE ||
                 (flags & FLAG_ALWAYS_DRAWN_WITH_CACHE) == FLAG_ALWAYS_DRAWN_WITH_CACHE) {
-            cache = child.getDrawingCache();
+            cache = child.getDrawingCache(true);
             if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
         }
 
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 70749d1..e84e5b0 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -1202,7 +1202,11 @@
                         int position, long id) {
 
                     if (position != -1) {
-                        mDropDownList.mListSelectionHidden = false;
+                        DropDownListView dropDownList = mDropDownList;
+
+                        if (dropDownList != null) {
+                            dropDownList.mListSelectionHidden = false;
+                        }
                     }
                 }
 
diff --git a/core/java/com/android/internal/util/BitwiseInputStream.java b/core/java/com/android/internal/util/BitwiseInputStream.java
index 4757919..031abdd 100644
--- a/core/java/com/android/internal/util/BitwiseInputStream.java
+++ b/core/java/com/android/internal/util/BitwiseInputStream.java
@@ -69,19 +69,19 @@
      *
      * @return byte of read data (possibly partially filled, from lsb)
      */
-    public byte read(int bits) throws AccessException {
+    public int read(int bits) throws AccessException {
         int index = mPos >>> 3;
         int offset = 16 - (mPos & 0x07) - bits;  // &7==%8
         if ((bits < 0) || (bits > 8) || ((mPos + bits) > mEnd)) {
             throw new AccessException("illegal read " +
                 "(pos " + mPos + ", end " + mEnd + ", bits " + bits + ")");
         }
-        int data = (mBuf[index] & 0x00FF) << 8;
-        if (offset < 8) data |= (mBuf[index + 1] & 0xFF);
+        int data = (mBuf[index] & 0xFF) << 8;
+        if (offset < 8) data |= mBuf[index + 1] & 0xFF;
         data >>>= offset;
         data &= (-1 >>> (32 - bits));
         mPos += bits;
-        return (byte)data;
+        return data;
     }
 
     /**
diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java
index 1b974ce..ab8a7f3 100644
--- a/core/java/com/android/internal/util/BitwiseOutputStream.java
+++ b/core/java/com/android/internal/util/BitwiseOutputStream.java
@@ -95,8 +95,8 @@
         int offset = 16 - (mPos & 0x07) - bits;  // &7==%8
         data <<= offset;
         mPos += bits;
-        mBuf[index] |= (data >>> 8);
-        if (offset < 8) mBuf[index + 1] |= (data & 0x00FF);
+        mBuf[index] |= data >>> 8;
+        if (offset < 8) mBuf[index + 1] |= data & 0xFF;
     }
 
     /**
diff --git a/core/jni/android_backup_BackupHelperDispatcher.cpp b/core/jni/android_backup_BackupHelperDispatcher.cpp
index 24d529b..2e3f0b9 100644
--- a/core/jni/android_backup_BackupHelperDispatcher.cpp
+++ b/core/jni/android_backup_BackupHelperDispatcher.cpp
@@ -87,6 +87,14 @@
         }
     }
 
+#if 0
+    LOGD("chunk header:");
+    LOGD("  headerSize=%d", flattenedHeader.headerSize);
+    LOGD("  version=0x%08x", flattenedHeader.version);
+    LOGD("  dataSize=%d", flattenedHeader.dataSize);
+    LOGD("  nameLength=%d", flattenedHeader.nameLength);
+#endif
+
     if (flattenedHeader.dataSize < 0 || flattenedHeader.nameLength < 0 ||
             remainingHeader < flattenedHeader.nameLength) {
         LOGW("Malformed V1 header remainingHeader=%d dataSize=%d nameLength=%d", remainingHeader,
@@ -101,13 +109,12 @@
     }
 
     amt = read(fd, buf, flattenedHeader.nameLength);
+    buf[flattenedHeader.nameLength] = 0;
 
     keyPrefix.unlockBuffer(flattenedHeader.nameLength);
 
     remainingHeader -= flattenedHeader.nameLength;
 
-    LOGD("remainingHeader=%d", remainingHeader);
-
     if (remainingHeader > 0) {
         lseek(fd, remainingHeader, SEEK_CUR);
     }
@@ -183,6 +190,7 @@
 
     header.headerSize = sizeof(chunk_header_v1) + header.nameLength + namePadding;
     header.version = VERSION_1_HEADER;
+    header.dataSize = prevPos - (pos + header.headerSize);
 
     lseek(fd, pos, SEEK_SET);
     err = write(fd, &header, sizeof(chunk_header_v1));
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index b07ba7d..8e48b38 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -125,37 +125,8 @@
         return;
     }
     JNIEnv *env = AndroidRuntime::getJNIEnv();
-
-    // parse message
-    switch (msgType) {
-    case CAMERA_MSG_ERROR:
-        LOGV("errorCallback");
-        int error;
-        switch (ext1) {
-            case DEAD_OBJECT:
-                error = kCameraErrorMediaServer;
-                break;
-            default:
-                error = kCameraErrorUnknown;
-                break;
-        }
-        env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
-                mCameraJObjectWeak, kErrorCallback, error, 0, NULL);
-        break;
-    case CAMERA_MSG_FOCUS:
-        LOGV("autoFocusCallback");
-        env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
-                mCameraJObjectWeak, kAutoFocusCallback, ext1, 0, NULL);
-        break;
-    case CAMERA_MSG_SHUTTER:
-        LOGV("shutterCallback");
-        env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
-                mCameraJObjectWeak, kShutterCallback, 0, 0, NULL);
-        break;
-    default:
-        LOGV("notifyCallback(%d, %d, %d)", msgType, ext1, ext2);
-        break;
-    }
+    env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
+            mCameraJObjectWeak, msgType, ext1, ext2);
 }
 
 void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int msgType)
@@ -203,27 +174,20 @@
 
     // return data based on callback type
     switch(msgType) {
-    case CAMERA_MSG_PREVIEW_FRAME:
-        LOGV("previewCallback");
-        copyAndPost(env, dataPtr, kPreviewCallback);
-        break;
     case CAMERA_MSG_VIDEO_FRAME:
-        LOGV("recordingCallback");
+        // should never happen
         break;
+    // don't return raw data to Java
     case CAMERA_MSG_RAW_IMAGE:
         LOGV("rawCallback");
         env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
-                mCameraJObjectWeak, kRawCallback, 0, 0, NULL);
-        break;
-    case CAMERA_MSG_COMPRESSED_IMAGE:
-        LOGV("jpegCallback");
-        copyAndPost(env, dataPtr, kJpegCallback);
+                mCameraJObjectWeak, msgType, 0, 0, NULL);
         break;
     default:
         LOGV("dataCallback(%d, %p)", msgType, dataPtr.get());
+        copyAndPost(env, dataPtr, msgType);
         break;
     }
-
 }
 
 // connect to camera service
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index d147bcc..2d90ba4 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -535,7 +535,7 @@
                                                           jint keyboard, jint keyboardHidden,
                                                           jint navigation,
                                                           jint screenWidth, jint screenHeight,
-                                                          jint sdkVersion)
+                                                          jint screenLayout, jint sdkVersion)
 {
     AssetManager* am = assetManagerForJavaObject(env, clazz);
     if (am == NULL) {
@@ -557,6 +557,7 @@
     config.navigation = (uint8_t)navigation;
     config.screenWidth = (uint16_t)screenWidth;
     config.screenHeight = (uint16_t)screenHeight;
+    config.screenLayout = (uint8_t)screenLayout;
     config.sdkVersion = (uint16_t)sdkVersion;
     config.minorVersion = 0;
     am->setConfiguration(config, locale8);
@@ -1567,7 +1568,7 @@
         (void*) android_content_AssetManager_setLocale },
     { "getLocales",      "()[Ljava/lang/String;",
         (void*) android_content_AssetManager_getLocales },
-    { "setConfiguration", "(IILjava/lang/String;IIIIIIIII)V",
+    { "setConfiguration", "(IILjava/lang/String;IIIIIIIIII)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/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 91cd9fd..7571e24 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -512,6 +512,9 @@
         <!-- The screen orientation has changed, that is the user has
              rotated the device. -->
         <flag name="orientation" value="0x0080" />
+        <!-- The screen orientation has changed, that is the user has
+             rotated the device. -->
+        <flag name="screenLayout" value="0x0100" />
         <!-- The font scaling factor has changed, that is the user has
              selected a new global font size. -->
         <flag name="fontScale" value="0x40000000" />
@@ -829,8 +832,59 @@
          <p>This appears as a child tag of the
          {@link #AndroidManifest manifest} tag. -->
     <declare-styleable name="AndroidManifestSupportsDensity" parent="AndroidManifest">
-        <!-- Required value of the density in dip (device independent pixel). -->
-        <attr name="density" format="integer" />
+        <!-- Required value of the density in dip (device independent pixel).
+             You should use one of the pre-defined constants for the standard
+             screen densities defined here.
+        -->
+        <attr name="density" format="integer">
+            <!-- A low density screen, such as a QVGA or WQVGA screen in a
+                 typical hand-held phone.  The constant for this is 120. -->
+            <enum name="low" value="120" />
+            <!-- A medium density screen, such as an HVGA screen in a
+                 typical hand-held phone.  The constant for this is 160. -->
+            <enum name="medium" value="160" />
+            <!-- A high density screen, such as a VGA or WVGA screen in a
+                 typical hand-held phone.  The constant for this is 240. -->
+            <enum name="high" value="240" />
+        </attr>
+    </declare-styleable>
+
+    <!-- The <code>supports-screens</code> specifies the screen dimensions an
+         application supports.  By default a modern application supports all
+         screen sizes and must explicitly disable certain screen sizes here;
+         older applications are assumed to only support the traditional normal
+         (HVGA) screen size.  Note that screen size is a separate axis from
+         density, and is determined as the available pixels to an application
+         after density scaling has been applied.
+         
+         <p>This appears as a child tag of the
+         {@link #AndroidManifest manifest} tag. -->
+    <declare-styleable name="AndroidManifestSupportsScreens" parent="AndroidManifest">
+        <!-- Indicates whether the application supports smaller screen form-factors.
+             A small screen is defined as one with a smaller aspect ratio than
+             the traditional HVGA screen; that is, for a portrait screen, less
+             tall than an HVGA screen.  In practice, this means a QVGA low
+             density or VGA high density screen.  An application that does
+             not support small screens <em>will not be available</em> for
+             small screen devices, since there is little the platform can do
+             to make such an application work on a smaller screen. -->
+        <attr name="smallScreens" format="boolean" />
+        <!-- Indicates whether an application supports the normal screen
+             form-factors.  Traditionally this is an HVGA normal density
+             screen, but WQVGA low density and WVGA high density are also
+             considered to be normal.  This attribute is true by default,
+             and applications currently should leave it that way. -->
+        <attr name="normalScreens" format="boolean" />
+        <!-- Indicates whether the application supports larger screen form-factors.
+             A large screen is defined as a screen that is significantly larger
+             than a normal phone screen, and thus may require some special care
+             on the application's part to make good use of it.  An example would
+             be a VGA <em>normal density</em> screen, though even larger screens
+             are certainly possible.  An application that does not support
+             large screens will be placed as a postage stamp on such a
+             screen, so that it retains the dimensions it was originally
+             designed for. -->
+        <attr name="largeScreens" format="boolean" />
     </declare-styleable>
 
     <!-- The <code>expandable</code> specifies if this package supports screen metrics
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 4634b50..14d8dbe 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1117,6 +1117,9 @@
   <public type="attr" name="glEsVersion" />
   <public type="attr" name="queryAfterZeroResults" />
   <public type="attr" name="dropDownHeight" />
+  <public type="attr" name="smallScreens" />
+  <public type="attr" name="normalScreens" />
+  <public type="attr" name="largeScreens" />
 
   <public-padding type="attr" name="donut_resource_pad" end="0x0101029f" />
 
diff --git a/include/tts/TtsEngine.h b/include/tts/TtsEngine.h
index 8486532..ca50a5e 100644
--- a/include/tts/TtsEngine.h
+++ b/include/tts/TtsEngine.h
@@ -69,6 +69,14 @@
     TTS_MISSING_RESOURCES       = -6
 };
 
+enum tts_support_result {
+    TTS_LANG_COUNTRY_VAR_AVAILABLE = 2,
+    TTS_LANG_COUNTRY_AVAILABLE = 1,
+    TTS_LANG_AVAILABLE = 0,
+    TTS_LANG_MISSING_DATA = -1,
+    TTS_LANG_NOT_SUPPORTED = -2
+};
+
 class TtsEngine
 {
 public:
@@ -86,19 +94,32 @@
     // @return TTS_SUCCESS, or TTS_FAILURE
     virtual tts_result stop();
 
+    // Returns the level of support for the language, country and variant.
+    // @return TTS_LANG_COUNTRY_VAR_AVAILABLE if the language, country and variant are supported,
+    //            and the corresponding resources are correctly installed
+    //         TTS_LANG_COUNTRY_AVAILABLE if the language and country are supported and the
+    //             corresponding resources are correctly installed, but there is no match for
+    //             the specified variant
+    //         TTS_LANG_AVAILABLE if the language is supported and the
+    //             corresponding resources are correctly installed, but there is no match for
+    //             the specified country and variant
+    //         TTS_LANG_MISSING_DATA if the required resources to provide any level of support
+    //             for the language are not correctly installed
+    //         TTS_LANG_NOT_SUPPORTED if the language is not supported by the TTS engine.
+    virtual tts_support_result isLanguageAvailable(const char *lang, const char *country,
+            const char *variant);
+
     // Load the resources associated with the specified language. The loaded
     // language will only be used once a call to setLanguage() with the same
-    // language value is issued. Language values are based on the Android
-    // conventions for localization as described in the Android platform
-    // documentation on internationalization. This implies that language
-    // data is specified in the format xx-rYY, where xx is a two letter
-    // ISO 639-1 language code in lowercase and rYY is a two letter
-    // ISO 3166-1-alpha-2 language code in uppercase preceded by a
-    // lowercase "r".
-    // @param value pointer to the language value
-    // @param size  length of the language value
+    // language value is issued. Language and country values are coded according to the ISO three
+    // letter codes for languages and countries, as can be retrieved from a java.util.Locale
+    // instance. The variant value is encoded as the variant string retrieved from a
+    // java.util.Locale instance built with that variant data.
+    // @param lang pointer to the ISO three letter code for the language
+    // @param country pointer to the ISO three letter code for the country
+    // @param variant pointer to the variant code
     // @return TTS_SUCCESS, or TTS_FAILURE
-    virtual tts_result loadLanguage(const char *value, const size_t size);
+    virtual tts_result loadLanguage(const char *lang, const char *country, const char *variant);
     
     // Load the resources associated with the specified language, country and Locale variant.
     // The loaded language will only be used once a call to setLanguageFromLocale() with the same
diff --git a/include/ui/Camera.h b/include/ui/Camera.h
index bbc21c4..97e0e90 100644
--- a/include/ui/Camera.h
+++ b/include/ui/Camera.h
@@ -63,16 +63,12 @@
 #define FRAME_CALLBACK_FLAG_CAMERA                   0x05
 #define FRAME_CALLBACK_FLAG_BARCODE_SCANNER          0x07
 
-// msgType in notifyCallback function
+// msgType in notifyCallback and dataCallback functions
 enum {
-    CAMERA_MSG_ERROR,
+    CAMERA_MSG_ERROR = 0,
     CAMERA_MSG_SHUTTER,
     CAMERA_MSG_FOCUS,
-    CAMERA_MSG_ZOOM
-};
-
-// msgType in dataCallback function
-enum {
+    CAMERA_MSG_ZOOM,
     CAMERA_MSG_PREVIEW_FRAME,
     CAMERA_MSG_VIDEO_FRAME,
     CAMERA_MSG_POSTVIEW_FRAME,
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index f1029b7..5c41ead 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -866,7 +866,7 @@
             uint8_t keyboard;
             uint8_t navigation;
             uint8_t inputFlags;
-            uint8_t pad0;
+            uint8_t inputPad0;
         };
         uint32_t input;
     };
@@ -905,6 +905,23 @@
         uint32_t version;
     };
     
+    enum {
+        SCREENLAYOUT_ANY  = 0x0000,
+        SCREENLAYOUT_SMALL = 0x0001,
+        SCREENLAYOUT_NORMAL = 0x0002,
+        SCREENLAYOUT_LARGE = 0x0003,
+    };
+    
+    union {
+        struct {
+            uint8_t screenLayout;
+            uint8_t screenConfigPad0;
+            uint8_t screenConfigPad1;
+            uint8_t screenConfigPad2;
+        };
+        uint32_t screenConfig;
+    };
+    
     inline void copyFromDeviceNoSwap(const ResTable_config& o) {
         const size_t size = dtohl(o.size);
         if (size >= sizeof(ResTable_config)) {
@@ -950,6 +967,8 @@
         diff = (int32_t)(screenSize - o.screenSize);
         if (diff != 0) return diff;
         diff = (int32_t)(version - o.version);
+        if (diff != 0) return diff;
+        diff = (int32_t)(screenLayout - o.screenLayout);
         return (int)diff;
     }
     
@@ -967,7 +986,8 @@
         CONFIG_ORIENTATION = 0x0080,
         CONFIG_DENSITY = 0x0100,
         CONFIG_SCREEN_SIZE = 0x0200,
-        CONFIG_VERSION = 0x0400
+        CONFIG_VERSION = 0x0400,
+        CONFIG_SCREEN_LAYOUT = 0x0800
     };
     
     // Compare two configuration, returning CONFIG_* flags set for each value
@@ -985,6 +1005,7 @@
         if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
         if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
         if (version != o.version) diffs |= CONFIG_VERSION;
+        if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
         return diffs;
     }
     
@@ -1062,6 +1083,13 @@
             }
         }
 
+        if (screenConfig || o.screenConfig) {
+            if (screenLayout != o.screenLayout) {
+                if (!screenLayout) return false;
+                if (!o.screenLayout) return true;
+            }
+        }
+
         if (version || o.version) {
             if (sdkVersion != o.sdkVersion) {
                 if (!sdkVersion) return false;
@@ -1191,6 +1219,12 @@
                 }
             }
 
+            if (screenConfig || o.screenConfig) {
+                if ((screenLayout != o.screenLayout) && requested->screenLayout) {
+                    return (screenLayout);
+                }
+            }
+
             if (version || o.version) {
                 if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
                     return (sdkVersion);
@@ -1282,6 +1316,12 @@
                 return false;
             }
         }
+        if (screenConfig != 0) {
+            if (settings.screenLayout != 0 && screenLayout != 0
+                && screenLayout != settings.screenLayout) {
+                return false;
+            }
+        }
         if (version != 0) {
             if (settings.sdkVersion != 0 && sdkVersion != 0
                 && sdkVersion != settings.sdkVersion) {
@@ -1310,13 +1350,13 @@
 
     String8 toString() const {
         char buf[200];
-        sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=0x%02x touch=0x%02x dens=0x%02x "
-                "kbd=0x%02x nav=0x%02x input=0x%02x screenW=0x%04x screenH=0x%04x vers=%d.%d",
+        sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d "
+                "kbd=%d nav=%d input=%d scrnW=%d scrnH=%d layout=%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, sdkVersion, minorVersion);
+                screenWidth, screenHeight, screenLayout, sdkVersion, minorVersion);
         return String8(buf);
     }
 };
diff --git a/libs/utils/BackupData.cpp b/libs/utils/BackupData.cpp
index 0868cff..cce754a 100644
--- a/libs/utils/BackupData.cpp
+++ b/libs/utils/BackupData.cpp
@@ -107,7 +107,10 @@
     } else {
         k = key;
     }
-    LOGD("m_keyPrefix=%s key=%s k=%s", m_keyPrefix.string(), key.string(), k.string());
+    if (true) {
+        LOGD("Writing entity: prefix='%s' key='%s' dataSize=%d", m_keyPrefix.string(), key.string(),
+                dataSize);
+    }
 
     entity_header_v1 header;
     ssize_t keyLen;
diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp
index 99a4abc..4ad9b51 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/utils/BackupHelpers.cpp
@@ -68,11 +68,15 @@
 
 const static int CURRENT_METADATA_VERSION = 1;
 
-#if 1 // TEST_BACKUP_HELPERS
+#if 1
+#define LOGP(f, x...)
+#else
+#if TEST_BACKUP_HELPERS
 #define LOGP(f, x...) printf(f "\n", x)
 #else
 #define LOGP(x...) LOGD(x)
 #endif
+#endif
 
 const static int ROUND_UP[4] = { 0, 3, 2, 1 };
 
@@ -349,7 +353,6 @@
 
         err = stat(file, &st);
         if (err != 0) {
-            LOGW("Error stating file %s", file);
             r.deleted = true;
         } else {
             r.deleted = false;
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index e4f9f0f..7a33220 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -3919,7 +3919,7 @@
                         printf("      NON-INTEGER ResTable_type ADDRESS: %p\n", type);
                         continue;
                     }
-                    printf("      config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d\n",
+                    printf("      config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d lyt=%d\n",
                            (int)configIndex,
                            type->config.language[0] ? type->config.language[0] : '-',
                            type->config.language[1] ? type->config.language[1] : '-',
@@ -3932,7 +3932,8 @@
                            type->config.inputFlags,
                            type->config.navigation,
                            dtohs(type->config.screenWidth),
-                           dtohs(type->config.screenHeight));
+                           dtohs(type->config.screenHeight),
+                           type->config.screenLayout);
                     size_t entryCount = dtohl(type->entryCount);
                     uint32_t entriesStart = dtohl(type->entriesStart);
                     if ((entriesStart&0x3) != 0) {
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index c356acb..8537cae 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -297,8 +297,32 @@
                 variantNativeString);
     }
     env->ReleaseStringUTFChars(language, langNativeString);
-    env->ReleaseStringUTFChars(language, countryNativeString);
-    env->ReleaseStringUTFChars(language, variantNativeString);
+    env->ReleaseStringUTFChars(country, countryNativeString);
+    env->ReleaseStringUTFChars(variant, variantNativeString);
+}
+
+
+static void
+android_tts_SynthProxy_loadLanguage(JNIEnv *env, jobject thiz, jint jniData,
+        jstring language, jstring country, jstring variant)
+{
+    if (jniData == 0) {
+        LOGE("android_tts_SynthProxy_loadLanguage(): invalid JNI data");
+        return;
+    }
+
+    SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
+    const char *langNativeString = env->GetStringUTFChars(language, 0);
+    const char *countryNativeString = env->GetStringUTFChars(country, 0);
+    const char *variantNativeString = env->GetStringUTFChars(variant, 0);
+    // TODO check return codes
+    if (pSynthData->mNativeSynthInterface) {
+        pSynthData->mNativeSynthInterface->loadLanguage(langNativeString, countryNativeString,
+                variantNativeString);
+    }
+    env->ReleaseStringUTFChars(language, langNativeString);
+    env->ReleaseStringUTFChars(country, countryNativeString);
+    env->ReleaseStringUTFChars(variant, variantNativeString);
 }
 
 
@@ -567,6 +591,10 @@
         "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
         (void*)android_tts_SynthProxy_setLanguage
     },
+    {   "native_loadLanguage",
+        "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
+        (void*)android_tts_SynthProxy_loadLanguage
+    },
     {   "native_setSpeechRate",
         "(II)V",
         (void*)android_tts_SynthProxy_setSpeechRate
diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index 3bdff37..a8eaaa43 100755
--- a/packages/TtsService/src/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
@@ -73,6 +73,13 @@
     public void setLanguage(String language, String country, String variant) {
         native_setLanguage(mJniData, language, country, variant);
     }
+    
+    /**
+     * Loads the language: it's not set, but prepared for use later.
+     */
+    public void loadLanguage(String language, String country, String variant) {
+        native_loadLanguage(mJniData, language, country, variant);
+    }
 
     /**
      * Sets the speech rate
@@ -149,6 +156,9 @@
 
     private native final void native_setLanguage(int jniData, String language, String country,
             String variant);
+    
+    private native final void native_loadLanguage(int jniData, String language, String country,
+            String variant);
 
     private native final void native_setSpeechRate(int jniData, int speechRate);
     
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 3c931b8..421b2ca 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -47,12 +47,13 @@
 public class TtsService extends Service implements OnCompletionListener {
 
     private static class SpeechItem {
-        public static final int SPEECH = 0;
-        public static final int EARCON = 1;
-        public static final int SILENCE = 2;
+        public static final int TEXT = 0;
+        public static final int IPA = 1;
+        public static final int EARCON = 2;
+        public static final int SILENCE = 3;
         public String mText = null;
         public ArrayList<String> mParams = null;
-        public int mType = SPEECH;
+        public int mType = TEXT;
         public long mDuration = 0;
 
         public SpeechItem(String text, ArrayList<String> params, int itemType) {
@@ -297,7 +298,29 @@
         if (queueMode == 0) {
             stop();
         }
-        mSpeechQueue.add(new SpeechItem(text, params, SpeechItem.SPEECH));
+        mSpeechQueue.add(new SpeechItem(text, params, SpeechItem.TEXT));
+        if (!mIsSpeaking) {
+            processSpeechQueue();
+        }
+    }
+
+    /**
+     * Speaks the given IPA text using the specified queueing mode and parameters.
+     *
+     * @param ipaText
+     *            The IPA text that should be spoken
+     * @param queueMode
+     *            0 for no queue (interrupts all previous utterances), 1 for
+     *            queued
+     * @param params
+     *            An ArrayList of parameters. This is not implemented for all
+     *            engines.
+     */
+    private void speakIpa(String ipaText, int queueMode, ArrayList<String> params) {
+        if (queueMode == 0) {
+            stop();
+        }
+        mSpeechQueue.add(new SpeechItem(ipaText, params, SpeechItem.IPA));
         if (!mIsSpeaking) {
             processSpeechQueue();
         }
@@ -455,13 +478,13 @@
             SpeechItem splitItem;
             while (end < currentSpeechItem.mText.length()){
                 splitText = currentSpeechItem.mText.substring(start, end);
-                splitItem = new SpeechItem(splitText, null, SpeechItem.SPEECH);
+                splitItem = new SpeechItem(splitText, null, SpeechItem.TEXT);
                 splitItems.add(splitItem);
                 start = end;
                 end = start + MAX_SPEECH_ITEM_CHAR_LENGTH - 1;
             }
             splitText = currentSpeechItem.mText.substring(start);
-            splitItem = new SpeechItem(splitText, null, SpeechItem.SPEECH);
+            splitItem = new SpeechItem(splitText, null, SpeechItem.TEXT);
             splitItems.add(splitItem);
             mSpeechQueue.remove(0);
             for (int i = splitItems.size() - 1; i >= 0; i--){
@@ -491,10 +514,12 @@
             // processSpeechQueue to continue running the queue
             Log.i("TTS processing: ", currentSpeechItem.mText);
             if (sr == null) {
-                if (currentSpeechItem.mType == SpeechItem.SPEECH) {
+                if (currentSpeechItem.mType == SpeechItem.TEXT) {
                     currentSpeechItem = splitCurrentTextIfNeeded(currentSpeechItem);
                     speakInternalOnly(currentSpeechItem.mText,
                             currentSpeechItem.mParams);
+                } else if (currentSpeechItem.mType == SpeechItem.IPA) {
+                    // TODO Implement IPA support
                 } else {
                     // This is either silence or an earcon that was missing
                     silence(currentSpeechItem.mDuration);
@@ -560,8 +585,7 @@
     }
 
     /**
-     * Synthesizes the given text using the specified queuing mode and
-     * parameters.
+     * Synthesizes the given text to a file using the specified parameters.
      *
      * @param text
      *            The String of text that should be synthesized
@@ -606,6 +630,52 @@
         return true;
     }
 
+    /**
+     * Synthesizes the given IPA text to a file using the specified parameters.
+     *
+     * @param ipaText
+     *            The String of IPA text that should be synthesized
+     * @param params
+     *            An ArrayList of parameters. The first element of this array
+     *            controls the type of voice to use.
+     * @param filename
+     *            The string that gives the full output filename; it should be
+     *            something like "/sdcard/myappsounds/mysound.wav".
+     * @return A boolean that indicates if the synthesis succeeded
+     */
+    private boolean synthesizeIpaToFile(String ipaText, ArrayList<String> params,
+            String filename, boolean calledFromApi) {
+        // Only stop everything if this is a call made by an outside app trying
+        // to
+        // use the API. Do NOT stop if this is a call from within the service as
+        // clearing the speech queue here would be a mistake.
+        if (calledFromApi) {
+            stop();
+        }
+        Log.i("TTS", "Synthesizing IPA to " + filename);
+        boolean synthAvailable = false;
+        try {
+            synthAvailable = synthesizerLock.tryLock();
+            if (!synthAvailable) {
+                return false;
+            }
+            // Don't allow a filename that is too long
+            // TODO use platform constant
+            if (filename.length() > 250) {
+                return false;
+            }
+            // TODO: Add nativeSynth.synthesizeIpaToFile(text, filename);
+        } finally {
+            // This check is needed because finally will always run; even if the
+            // method returns somewhere in the try block.
+            if (synthAvailable) {
+                synthesizerLock.unlock();
+            }
+        }
+        Log.i("TTS", "Completed synthesis for " + filename);
+        return true;
+    }
+
     @Override
     public IBinder onBind(Intent intent) {
         if (ACTION.equals(intent.getAction())) {
@@ -652,6 +722,27 @@
         }
 
         /**
+         * Speaks the given IPA text using the specified queueing mode and
+         * parameters.
+         *
+         * @param ipaText
+         *            The IPA text that should be spoken
+         * @param queueMode
+         *            0 for no queue (interrupts all previous utterances), 1 for
+         *            queued
+         * @param params
+         *            An ArrayList of parameters. The first element of this
+         *            array controls the type of voice to use.
+         */
+        public void speakIpa(String ipaText, int queueMode, String[] params) {
+            ArrayList<String> speakingParams = new ArrayList<String>();
+            if (params != null) {
+                speakingParams = new ArrayList<String>(Arrays.asList(params));
+            }
+            mSelf.speakIpa(ipaText, queueMode, speakingParams);
+        }
+
+        /**
          * Plays the earcon using the specified queueing mode and parameters.
          *
          * @param earcon
@@ -794,7 +885,7 @@
         }
 
         /**
-         * Speaks the given text using the specified queueing mode and
+         * Synthesizes the given text to a file using the specified
          * parameters.
          *
          * @param text
@@ -815,6 +906,29 @@
             }
             return mSelf.synthesizeToFile(text, speakingParams, filename, true);
         }
+
+        /**
+         * Synthesizes the given IPA text to a file using the specified
+         * parameters.
+         *
+         * @param ipaText
+         *            The String of IPA text that should be synthesized
+         * @param params
+         *            An ArrayList of parameters. The first element of this
+         *            array controls the type of voice to use.
+         * @param filename
+         *            The string that gives the full output filename; it should
+         *            be something like "/sdcard/myappsounds/mysound.wav".
+         * @return A boolean that indicates if the synthesis succeeded
+         */
+        public boolean synthesizeIpaToFile(String ipaText, String[] params,
+                String filename) {
+            ArrayList<String> speakingParams = new ArrayList<String>();
+            if (params != null) {
+                speakingParams = new ArrayList<String>(Arrays.asList(params));
+            }
+            return mSelf.synthesizeIpaToFile(ipaText, speakingParams, filename, true);
+        }
     };
 
 }
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index bc2eaed..c0f0d74 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -34,7 +34,6 @@
 import android.content.pm.Signature;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
@@ -61,7 +60,6 @@
 import java.io.EOFException;
 import java.io.File;
 import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.RandomAccessFile;
@@ -69,7 +67,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 
 class BackupManagerService extends IBackupManager.Stub {
@@ -138,10 +135,12 @@
     private class RestoreParams {
         public IBackupTransport transport;
         public IRestoreObserver observer;
+        public long token;
 
-        RestoreParams(IBackupTransport _transport, IRestoreObserver _obs) {
+        RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token) {
             transport = _transport;
             observer = _obs;
+            token = _token;
         }
     }
 
@@ -347,9 +346,8 @@
 
             case MSG_RUN_RESTORE:
             {
-                int token = msg.arg1;
                 RestoreParams params = (RestoreParams)msg.obj;
-                (new PerformRestoreThread(params.transport, params.observer, token)).start();
+                (new PerformRestoreThread(params.transport, params.observer, params.token)).start();
                 break;
             }
             }
@@ -531,6 +529,19 @@
 
     // clear an application's data, blocking until the operation completes or times out
     void clearApplicationDataSynchronous(String packageName) {
+        // Don't wipe packages marked allowClearUserData=false
+        try {
+            PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
+            if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) == 0) {
+                if (DEBUG) Log.i(TAG, "allowClearUserData=false so not wiping "
+                        + packageName);
+                return;
+            }
+        } catch (NameNotFoundException e) {
+            Log.w(TAG, "Tried to clear data for " + packageName + " but not found");
+            return;
+        }
+
         ClearDataObserver observer = new ClearDataObserver();
 
         synchronized(mClearDataLock) {
@@ -761,7 +772,7 @@
     class PerformRestoreThread extends Thread {
         private IBackupTransport mTransport;
         private IRestoreObserver mObserver;
-        private int mToken;
+        private long mToken;
         private RestoreSet mImage;
         private File mStateDir;
 
@@ -776,7 +787,7 @@
         }
 
         PerformRestoreThread(IBackupTransport transport, IRestoreObserver observer,
-                int restoreSetToken) {
+                long restoreSetToken) {
             mTransport = transport;
             mObserver = observer;
             mToken = restoreSetToken;
@@ -847,9 +858,7 @@
                     }
                 }
 
-                // STOPSHIP TODO: pick out the set for this token (instead of images[0])
-                long token = images[0].token;
-                if (!mTransport.startRestore(token, restorePackages.toArray(new PackageInfo[0]))) {
+                if (!mTransport.startRestore(mToken, restorePackages.toArray(new PackageInfo[0]))) {
                     // STOPSHIP TODO: Handle the failure somehow?
                     Log.e(TAG, "Error starting restore operation");
                     return;
@@ -1198,7 +1207,7 @@
             }
         }
 
-        public int performRestore(int token, IRestoreObserver observer)
+        public int performRestore(long token, IRestoreObserver observer)
                 throws android.os.RemoteException {
             mContext.enforceCallingPermission("android.permission.BACKUP", "performRestore");
 
@@ -1206,8 +1215,7 @@
                 for (int i = 0; i < mRestoreSets.length; i++) {
                     if (token == mRestoreSets[i].token) {
                         Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
-                        msg.obj = new RestoreParams(mRestoreTransport, observer);
-                        msg.arg1 = token;
+                        msg.obj = new RestoreParams(mRestoreTransport, observer, token);
                         mBackupHandler.sendMessage(msg);
                         return 0;
                     }
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index fef3598..68bf4fb 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -504,6 +504,7 @@
                 if (mPhoneMemMonitor.checkLocked(curTime, mPhonePid,
                         mPhonePss)) {
                     // Just kill the phone process and let it restart.
+                    Log.i(TAG, "Watchdog is killing the phone process");
                     Process.killProcess(mPhonePid);
                 }
             } else {
@@ -848,6 +849,7 @@
 
             // Only kill the process if the debugger is not attached.
             if (!Debug.isDebuggerConnected()) {
+                Log.i(TAG, "Watchdog is killing the system process");
                 Process.killProcess(Process.myPid());
             }
         }
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 3b47ae7..5ea7504 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -77,6 +77,7 @@
 import android.os.SystemProperties;
 import android.os.TokenWatcher;
 import android.provider.Settings;
+import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.SparseIntArray;
@@ -415,7 +416,8 @@
     final Rect mTempRect = new Rect();
 
     final Configuration mTempConfiguration = new Configuration();
-
+    int screenLayout = Configuration.SCREENLAYOUT_UNDEFINED;
+    
     public static WindowManagerService main(Context context,
             PowerManagerService pm, boolean haveInputMethods) {
         WMThread thr = new WMThread(context, pm, haveInputMethods);
@@ -3724,6 +3726,40 @@
             orientation = Configuration.ORIENTATION_LANDSCAPE;
         }
         config.orientation = orientation;
+        
+        if (screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
+            // Note we only do this once because at this point we don't
+            // expect the screen to change in this way at runtime, and want
+            // to avoid all of this computation for every config change.
+            DisplayMetrics dm = new DisplayMetrics();
+            mDisplay.getMetrics(dm);
+            int longSize = dw;
+            int shortSize = dh;
+            if (longSize < shortSize) {
+                int tmp = longSize;
+                longSize = shortSize;
+                shortSize = tmp;
+            }
+            longSize = (int)(longSize/dm.density);
+            shortSize = (int)(shortSize/dm.density);
+            
+            // These semi-magic numbers define our compatibility modes for
+            // applications with different screens.  Don't change unless you
+            // make sure to test lots and lots of apps!
+            if (longSize < 470) {
+                // This is shorter than an HVGA normal density screen (which
+                // is 480 pixels on its long side).
+                screenLayout = Configuration.SCREENLAYOUT_SMALL;
+            } else if (longSize > 490 && shortSize > 330) {
+                // This is larger than an HVGA normal density screen (which
+                // is 480x320 pixels).
+                screenLayout = Configuration.SCREENLAYOUT_LARGE;
+            } else {
+                screenLayout = Configuration.SCREENLAYOUT_NORMAL;
+            }
+        }
+        config.screenLayout = screenLayout;
+        
         config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
         config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
         mPolicy.adjustConfigurationLw(config);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index fd1dfc83..6d04b6b 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -10472,8 +10472,17 @@
     // done with this agent
     public void unbindBackupAgent(ApplicationInfo appInfo) {
         if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo);
+        if (appInfo == null) {
+            Log.w(TAG, "unbind backup agent for null app");
+            return;
+        }
 
         synchronized(this) {
+            if (mBackupAppName == null) {
+                Log.w(TAG, "Unbinding backup agent with no active backup");
+                return;
+            }
+
             if (!mBackupAppName.equals(appInfo.packageName)) {
                 Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
                 return;
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index a835dee..03bdbda 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -789,7 +789,7 @@
         if (inStream.read(8) != 3) {
             throw new CodingException("MESSAGE_IDENTIFIER subparam size incorrect");
         }
-        bData.messageType = inStream.read(4);
+        bData.messageType = (byte)inStream.read(4);
         bData.messageId = inStream.read(8) << 8;
         bData.messageId |= inStream.read(8);
         bData.hasUserDataHeader = (inStream.read(1) == 1);
@@ -799,7 +799,7 @@
     private static void decodeUserData(BearerData bData, BitwiseInputStream inStream)
         throws BitwiseInputStream.AccessException
     {
-        byte paramBytes = inStream.read(8);
+        int paramBytes = inStream.read(8);
         bData.userData = new UserData();
         bData.userData.msgEncoding = inStream.read(5);
         bData.userData.msgEncodingSet = true;
@@ -867,7 +867,7 @@
             inStream.skip(offset);
             byte[] expandedData = new byte[numFields];
             for (int i = 0; i < numFields; i++) {
-                expandedData[i] = inStream.read(7);
+                expandedData[i] = (byte)inStream.read(7);
             }
             return new String(expandedData, 0, numFields, "US-ASCII");
         } catch (java.io.UnsupportedEncodingException ex) {
@@ -922,7 +922,7 @@
     private static void decodeReplyOption(BearerData bData, BitwiseInputStream inStream)
         throws BitwiseInputStream.AccessException, CodingException
     {
-        byte paramBytes = inStream.read(8);
+        int paramBytes = inStream.read(8);
         if (paramBytes != 1) {
             throw new CodingException("REPLY_OPTION subparam size incorrect");
         }
@@ -985,18 +985,18 @@
     private static void decodeCallbackNumber(BearerData bData, BitwiseInputStream inStream)
         throws BitwiseInputStream.AccessException, CodingException
     {
-        byte paramBytes = inStream.read(8);
+        int paramBytes = inStream.read(8);
         CdmaSmsAddress addr = new CdmaSmsAddress();
-        addr.digitMode = inStream.read(1);
+        addr.digitMode = (byte)inStream.read(1);
         byte fieldBits = 4;
         byte consumedBits = 1;
         if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
             addr.ton = inStream.read(3);
-            addr.numberPlan = inStream.read(4);
+            addr.numberPlan = (byte)inStream.read(4);
             fieldBits = 8;
             consumedBits += 7;
         }
-        addr.numberOfDigits = inStream.read(8);
+        addr.numberOfDigits = (byte)inStream.read(8);
         consumedBits += 8;
         int remainingBits = (paramBytes * 8) - consumedBits;
         int dataBits = addr.numberOfDigits * fieldBits;
@@ -1076,7 +1076,7 @@
         if (inStream.read(8) != 1) {
             throw new CodingException("PRIVACY_INDICATOR subparam size incorrect");
         }
-        bData.privacy = inStream.read(2);
+        bData.privacy = (byte)inStream.read(2);
         inStream.skip(6);
         bData.privacyIndicatorSet = true;
     }
@@ -1097,7 +1097,7 @@
         if (inStream.read(8) != 1) {
             throw new CodingException("DISPLAY_MODE subparam size incorrect");
         }
-        bData.displayMode = inStream.read(2);
+        bData.displayMode = (byte)inStream.read(2);
         inStream.skip(6);
         bData.displayModeSet = true;
     }
@@ -1108,7 +1108,7 @@
         if (inStream.read(8) != 1) {
             throw new CodingException("PRIORITY_INDICATOR subparam size incorrect");
         }
-        bData.priority = inStream.read(2);
+        bData.priority = (byte)inStream.read(2);
         inStream.skip(6);
         bData.priorityIndicatorSet = true;
     }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java b/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java
index a935247..c5562b3 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java
@@ -25,6 +25,8 @@
 
 import android.util.Log;
 
+import java.util.Random;
+
 public class BitwiseStreamsTest extends AndroidTestCase {
     private final static String LOG_TAG = "BitwiseStreamsTest";
 
@@ -39,7 +41,7 @@
         BitwiseInputStream inStream = new BitwiseInputStream(outBuf);
         byte[] inBufDup = new byte[inBuf.length];
         inStream.skip(offset);
-        for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
+        for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8);
         assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
     }
 
@@ -53,7 +55,7 @@
         BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
         inStream.skip(offset);
         byte[] inBufDup = new byte[inBuf.length];
-        for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
+        for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8);
         assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
     }
 
@@ -67,7 +69,7 @@
         BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
         inStream.skip(offset);
         byte[] inBufDup = new byte[inBuf.length];
-        for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
+        for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8);
         assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
     }
 
@@ -84,12 +86,33 @@
         BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
         inStream.skip(offset);
         byte[] inBufDup = new byte[inBuf.length];
-        for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
+        for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8);
         assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
     }
 
     @SmallTest
     public void testFive() throws Exception {
+        Random random = new Random();
+        int iterations = 10000;
+        int[] sizeArr = new int[iterations];
+        int[] valueArr = new int[iterations];
+        BitwiseOutputStream outStream = new BitwiseOutputStream(iterations * 4);
+        for (int i = 0; i < iterations; i++) {
+            int x = random.nextInt();
+            int size = (x & 0x07) + 1;
+            int value = x & (-1 >>> (32 - size));
+            sizeArr[i] = size;
+            valueArr[i] = value;
+            outStream.write(size, value);
+        }
+        BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
+        for (int i = 0; i < iterations; i++) {
+            assertEquals(valueArr[i], inStream.read(sizeArr[i]));
+        }
+    }
+
+    @SmallTest
+    public void testSix() throws Exception {
         int num_runs = 10;
         long start = android.os.SystemClock.elapsedRealtime();
         for (int run = 0; run < num_runs; run++) {
@@ -104,7 +127,7 @@
             BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
             inStream.skip(offset);
             byte[] inBufDup = new byte[inBuf.length];
-            for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
+            for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8);
             assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
         }
         long end = android.os.SystemClock.elapsedRealtime();
diff --git a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
index b2529811..9188e04b 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
@@ -171,14 +171,14 @@
         assertEquals(bearerData.msgCenterTimeStamp.minute, 1);
         assertEquals(bearerData.msgCenterTimeStamp.second, 59);
         assertEquals(bearerData.validityPeriodAbsolute, null);
-        assertEquals(bearerData.validityPeriodRelative, -63);
+        assertEquals(bearerData.validityPeriodRelative, 193);
         assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997);
         assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5);
         assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18);
         assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0);
         assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0);
         assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0);
-        assertEquals(bearerData.deferredDeliveryTimeRelative, -57);
+        assertEquals(bearerData.deferredDeliveryTimeRelative, 199);
         assertEquals(bearerData.hasUserDataHeader, false);
         assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII);
         assertEquals(bearerData.userData.numFields, 2);
@@ -225,7 +225,7 @@
         assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0);
         assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0);
         assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0);
-        assertEquals(bearerData.deferredDeliveryTimeRelative, -110);
+        assertEquals(bearerData.deferredDeliveryTimeRelative, 146);
         assertEquals(bearerData.hasUserDataHeader, false);
         assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII);
         assertEquals(bearerData.userData.numFields, 2);
diff --git a/tests/DpiTest/AndroidManifest.xml b/tests/DpiTest/AndroidManifest.xml
index f71cff2..64ad7be 100644
--- a/tests/DpiTest/AndroidManifest.xml
+++ b/tests/DpiTest/AndroidManifest.xml
@@ -16,6 +16,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.google.android.test.dpi">
+    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="3" />
+    <supports-screens android:smallScreens="true" />
     <application android:label="DpiTest">
         <activity android:name="DpiTestActivity" android:label="DpiTest">
             <intent-filter>
diff --git a/tests/DpiTest/res/values-largeScreen/strings.xml b/tests/DpiTest/res/values-largeScreen/strings.xml
new file mode 100644
index 0000000..f4dd543
--- /dev/null
+++ b/tests/DpiTest/res/values-largeScreen/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="act_title">DpiTest: Large Screen</string>
+</resources>
diff --git a/tests/DpiTest/res/values-normalScreen/strings.xml b/tests/DpiTest/res/values-normalScreen/strings.xml
new file mode 100644
index 0000000..256d696
--- /dev/null
+++ b/tests/DpiTest/res/values-normalScreen/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="act_title">DpiTest: Normal Screen</string>
+</resources>
diff --git a/tests/DpiTest/res/values-smallScreen/strings.xml b/tests/DpiTest/res/values-smallScreen/strings.xml
new file mode 100644
index 0000000..cdb4ac9
--- /dev/null
+++ b/tests/DpiTest/res/values-smallScreen/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="act_title">DpiTest: Small Screen</string>
+</resources>
diff --git a/tests/DpiTest/res/values/strings.xml b/tests/DpiTest/res/values/strings.xml
new file mode 100644
index 0000000..ef924ac
--- /dev/null
+++ b/tests/DpiTest/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="act_title">DpiTest: Unknown Screen</string>
+</resources>
diff --git a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
index 3759622..5a9f3f5 100644
--- a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
+++ b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
@@ -34,6 +34,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        this.setTitle(R.string.act_title);
         LinearLayout root = new LinearLayout(this);
         root.setOrientation(LinearLayout.VERTICAL);
 
diff --git a/tests/backup/src/com/android/backuptest/BackupTestAgent.java b/tests/backup/src/com/android/backuptest/BackupTestAgent.java
index 6acd90c..8e4fd39 100644
--- a/tests/backup/src/com/android/backuptest/BackupTestAgent.java
+++ b/tests/backup/src/com/android/backuptest/BackupTestAgent.java
@@ -18,6 +18,7 @@
 
 import android.backup.BackupHelperAgent;
 import android.backup.FileBackupHelper;
+import android.backup.SharedPreferencesBackupHelper;
 
 public class BackupTestAgent extends BackupHelperAgent
 {
@@ -25,6 +26,7 @@
         addHelper("data_files", new FileBackupHelper(this, BackupTestActivity.FILE_NAME));
         addHelper("more_data_files", new FileBackupHelper(this, "another_file.txt", "3.txt",
                     "empty.txt"));
+        addHelper("shared_prefs", new SharedPreferencesBackupHelper(this, "settings", "raw"));
     }
 }
 
diff --git a/tests/backup/test_backup.sh b/tests/backup/test_backup.sh
index 6ef5dff..dbf9ed2 100755
--- a/tests/backup/test_backup.sh
+++ b/tests/backup/test_backup.sh
@@ -9,6 +9,8 @@
 adb shell "rm /data/data/com.android.backuptest/files/* ; \
            mkdir /data/data/com.android.backuptest ; \
            mkdir /data/data/com.android.backuptest/files ; \
+           mkdir /data/data/com.android.backuptest/shared_prefs ; \
+           echo -n \"<map><int name=\\\"pref\\\" value=\\\"1\\\" /></map>\" > /data/data/com.android.backuptest/shared_prefs/raw.xml ; \
            echo -n first file > /data/data/com.android.backuptest/files/file.txt ; \
            echo -n asdf > /data/data/com.android.backuptest/files/another_file.txt ; \
            echo -n 3 > /data/data/com.android.backuptest/files/3.txt ; \
@@ -20,3 +22,6 @@
 
 # run the backup
 adb shell bmgr run
+
+
+
diff --git a/tests/backup/test_restore.sh b/tests/backup/test_restore.sh
index f3d581e..ccf29cf 100755
--- a/tests/backup/test_restore.sh
+++ b/tests/backup/test_restore.sh
@@ -2,7 +2,7 @@
 
 function check_file
 {
-    data=$(adb shell cat /data/data/com.android.backuptest/files/$1)
+    data=$(adb shell cat /data/data/com.android.backuptest/$1)
     if [ "$data" = "$2" ] ; then
         echo "$1 has correct value [$2]"
     else
@@ -16,8 +16,12 @@
 echo --- Previous files
 adb shell "ls -l /data/data/com.android.backuptest/files"
 adb shell "rm /data/data/com.android.backuptest/files/*"
-echo --- Erased files
+echo --- Previous shared_prefs
+adb shell "ls -l /data/data/com.android.backuptest/shared_prefs"
+adb shell "rm /data/data/com.android.backuptest/shared_prefs/*"
+echo --- Erased files and shared_prefs
 adb shell "ls -l /data/data/com.android.backuptest/files"
+adb shell "ls -l /data/data/com.android.backuptest/shared_prefs"
 echo ---
 
 echo
@@ -32,15 +36,18 @@
 echo
 
 # check the results
-check_file file.txt "first file"
-check_file another_file.txt "asdf"
-check_file 3.txt "3"
-check_file empty.txt ""
+check_file files/file.txt "first file"
+check_file files/another_file.txt "asdf"
+check_file files/3.txt "3"
+check_file files/empty.txt ""
+check_file shared_prefs/raw.xml '<map><int name="pref" value="1" /></map>'
 
 echo
 echo
 echo
 echo --- Restored files
 adb shell "ls -l /data/data/com.android.backuptest/files"
+echo --- Restored shared_prefs
+adb shell "ls -l /data/data/com.android.backuptest/shared_prefs"
 echo ---
 echo
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 6bc1ee6..67af116 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -187,6 +187,13 @@
         return 0;
     }
 
+    // screen layout
+    if (getScreenLayoutName(part.string(), &config)) {
+        *axis = AXIS_SCREENLAYOUT;
+        *value = config.screenLayout;
+        return 0;
+    }
+
     // version
     if (getVersionName(part.string(), &config)) {
         *axis = AXIS_VERSION;
@@ -202,7 +209,7 @@
 {
     Vector<String8> parts;
 
-    String8 mcc, mnc, loc, orient, den, touch, key, keysHidden, nav, size, vers;
+    String8 mcc, mnc, loc, orient, den, touch, key, keysHidden, nav, size, layout, vers;
 
     const char *p = dir;
     const char *q;
@@ -378,6 +385,18 @@
         //printf("not screen size: %s\n", part.string());
     }
 
+    if (getScreenLayoutName(part.string())) {
+        layout = part;
+
+        index++;
+        if (index == N) {
+            goto success;
+        }
+        part = parts[index];
+    } else {
+        //printf("not screen layout: %s\n", part.string());
+    }
+
     if (getVersionName(part.string())) {
         vers = part;
 
@@ -404,6 +423,7 @@
     this->keyboard = key;
     this->navigation = nav;
     this->screenSize = size;
+    this->screenLayout = layout;
     this->version = vers;
 
     // what is this anyway?
@@ -435,6 +455,8 @@
     s += ",";
     s += screenSize;
     s += ",";
+    s += screenLayout;
+    s += ",";
     s += version;
     return s;
 }
@@ -483,6 +505,10 @@
         s += "-";
         s += screenSize;
     }
+    if (this->screenLayout != "") {
+        s += "-";
+        s += screenLayout;
+    }
     if (this->version != "") {
         s += "-";
         s += version;
@@ -786,6 +812,26 @@
     return true;
 }
 
+bool AaptGroupEntry::getScreenLayoutName(const char* name,
+                                     ResTable_config* out)
+{
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->screenLayout = out->SCREENLAYOUT_ANY;
+        return true;
+    } else if (strcmp(name, "smallscreen") == 0) {
+        if (out) out->screenLayout = out->SCREENLAYOUT_SMALL;
+        return true;
+    } else if (strcmp(name, "normalscreen") == 0) {
+        if (out) out->screenLayout = out->SCREENLAYOUT_NORMAL;
+        return true;
+    } else if (strcmp(name, "largescreen") == 0) {
+        if (out) out->screenLayout = out->SCREENLAYOUT_LARGE;
+        return true;
+    }
+
+    return false;
+}
+
 bool AaptGroupEntry::getVersionName(const char* name,
                                     ResTable_config* out)
 {
@@ -828,6 +874,7 @@
     if (v == 0) v = keyboard.compare(o.keyboard);
     if (v == 0) v = navigation.compare(o.navigation);
     if (v == 0) v = screenSize.compare(o.screenSize);
+    if (v == 0) v = screenLayout.compare(o.screenLayout);
     if (v == 0) v = version.compare(o.version);
     return v;
 }
@@ -846,6 +893,7 @@
     getKeyboardName(keyboard.string(), &params);
     getNavigationName(navigation.string(), &params);
     getScreenSizeName(screenSize.string(), &params);
+    getScreenLayoutName(screenLayout.string(), &params);
     getVersionName(version.string(), &params);
     return params;
 }
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 01c8140..3b96412 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -37,6 +37,7 @@
     AXIS_KEYBOARD,
     AXIS_NAVIGATION,
     AXIS_SCREENSIZE,
+    AXIS_SCREENLAYOUT,
     AXIS_VERSION
 };
 
@@ -62,6 +63,7 @@
     String8 keyboard;
     String8 navigation;
     String8 screenSize;
+    String8 screenLayout;
     String8 version;
 
     bool initFromDirName(const char* dir, String8* resType);
@@ -78,6 +80,7 @@
     static bool getKeyboardName(const char* name, ResTable_config* out = NULL);
     static bool getNavigationName(const char* name, ResTable_config* out = NULL);
     static bool getScreenSizeName(const char* name, ResTable_config* out = NULL);
+    static bool getScreenLayoutName(const char* name, ResTable_config* out = NULL);
     static bool getVersionName(const char* name, ResTable_config* out = NULL);
 
     int compare(const AaptGroupEntry& o) const;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 503f661..e04491d 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -329,6 +329,9 @@
     TARGET_SDK_VERSION_ATTR = 0x01010270,
     TEST_ONLY_ATTR = 0x01010272,
     DENSITY_ATTR = 0x0101026c,
+    SMALL_SCREEN_ATTR = 0x01010284,
+    NORMAL_SCREEN_ATTR = 0x01010285,
+    LARGE_SCREEN_ATTR = 0x01010286,
 };
 
 const char *getComponentName(String8 &pkgName, String8 &componentName) {
@@ -499,6 +502,10 @@
             bool isLauncherActivity = false;
             bool withinApplication = false;
             bool withinReceiver = false;
+            int targetSdk = 0;
+            int smallScreen = 1;
+            int normalScreen = 1;
+            int largeScreen = 1;
             String8 pkg;
             String8 activityName;
             String8 activityLabel;
@@ -572,8 +579,10 @@
                                         error.string());
                                 goto bail;
                             }
+                            if (name == "Donut") targetSdk = 4;
                             printf("sdkVersion:'%s'\n", name.string());
                         } else if (code != -1) {
+                            targetSdk = code;
                             printf("sdkVersion:'%d'\n", code);
                         }
                         code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error);
@@ -585,8 +594,12 @@
                                         error.string());
                                 goto bail;
                             }
+                            if (name == "Donut" && targetSdk < 4) targetSdk = 4;
                             printf("targetSdkVersion:'%s'\n", name.string());
                         } else if (code != -1) {
+                            if (targetSdk < code) {
+                                targetSdk = code;
+                            }
                             printf("targetSdkVersion:'%d'\n", code);
                         }
                     } else if (tag == "uses-configuration") {
@@ -625,6 +638,13 @@
                             goto bail;
                         }
                         printf("supports-density:'%d'\n", dens);
+                    } else if (tag == "supports-screens") {
+                        smallScreen = getIntegerAttribute(tree,
+                                SMALL_SCREEN_ATTR, NULL, 1);
+                        normalScreen = getIntegerAttribute(tree,
+                                NORMAL_SCREEN_ATTR, NULL, 1);
+                        largeScreen = getIntegerAttribute(tree,
+                                LARGE_SCREEN_ATTR, NULL, 1);
                     }
                 } else if (depth == 3 && withinApplication) {
                     withinActivity = false;
@@ -733,6 +753,25 @@
                 }
             }
             
+            // Determine default values for any unspecified screen sizes,
+            // based on the target SDK of the package.  As of 4 (donut)
+            // the screen size support was introduced, so all default to
+            // enabled.
+            if (smallScreen > 0) {
+                smallScreen = targetSdk >= 4 ? -1 : 0;
+            }
+            if (normalScreen > 0) {
+                normalScreen = -1;
+            }
+            if (largeScreen > 0) {
+                largeScreen = targetSdk >= 4 ? -1 : 0;
+            }
+            printf("supports-screens:");
+            if (smallScreen != 0) printf(" 'small'");
+            if (normalScreen != 0) printf(" 'normal'");
+            if (largeScreen != 0) printf(" 'large'");
+            printf("\n");
+            
             printf("locales:");
             Vector<String8> locales;
             res.getLocales(&locales);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
index 1fa11af..06dd96f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
@@ -59,7 +59,7 @@
     public 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 version)  {
+            int screenLayout, int version)  {
         
         Configuration c = new Configuration();
         c.mcc = mcc;
@@ -70,5 +70,6 @@
         c.keyboardHidden = keyboardHidden;
         c.navigation = navigation;
         c.orientation = orientation;
+        c.screenLayout = screenLayout;
     }
 }