Merge change 26323 into eclair

* changes:
  Fix bug with ScrollView so that text entry fields are not hidden by virtual keyboard.
diff --git a/api/current.xml b/api/current.xml
index efeecb6..fa54a10 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2825,6 +2825,28 @@
  visibility="public"
 >
 </field>
+<field name="detailColumn"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843427"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="detailSocialSummary"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843428"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="dial"
  type="int"
  transient="false"
@@ -7522,6 +7544,17 @@
  visibility="public"
 >
 </field>
+<field name="summaryColumn"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843426"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="summaryOff"
  type="int"
  transient="false"
@@ -36741,6 +36774,17 @@
  visibility="public"
 >
 </field>
+<field name="FLAG_ACTIVITY_NO_ANIMATION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="65536"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="FLAG_ACTIVITY_NO_HISTORY"
  type="int"
  transient="false"
@@ -67644,6 +67688,17 @@
  visibility="public"
 >
 </method>
+<method name="getFocusMode"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getInt"
  return="int"
  abstract="false"
@@ -67789,6 +67844,17 @@
  visibility="public"
 >
 </method>
+<method name="getSupportedFocusModes"
+ return="java.util.List&lt;java.lang.String&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getSupportedPictureFormats"
  return="java.util.List&lt;java.lang.Integer&gt;"
  abstract="false"
@@ -67970,6 +68036,19 @@
 <parameter name="value" type="java.lang.String">
 </parameter>
 </method>
+<method name="setFocusMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
 <method name="setGpsAltitude"
  return="void"
  abstract="false"
@@ -68371,6 +68450,61 @@
  visibility="public"
 >
 </field>
+<field name="FLASH_MODE_VIDEO_LIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;video-light&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FOCUS_MODE_AUTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;auto&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FOCUS_MODE_FIXED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;fixed&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FOCUS_MODE_INFINITY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;infinity&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FOCUS_MODE_MACRO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;macro&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SCENE_MODE_ACTION"
  type="java.lang.String"
  transient="false"
@@ -134730,6 +134864,21 @@
 <parameter name="addr" type="int">
 </parameter>
 </method>
+<method name="formatShortFileSize"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="number" type="long">
+</parameter>
+</method>
 </class>
 <class name="Time"
  extends="java.lang.Object"
diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c
index ec4e2a2..ba74c78 100644
--- a/cmds/keystore/keystore.c
+++ b/cmds/keystore/keystore.c
@@ -291,7 +291,7 @@
     return NO_ERROR;
 }
 
-static int8_t scan()
+static int8_t saw()
 {
     DIR *dir = opendir(".");
     struct dirent *file;
@@ -411,7 +411,7 @@
     INSERT   =   4,
     DELETE   =   8,
     EXIST    =  16,
-    SCAN     =  32,
+    SAW      =  32,
     RESET    =  64,
     PASSWORD = 128,
     LOCK     = 256,
@@ -430,7 +430,7 @@
     {insert,   'i', NO_ERROR, INSERT,   {KEY_SIZE, VALUE_SIZE}},
     {delete,   'd', 0,        DELETE,   {KEY_SIZE}},
     {exist,    'e', 0,        EXIST,    {KEY_SIZE}},
-    {scan,     's', 0,        SCAN,     {KEY_SIZE}},
+    {saw,      's', 0,        SAW,      {KEY_SIZE}},
     {reset,    'r', 0,        RESET,    {0}},
     {password, 'p', 0,        PASSWORD, {PASSWORD_SIZE, PASSWORD_SIZE}},
     {lock,     'l', NO_ERROR, LOCK,     {0}},
@@ -446,7 +446,7 @@
     {AID_SYSTEM,   0,          ~GET},
     {AID_VPN,      AID_SYSTEM, GET},
     {AID_WIFI,     AID_SYSTEM, GET},
-    {0,            0,          TEST | GET | INSERT | DELETE | EXIST | SCAN},
+    {0,            0,          TEST | GET | INSERT | DELETE | EXIST | SAW},
 };
 
 static int8_t process(int8_t code) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a86fe90..4561899 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -790,8 +790,8 @@
      * @see #onPostCreate
      */
     protected void onCreate(Bundle savedInstanceState) {
-        mVisibleFromClient = mWindow.getWindowStyle().getBoolean(
-                com.android.internal.R.styleable.Window_windowNoDisplay, true);
+        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
+                com.android.internal.R.styleable.Window_windowNoDisplay, false);
         mCalled = true;
     }
 
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index caf72af..c0a0480 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -1144,7 +1144,7 @@
         String query = mSearchAutoComplete.getText().toString();
         String action = mGlobalSearchMode ? Intent.ACTION_WEB_SEARCH : Intent.ACTION_SEARCH;
         Intent intent = createIntent(action, null, null, query, null,
-                actionKey, actionMsg);
+                actionKey, actionMsg, null);
         // Allow GlobalSearch to log and create shortcut for searches launched by
         // the search button, enter key or an action key.
         if (mGlobalSearchMode) {
@@ -1579,9 +1579,10 @@
 
             String query = getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY);
             String extraData = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA);
+            String mode = mGlobalSearchMode ? SearchManager.MODE_GLOBAL_SEARCH_SUGGESTION : null;
 
             return createIntent(action, dataUri, extraData, query, componentName, actionKey,
-                    actionMsg);
+                    actionMsg, mode);
         } catch (RuntimeException e ) {
             int rowNum;
             try {                       // be really paranoid now
@@ -1607,10 +1608,12 @@
      *        or {@link KeyEvent#KEYCODE_UNKNOWN} if none.
      * @param actionMsg The message for the action key that was pressed,
      *        or <code>null</code> if none.
+     * @param mode The search mode, one of the acceptable values for
+     *             {@link SearchManager#SEARCH_MODE}, or {@code null}.
      * @return The intent.
      */
     private Intent createIntent(String action, Uri data, String extraData, String query,
-            String componentName, int actionKey, String actionMsg) {
+            String componentName, int actionKey, String actionMsg, String mode) {
         // Now build the Intent
         Intent intent = new Intent(action);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -1634,6 +1637,9 @@
             intent.putExtra(SearchManager.ACTION_KEY, actionKey);
             intent.putExtra(SearchManager.ACTION_MSG, actionMsg);
         }
+        if (mode != null) {
+            intent.putExtra(SearchManager.SEARCH_MODE, mode);
+        }
         // Only allow 3rd-party intents from GlobalSearch
         if (!mGlobalSearchMode) {
             intent.setComponent(mSearchable.getSearchActivity());
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 6a0285d..f0876f4 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1289,6 +1289,25 @@
     public final static String SOURCE = "source";
 
     /**
+     * Intent extra data key: Use {@link android.content.Intent#getBundleExtra
+     * content.Intent.getBundleExtra(SEARCH_MODE)} to get the search mode used
+     * to launch the intent.
+     * The only current value for this is {@link #MODE_GLOBAL_SEARCH_SUGGESTION}.
+     *
+     * @hide
+     */
+    public final static String SEARCH_MODE = "search_mode";
+
+    /**
+     * Value for the {@link #SEARCH_MODE} key.
+     * This is used if the intent was launched by clicking a suggestion in global search
+     * mode (Quick Search Box).
+     *
+     * @hide
+     */
+    public static final String MODE_GLOBAL_SEARCH_SUGGESTION = "global_search_suggestion";
+
+    /**
      * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
      * {@link android.content.Intent#getIntExtra content.Intent.getIntExtra()}
      * to obtain the keycode that the user used to trigger this query.  It will be zero if the
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 409c744..24ad06a 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -83,6 +83,12 @@
      * @param uuid
      */
     public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) {
+        if ((uuidArray == null || uuidArray.length == 0) && uuid == null)
+            return true;
+
+        if (uuidArray == null)
+            return false;
+
         for (ParcelUuid element: uuidArray) {
             if (element.equals(uuid)) return true;
         }
@@ -98,7 +104,14 @@
      */
     public static boolean containsAnyUuid(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
         if (uuidA == null && uuidB == null) return true;
-        if (uuidA == null || uuidB == null) return false;
+
+        if (uuidA == null) {
+            return uuidB.length == 0 ? true : false;
+        }
+
+        if (uuidB == null) {
+            return uuidA.length == 0 ? true : false;
+        }
 
         HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
         for (ParcelUuid uuid: uuidB) {
@@ -117,7 +130,12 @@
      */
     public static boolean containsAllUuids(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
         if (uuidA == null && uuidB == null) return true;
-        if (uuidA == null || uuidB == null) return false;
+
+        if (uuidA == null) {
+            return uuidB.length == 0 ? true : false;
+        }
+
+        if (uuidB == null) return true;
 
         HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
         for (ParcelUuid uuid: uuidB) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 7366b8b..f6ca50d 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2318,6 +2318,18 @@
      */
     public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 0X00020000;
     /**
+     * If set in an Intent passed to {@link Context#startActivity Context.startActivity()},
+     * this flag will prevent the system from applying an activity transition
+     * animation to go to the next activity state.  This doesn't mean an
+     * animation will never run -- if another activity change happens that doesn't
+     * specify this flag before the activity started here is displayed, then
+     * that transition will be used.  This this flag can be put to good use
+     * when you are going to do a series of activity operations but the
+     * animation seen by the user shouldn't be driven by the first activity
+     * change but rather a later one.
+     */
+    public static final int FLAG_ACTIVITY_NO_ANIMATION = 0X00010000;
+    /**
      * If set, when sending a broadcast only registered receivers will be
      * called -- no BroadcastReceiver components will be launched.
      */
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 50faf57..11c67cc 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -274,6 +274,25 @@
          * Apply translation to the canvas that is necessary to draw the content.
          */
         public void translateCanvas(Canvas canvas) {
+            if (applicationScale == 1.5f) {
+                /*  When we scale for compatibility, we can put our stretched
+                    bitmaps and ninepatches on exacty 1/2 pixel boundaries,
+                    which can give us inconsistent drawing due to imperfect
+                    float precision in the graphics engine's inverse matrix.
+                 
+                    As a work-around, we translate by a tiny amount to avoid
+                    landing on exact pixel centers and boundaries, giving us
+                    the slop we need to draw consistently.
+                 
+                    This constant is meant to resolve to 1/255 after it is
+                    scaled by 1.5 (applicationScale). Note, this is just a guess
+                    as to what is small enough not to create its own artifacts,
+                    and big enough to avoid the precision problems. Feel free
+                    to experiment with smaller values as you choose.
+                 */
+                final float tinyOffset = 2.0f / (3 * 255);
+                canvas.translate(tinyOffset, tinyOffset);
+            }
             canvas.scale(applicationScale, applicationScale);
         }
 
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index cc44400..5f1a3c5 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -357,10 +357,12 @@
 
     /**
      * Starts auto-focus function and registers a callback function to run when
-     * camera is focused. Only valid after startPreview() has been called. If
-     * the camera does not support auto-focus, it is a no-op and {@link
-     * AutoFocusCallback#onAutoFocus(boolean, Camera)} callback will be called
-     * immediately.
+     * camera is focused. Only valid after startPreview() has been called.
+     * Applications should call {@link
+     * android.hardware.Camera.Parameters#getFocusMode()} to determine if this
+     * method should be called. If the camera does not support auto-focus, it is
+     * a no-op and {@link AutoFocusCallback#onAutoFocus(boolean, Camera)}
+     * callback will be called immediately.
      * <p>If your application should not be installed
      * on devices without auto-focus, you must declare that your application
      * uses auto-focus with the
@@ -598,6 +600,7 @@
         private static final String KEY_ANTIBANDING = "antibanding";
         private static final String KEY_SCENE_MODE = "scene-mode";
         private static final String KEY_FLASH_MODE = "flash-mode";
+        private static final String KEY_FOCUS_MODE = "focus-mode";
         // Parameter key suffix for supported values.
         private static final String SUPPORTED_VALUES_SUFFIX = "-values";
 
@@ -646,6 +649,10 @@
          * Flash will be fired in red-eye reduction mode.
          */
         public static final String FLASH_MODE_RED_EYE = "red-eye";
+        /**
+         * Constant emission of light. This can be used for video recording.
+         */
+        public static final String FLASH_MODE_VIDEO_LIGHT = "video-light";
 
         // Values for scene mode settings.
         public static final String SCENE_MODE_AUTO = "auto";
@@ -664,6 +671,25 @@
         public static final String SCENE_MODE_PARTY = "party";
         public static final String SCENE_MODE_CANDLELIGHT = "candlelight";
 
+        // Values for focus mode settings.
+        /**
+         * Auto-focus mode.
+         */
+        public static final String FOCUS_MODE_AUTO = "auto";
+        /**
+         * Focus is set at infinity. Applications should not call
+         * {@link #autoFocus(AutoFocusCallback)} in this mode.
+         */
+        public static final String FOCUS_MODE_INFINITY = "infinity";
+        public static final String FOCUS_MODE_MACRO = "macro";
+        /**
+         * Focus is fixed. The camera is always in this mode if the focus is not
+         * adjustable. If the camera has auto-focus, this mode can fix the
+         * focus, which is usually at hyperfocal distance. Applications should
+         * not call {@link #autoFocus(AutoFocusCallback)} in this mode.
+         */
+        public static final String FOCUS_MODE_FIXED = "fixed";
+
         // Formats for setPreviewFormat and setPictureFormat.
         private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
         private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
@@ -1295,6 +1321,39 @@
             return split(str);
         }
 
+        /**
+         * Gets the current focus mode setting.
+         *
+         * @return one of FOCUS_MODE_XXX string constant. If the camera does not
+         *         support auto-focus, this should return {@link
+         *         #FOCUS_MODE_FIXED}. If the focus mode is not FOCUS_MODE_FIXED
+         *         or {@link #FOCUS_MODE_INFINITY}, applications should call
+         *         {@link #autoFocus(AutoFocusCallback)} to start the focus.
+         */
+        public String getFocusMode() {
+            return get(KEY_FOCUS_MODE);
+        }
+
+        /**
+         * Sets the focus mode.
+         *
+         * @param value FOCUS_MODE_XXX string constants.
+         */
+        public void setFocusMode(String value) {
+            set(KEY_FOCUS_MODE, value);
+        }
+
+        /**
+         * Gets the supported focus modes.
+         *
+         * @return a List of FOCUS_MODE_XXX string constants. null if focus mode
+         *         setting is not supported.
+         */
+        public List<String> getSupportedFocusModes() {
+            String str = get(KEY_FOCUS_MODE + SUPPORTED_VALUES_SUFFIX);
+            return split(str);
+        }
+
         // Splits a comma delimited string to an ArrayList of String.
         // Return null if the passing string is null or the size is 0.
         private ArrayList<String> split(String str) {
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 90c6328..3df228d 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -410,7 +410,8 @@
             private AggregationSuggestions() {}
 
             /**
-             * The directory twig for this sub-table
+             * The directory twig for this sub-table. The URI can be followed by an optional
+             * type-to-filter, similar to {@link Contacts#CONTENT_FILTER_URI}.
              */
             public static final String CONTENT_DIRECTORY = "suggestions";
         }
@@ -900,32 +901,9 @@
         public static final String PACKAGE_COMMON = "common";
 
         /**
-         * Columns common across the specific types.
-         */
-        private interface BaseCommonColumns {
-            /**
-             * The package name to use when creating {@link Resources} objects for
-             * this data row. This value is only designed for use when building user
-             * interfaces, and should not be used to infer the owner.
-             */
-            public static final String RES_PACKAGE = "res_package";
-
-            /**
-             * The MIME type of the item represented by this row.
-             */
-            public static final String MIMETYPE = "mimetype";
-
-            /**
-             * The {@link RawContacts#_ID} that this data belongs to.
-             */
-            public static final String RAW_CONTACT_ID = "raw_contact_id";
-        }
-
-        /**
          * The base types that all "Typed" data kinds support.
          */
         public interface BaseTypes {
-
             /**
              * A custom type. The custom label should be supplied by user.
              */
@@ -935,7 +913,7 @@
         /**
          * Columns common across the specific types.
          */
-        private interface CommonColumns extends BaseTypes{
+        private interface CommonColumns extends BaseTypes {
             /**
              * The data for the contact method.
              * <P>Type: TEXT</P>
@@ -1101,30 +1079,67 @@
              */
             public static final String NUMBER = DATA;
 
+            /**
+             * @deprecated use {@link #getTypeLabel(Resources, int, CharSequence)} instead.
+             */
+            @Deprecated
             public static final CharSequence getDisplayLabel(Context context, int type,
                     CharSequence label, CharSequence[] labelArray) {
-                CharSequence display = "";
-
-                if (type != Phone.TYPE_CUSTOM) {
-                    CharSequence[] labels = labelArray != null? labelArray
-                            : context.getResources().getTextArray(
-                                    com.android.internal.R.array.phoneTypes);
-                    try {
-                        display = labels[type - 1];
-                    } catch (ArrayIndexOutOfBoundsException e) {
-                        display = labels[Phone.TYPE_CUSTOM];
-                    }
-                } else {
-                    if (!TextUtils.isEmpty(label)) {
-                        display = label;
-                    }
-                }
-                return display;
+                return getTypeLabel(context.getResources(), type, label);
             }
 
+            /**
+             * @deprecated use {@link #getTypeLabel(Resources, int, CharSequence)} instead.
+             */
+            @Deprecated
             public static final CharSequence getDisplayLabel(Context context, int type,
                     CharSequence label) {
-                return getDisplayLabel(context, type, label, null);
+                return getTypeLabel(context.getResources(), type, label);
+            }
+
+            /**
+             * Return the string resource that best describes the given
+             * {@link CommonColumns#TYPE}. Will always return a valid resource.
+             */
+            public static final int getTypeLabelResource(int type) {
+                switch (type) {
+                    case TYPE_HOME: return com.android.internal.R.string.phoneTypeHome;
+                    case TYPE_MOBILE: return com.android.internal.R.string.phoneTypeMobile;
+                    case TYPE_WORK: return com.android.internal.R.string.phoneTypeWork;
+                    case TYPE_FAX_WORK: return com.android.internal.R.string.phoneTypeFaxWork;
+                    case TYPE_FAX_HOME: return com.android.internal.R.string.phoneTypeFaxHome;
+                    case TYPE_PAGER: return com.android.internal.R.string.phoneTypePager;
+                    case TYPE_OTHER: return com.android.internal.R.string.phoneTypeOther;
+                    case TYPE_CALLBACK: return com.android.internal.R.string.phoneTypeCallback;
+                    case TYPE_CAR: return com.android.internal.R.string.phoneTypeCar;
+                    case TYPE_COMPANY_MAIN: return com.android.internal.R.string.phoneTypeCompanyMain;
+                    case TYPE_ISDN: return com.android.internal.R.string.phoneTypeIsdn;
+                    case TYPE_MAIN: return com.android.internal.R.string.phoneTypeMain;
+                    case TYPE_OTHER_FAX: return com.android.internal.R.string.phoneTypeOtherFax;
+                    case TYPE_RADIO: return com.android.internal.R.string.phoneTypeRadio;
+                    case TYPE_TELEX: return com.android.internal.R.string.phoneTypeTelex;
+                    case TYPE_TTY_TDD: return com.android.internal.R.string.phoneTypeTtyTdd;
+                    case TYPE_WORK_MOBILE: return com.android.internal.R.string.phoneTypeWorkMobile;
+                    case TYPE_WORK_PAGER: return com.android.internal.R.string.phoneTypeWorkPager;
+                    case TYPE_ASSISTANT: return com.android.internal.R.string.phoneTypeAssistant;
+                    case TYPE_MMS: return com.android.internal.R.string.phoneTypeMms;
+                    default: return com.android.internal.R.string.phoneTypeCustom;
+                }
+            }
+
+            /**
+             * Return a {@link CharSequence} that best describes the given type,
+             * possibly substituting the given {@link CommonColumns#LABEL} value
+             * for {@link BaseTypes#TYPE_CUSTOM}.
+             */
+            public static final CharSequence getTypeLabel(Resources res, int type,
+                    CharSequence label) {
+                if ((type == TYPE_CUSTOM || type == TYPE_ASSISTANT) && !TextUtils.isEmpty(label)) {
+                    return label;
+                } else {
+                    final int labelRes = getTypeLabelResource(type);
+                    return res.getText(labelRes);
+                }
             }
         }
 
@@ -1177,6 +1192,35 @@
              * <P>Type: TEXT</P>
              */
             public static final String DISPLAY_NAME = DATA4;
+
+            /**
+             * Return the string resource that best describes the given
+             * {@link CommonColumns#TYPE}. Will always return a valid resource.
+             */
+            public static final int getTypeLabelResource(int type) {
+                switch (type) {
+                    case TYPE_HOME: return com.android.internal.R.string.emailTypeHome;
+                    case TYPE_WORK: return com.android.internal.R.string.emailTypeWork;
+                    case TYPE_OTHER: return com.android.internal.R.string.emailTypeOther;
+                    case TYPE_MOBILE: return com.android.internal.R.string.emailTypeMobile;
+                    default: return com.android.internal.R.string.emailTypeCustom;
+                }
+            }
+
+            /**
+             * Return a {@link CharSequence} that best describes the given type,
+             * possibly substituting the given {@link CommonColumns#LABEL} value
+             * for {@link BaseTypes#TYPE_CUSTOM}.
+             */
+            public static final CharSequence getTypeLabel(Resources res, int type,
+                    CharSequence label) {
+                if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) {
+                    return label;
+                } else {
+                    final int labelRes = getTypeLabelResource(type);
+                    return res.getText(labelRes);
+                }
+            }
         }
 
         /**
@@ -1271,6 +1315,34 @@
              * Type: TEXT
              */
             public static final String COUNTRY = DATA10;
+
+            /**
+             * Return the string resource that best describes the given
+             * {@link CommonColumns#TYPE}. Will always return a valid resource.
+             */
+            public static final int getTypeLabelResource(int type) {
+                switch (type) {
+                    case TYPE_HOME: return com.android.internal.R.string.postalTypeHome;
+                    case TYPE_WORK: return com.android.internal.R.string.postalTypeWork;
+                    case TYPE_OTHER: return com.android.internal.R.string.postalTypeOther;
+                    default: return com.android.internal.R.string.postalTypeCustom;
+                }
+            }
+
+            /**
+             * Return a {@link CharSequence} that best describes the given type,
+             * possibly substituting the given {@link CommonColumns#LABEL} value
+             * for {@link BaseTypes#TYPE_CUSTOM}.
+             */
+            public static final CharSequence getTypeLabel(Resources res, int type,
+                    CharSequence label) {
+                if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) {
+                    return label;
+                } else {
+                    final int labelRes = getTypeLabelResource(type);
+                    return res.getText(labelRes);
+                }
+            }
         }
 
         /**
@@ -1309,6 +1381,68 @@
             public static final int PROTOCOL_ICQ = 6;
             public static final int PROTOCOL_JABBER = 7;
             public static final int PROTOCOL_NETMEETING = 8;
+
+            /**
+             * Return the string resource that best describes the given
+             * {@link CommonColumns#TYPE}. Will always return a valid resource.
+             */
+            public static final int getTypeLabelResource(int type) {
+                switch (type) {
+                    case TYPE_HOME: return com.android.internal.R.string.imTypeHome;
+                    case TYPE_WORK: return com.android.internal.R.string.imTypeWork;
+                    case TYPE_OTHER: return com.android.internal.R.string.imTypeOther;
+                    default: return com.android.internal.R.string.imTypeCustom;
+                }
+            }
+
+            /**
+             * Return a {@link CharSequence} that best describes the given type,
+             * possibly substituting the given {@link CommonColumns#LABEL} value
+             * for {@link BaseTypes#TYPE_CUSTOM}.
+             */
+            public static final CharSequence getTypeLabel(Resources res, int type,
+                    CharSequence label) {
+                if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) {
+                    return label;
+                } else {
+                    final int labelRes = getTypeLabelResource(type);
+                    return res.getText(labelRes);
+                }
+            }
+
+            /**
+             * Return the string resource that best describes the given
+             * {@link Im#PROTOCOL}. Will always return a valid resource.
+             */
+            public static final int getProtocolLabelResource(int type) {
+                switch (type) {
+                    case PROTOCOL_AIM: return com.android.internal.R.string.imProtocolAim;
+                    case PROTOCOL_MSN: return com.android.internal.R.string.imProtocolMsn;
+                    case PROTOCOL_YAHOO: return com.android.internal.R.string.imProtocolYahoo;
+                    case PROTOCOL_SKYPE: return com.android.internal.R.string.imProtocolSkype;
+                    case PROTOCOL_QQ: return com.android.internal.R.string.imProtocolQq;
+                    case PROTOCOL_GOOGLE_TALK: return com.android.internal.R.string.imProtocolGoogleTalk;
+                    case PROTOCOL_ICQ: return com.android.internal.R.string.imProtocolIcq;
+                    case PROTOCOL_JABBER: return com.android.internal.R.string.imProtocolJabber;
+                    case PROTOCOL_NETMEETING: return com.android.internal.R.string.imProtocolNetMeeting;
+                    default: return com.android.internal.R.string.imProtocolCustom;
+                }
+            }
+
+            /**
+             * Return a {@link CharSequence} that best describes the given
+             * protocol, possibly substituting the given
+             * {@link #CUSTOM_PROTOCOL} value for {@link #PROTOCOL_CUSTOM}.
+             */
+            public static final CharSequence getProtocolLabel(Resources res, int type,
+                    CharSequence label) {
+                if (type == PROTOCOL_CUSTOM && !TextUtils.isEmpty(label)) {
+                    return label;
+                } else {
+                    final int labelRes = getProtocolLabelResource(type);
+                    return res.getText(labelRes);
+                }
+            }
         }
 
         /**
@@ -1358,6 +1492,33 @@
              * <P>Type: TEXT</P>
              */
             public static final String PHONETIC_NAME = DATA8;
+
+            /**
+             * Return the string resource that best describes the given
+             * {@link CommonColumns#TYPE}. Will always return a valid resource.
+             */
+            public static final int getTypeLabelResource(int type) {
+                switch (type) {
+                    case TYPE_WORK: return com.android.internal.R.string.orgTypeWork;
+                    case TYPE_OTHER: return com.android.internal.R.string.orgTypeOther;
+                    default: return com.android.internal.R.string.orgTypeCustom;
+                }
+            }
+
+            /**
+             * Return a {@link CharSequence} that best describes the given type,
+             * possibly substituting the given {@link CommonColumns#LABEL} value
+             * for {@link BaseTypes#TYPE_CUSTOM}.
+             */
+            public static final CharSequence getTypeLabel(Resources res, int type,
+                    CharSequence label) {
+                if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) {
+                    return label;
+                } else {
+                    final int labelRes = getTypeLabelResource(type);
+                    return res.getText(labelRes);
+                }
+            }
         }
 
         /**
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 34921f4..f9ab31c 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -369,6 +369,10 @@
                 uuid = str.toString();
             }
             mBluetoothService.setRemoteDeviceProperty(address, name, uuid);
+
+            // UUIDs have changed, query remote service channel and update cache.
+            mBluetoothService.updateDeviceServiceChannelCache(address);
+
             mBluetoothService.sendUuidIntent(address);
         } else if (name.equals("Paired")) {
             if (propValues[1].equals("true")) {
@@ -537,8 +541,7 @@
         String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
         // We don't parse the xml here, instead just query Bluez for the properties.
         if (result) {
-            String[] properties = mBluetoothService.getRemoteDeviceProperties(address);
-            mBluetoothService.addRemoteDeviceProperties(address, properties);
+            mBluetoothService.updateRemoteDevicePropertiesCache(address);
         }
         mBluetoothService.sendUuidIntent(address);
     }
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 26007c5..e5b20bd 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -28,6 +28,7 @@
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetooth;
 import android.bluetooth.ParcelUuid;
 import android.content.BroadcastReceiver;
@@ -85,6 +86,7 @@
     private final Map<String, String> mAdapterProperties;
     private final HashMap <String, Map<String, String>> mDeviceProperties;
 
+    private final HashMap <String, Map<ParcelUuid, Integer>> mDeviceServiceChannelCache;
     private final ArrayList <String> mUuidIntentTracker;
 
     static {
@@ -111,6 +113,8 @@
         mIsDiscovering = false;
         mAdapterProperties = new HashMap<String, String>();
         mDeviceProperties = new HashMap<String, Map<String,String>>();
+
+        mDeviceServiceChannelCache = new HashMap<String, Map<ParcelUuid, Integer>>();
         mUuidIntentTracker = new ArrayList<String>();
         registerForAirplaneMode();
     }
@@ -880,16 +884,22 @@
             // Query for remote device properties, again.
             // We will need to reload the cache when we switch Bluetooth on / off
             // or if we crash.
-            String[] propValues = getRemoteDeviceProperties(address);
-            if (propValues != null) {
-                addRemoteDeviceProperties(address, propValues);
+            if (updateRemoteDevicePropertiesCache(address))
                 return getRemoteDeviceProperty(address, property);
-            }
         }
         Log.e(TAG, "getRemoteDeviceProperty: " + property + "not present:" + address);
         return null;
     }
 
+    /* package */ synchronized boolean updateRemoteDevicePropertiesCache(String address) {
+        String[] propValues = getRemoteDeviceProperties(address);
+        if (propValues != null) {
+            addRemoteDeviceProperties(address, propValues);
+            return true;
+        }
+        return false;
+    }
+
     /* package */ synchronized void addRemoteDeviceProperties(String address, String[] properties) {
         /*
          * We get a DeviceFound signal every time RSSI changes or name changes.
@@ -924,6 +934,10 @@
             propertyValues.put(name, newValue);
         }
         mDeviceProperties.put(address, propertyValues);
+
+        // We have added a new remote device or updated its properties.
+        // Also update the serviceChannel cache.
+        updateDeviceServiceChannelCache(address);
     }
 
     /* package */ void removeRemoteDeviceProperties(String address) {
@@ -1066,14 +1080,23 @@
      * @param uuid ParcelUuid of the service attribute
      *
      * @return rfcomm channel associated with the service attribute
+     *         -1 on error
      */
     public int getRemoteServiceChannel(String address, ParcelUuid uuid) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return BluetoothDevice.ERROR;
         }
-        return getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(),
-                0x0004);
+        // Check if we are recovering from a crash.
+        if (mDeviceProperties.isEmpty()) {
+            if (!updateRemoteDevicePropertiesCache(address))
+                return -1;
+        }
+
+        Map<ParcelUuid, Integer> value = mDeviceServiceChannelCache.get(address);
+        if (value != null && value.containsKey(uuid))
+            return value.get(uuid);
+        return -1;
     }
 
     public synchronized boolean setPin(String address, byte[] pin) {
@@ -1152,6 +1175,27 @@
         return cancelPairingUserInputNative(address, data.intValue());
     }
 
+    public void updateDeviceServiceChannelCache(String address) {
+        ParcelUuid[] deviceUuids = getRemoteUuids(address);
+        // We are storing the rfcomm channel numbers only for the uuids
+        // we are interested in.
+        int channel;
+        ParcelUuid[] interestedUuids = {BluetoothUuid.Handsfree,
+                                        BluetoothUuid.HSP,
+                                        BluetoothUuid.ObexObjectPush};
+
+        Map <ParcelUuid, Integer> value = new HashMap<ParcelUuid, Integer>();
+        for (ParcelUuid uuid: interestedUuids) {
+            if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) {
+                channel =
+                   getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(),
+                                                 0x0004);
+                value.put(uuid, channel);
+            }
+        }
+        mDeviceServiceChannelCache.put(address, value);
+    }
+
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -1194,6 +1238,7 @@
     /*package*/ synchronized void sendUuidIntent(String address) {
         ParcelUuid[] uuid = getUuidFromCache(address);
         Intent intent = new Intent(BluetoothDevice.ACTION_UUID);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
         intent.putExtra(BluetoothDevice.EXTRA_UUID, uuid);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
 
@@ -1366,4 +1411,5 @@
     private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value);
     private native boolean createDeviceNative(String address);
     private native boolean discoverServicesNative(String objectPath, String pattern);
+
 }
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index 367b26c..baaa3ce 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -32,6 +32,18 @@
      * @return formated string with the number
      */
     public static String formatFileSize(Context context, long number) {
+        return formatFileSize(context, number, false);
+    }
+    
+    /**
+     * Like {@link #formatFileSize}, but trying to generate shorter numbers
+     * (showing fewer digits of precisin).
+     */
+    public static String formatShortFileSize(Context context, long number) {
+        return formatFileSize(context, number, true);
+    }
+    
+    private static String formatFileSize(Context context, long number, boolean shorter) {
         if (context == null) {
             return "";
         }
@@ -58,13 +70,24 @@
             suffix = com.android.internal.R.string.petabyteShort;
             result = result / 1024;
         }
-        if (result < 100) {
-            String value = String.format("%.2f", result);
-            return context.getResources().
-                getString(com.android.internal.R.string.fileSizeSuffix,
-                          value, context.getString(suffix));
+        String value;
+        if (result < 1) {
+            value = String.format("%.2f", result);
+        } else if (result < 10) {
+            if (shorter) {
+                value = String.format("%.1f", result);
+            } else {
+                value = String.format("%.2f", result);
+            }
+        } else if (result < 100) {
+            if (shorter) {
+                value = String.format("%.0f", result);
+            } else {
+                value = String.format("%.2f", result);
+            }
+        } else {
+            value = String.format("%.0f", result);
         }
-        String value = String.format("%.0f", result);
         return context.getResources().
             getString(com.android.internal.R.string.fileSizeSuffix,
                       value, context.getString(suffix));
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 45ff27e..cc5aeb1 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -314,7 +314,9 @@
         public boolean showLw(boolean doAnimation);
     }
 
-    /** No transition happening. */
+    /** Not set up for a transition. */
+    public final int TRANSIT_UNSET = 0;
+    /** No animation for transition. */
     public final int TRANSIT_NONE = 0;
     /** Window has been added to the screen. */
     public final int TRANSIT_ENTER = 1;
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index dbddb2e..e233a02 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -605,8 +605,8 @@
     }
 
     // Called by JNI when an apple-touch-icon attribute was found.
-    private void didReceiveTouchIconUrl(String url) {
-        mCallbackProxy.onReceivedTouchIconUrl(url);
+    private void didReceiveTouchIconUrl(String url, boolean precomposed) {
+        mCallbackProxy.onReceivedTouchIconUrl(url, precomposed);
     }
 
     /**
@@ -707,6 +707,10 @@
         return value.string.toString();
     }
 
+    private float density() {
+        return mContext.getResources().getDisplayMetrics().density;
+    }
+
     //==========================================================================
     // native functions
     //==========================================================================
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index b051675..1ec769b 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -249,7 +249,7 @@
             case RECEIVED_TOUCH_ICON_URL:
                 if (mWebChromeClient != null) {
                     mWebChromeClient.onReceivedTouchIconUrl(mWebView,
-                            (String) msg.obj);
+                            (String) msg.obj, msg.arg1 == 1);
                 }
                 break;
 
@@ -1065,19 +1065,22 @@
         sendMessage(obtainMessage(RECEIVED_ICON, icon));
     }
 
-    /* package */ void onReceivedTouchIconUrl(String url) {
+    /* package */ void onReceivedTouchIconUrl(String url, boolean precomposed) {
         // We should have a current item but we do not want to crash so check
         // for null.
         WebHistoryItem i = mBackForwardList.getCurrentItem();
         if (i != null) {
-            i.setTouchIconUrl(url);
+            if (precomposed || i.getTouchIconUrl() != null) {
+                i.setTouchIconUrl(url);
+            }
         }
         // Do an unsynchronized quick check to avoid posting if no callback has
         // been set.
         if (mWebChromeClient == null) {
             return;
         }
-        sendMessage(obtainMessage(RECEIVED_TOUCH_ICON_URL, url));
+        sendMessage(obtainMessage(RECEIVED_TOUCH_ICON_URL,
+                precomposed ? 1 : 0, 0, url));
     }
 
     public void onReceivedTitle(String title) {
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 0e08514..1ae1d85 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -48,9 +48,11 @@
      * Notify the host application of the url for an apple-touch-icon.
      * @param view The WebView that initiated the callback.
      * @param url The icon url.
+     * @param precomposed True if the url is for a precomposed touch icon.
      * @hide pending council approval
      */
-    public void onReceivedTouchIconUrl(WebView view, String url) {}
+    public void onReceivedTouchIconUrl(WebView view, String url,
+            boolean precomposed) {}
 
     /**
      * A callback interface used by the host application to notify
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 39a2470..1a65ce8 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -448,8 +448,13 @@
             int initialScrollX = Touch.getInitialScrollX(this, buffer);
             int initialScrollY = Touch.getInitialScrollY(this, buffer);
             super.onTouchEvent(event);
-            if (Math.abs(mScrollX - initialScrollX) > slop
-                    || Math.abs(mScrollY - initialScrollY) > slop) {
+            int dx = Math.abs(mScrollX - initialScrollX);
+            int dy = Math.abs(mScrollY - initialScrollY);
+            // Use a smaller slop when checking to see if we've moved far enough
+            // to scroll the text, because experimentally, slop has shown to be
+            // to big for the case of a small textfield.
+            int smallerSlop = slop/2;
+            if (dx > smallerSlop || dy > smallerSlop) {
                 if (mWebView != null) {
                     mWebView.scrollFocusedTextInput(mScrollX, mScrollY);
                 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9101578..113eac5 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1782,12 +1782,22 @@
     }
 
     /**
+     * Given a distance in view space, convert it to content space. Note: this
+     * does not reflect translation, just scaling, so this should not be called
+     * with coordinates, but should be called for dimensions like width or
+     * height.
+     */
+    private int viewToContentDimension(int d) {
+        return Math.round(d * mInvActualScale);
+    }
+
+    /**
      * Given an x coordinate in view space, convert it to content space.  Also
      * may be used for absolute heights (such as for the WebTextView's
      * textSize, which is unaffected by the height of the title bar).
      */
     /*package*/ int viewToContentX(int x) {
-        return Math.round(x * mInvActualScale);
+        return viewToContentDimension(x);
     }
 
     /**
@@ -1796,7 +1806,7 @@
      * embedded into the WebView.
      */
     /*package*/ int viewToContentY(int y) {
-        return viewToContentX(y - getTitleHeight());
+        return viewToContentDimension(y - getTitleHeight());
     }
 
     /**
@@ -1811,7 +1821,7 @@
 
     /**
      * Given an x coordinate in content space, convert it to view
-     * space.  Also used for absolute heights.
+     * space.
      */
     /*package*/ int contentToViewX(int x) {
         return contentToViewDimension(x);
@@ -2505,16 +2515,26 @@
             // saved scroll position, it is ok to skip this.
             return false;
         }
-        int vx = contentToViewX(cx);
-        int vy = contentToViewY(cy);
+        int vx;
+        int vy;
+        if ((cx | cy) == 0) {
+            // If the page is being scrolled to (0,0), do not add in the title
+            // bar's height, and simply scroll to (0,0). (The only other work
+            // in contentToView_ is to multiply, so this would not change 0.)
+            vx = 0;
+            vy = 0;
+        } else {
+            vx = contentToViewX(cx);
+            vy = contentToViewY(cy);
+        }
 //        Log.d(LOGTAG, "content scrollTo [" + cx + " " + cy + "] view=[" +
 //                      vx + " " + vy + "]");
         // Some mobile sites attempt to scroll the title bar off the page by
-        // scrolling to (0,0) or (0,1).  If we are at the top left corner of the
+        // scrolling to (0,1).  If we are at the top left corner of the
         // page, assume this is an attempt to scroll off the title bar, and
         // animate the title bar off screen slowly enough that the user can see
         // it.
-        if (cx == 0 && cy <= 1 && mScrollX == 0 && mScrollY == 0) {
+        if (cx == 0 && cy == 1 && mScrollX == 0 && mScrollY == 0) {
             pinScrollTo(vx, vy, true, SLIDE_TITLE_DURATION);
             // Since we are animating, we have not yet reached the desired
             // scroll position.  Do not return true to request another attempt
@@ -4435,7 +4455,10 @@
             return;
         }
         mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, viewToContentX(x),
-                viewToContentY(y));
+                // Since this position is relative to the top of the text input
+                // field, we do not need to take the title bar's height into
+                // consideration.
+                viewToContentDimension(y));
     }
 
     /**
@@ -4845,7 +4868,7 @@
                                             / draw.mMinPrefWidth;
                                     mMinZoomScaleFixed = false;
                                 } else {
-                                    mMinZoomScale = mDefaultScale;
+                                    mMinZoomScale = restoreState.mDefaultScale;
                                     mMinZoomScaleFixed = true;
                                 }
                             } else {
@@ -4862,22 +4885,13 @@
                             mMaxZoomScale = restoreState.mMaxScale;
                         }
                         setNewZoomScale(mLastScale, false);
-                        if (getTitleHeight() != 0 && restoreState.mScrollX == 0
-                                && restoreState.mScrollY == 0) {
-                            // If there is a title bar, and the page is being
-                            // restored to (0,0), do not scroll the title bar
-                            // off the page.
-                            abortAnimation();
-                            scrollTo(0,0);
-                        } else {
-                            setContentScrollTo(restoreState.mScrollX,
-                                    restoreState.mScrollY);
-                        }
+                        setContentScrollTo(restoreState.mScrollX,
+                                restoreState.mScrollY);
                         if (useWideViewport
                                 && settings.getLoadWithOverviewMode()) {
                             if (restoreState.mViewScale == 0
                                     || (restoreState.mMobileSite
-                                            && mMinZoomScale < mDefaultScale)) {
+                                    && mMinZoomScale < restoreState.mDefaultScale)) {
                                 mInZoomOverview = true;
                             }
                         }
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index d4142bb..e734444 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -100,6 +100,15 @@
 
     private boolean mViewportUserScalable = true;
 
+    /*
+     * range is from 70 to 400.
+     * 0 is a special value means device-dpi. The default scale factor will be
+     * always 100.
+     * -1 means undefined. The default scale factor will be
+     * WebView.DEFAULT_SCALE_PERCENT.
+     */
+    private int mViewportDensityDpi = -1;
+
     private int mRestoredScale = 0;
     private int mRestoredScreenWidthScale = 0;
     private int mRestoredX = 0;
@@ -1539,6 +1548,7 @@
         float mMaxScale;
         float mViewScale;
         float mTextWrapScale;
+        float mDefaultScale;
         int mScrollX;
         int mScrollY;
         boolean mMobileSite;
@@ -1842,47 +1852,48 @@
         // set the viewport settings from WebKit
         setViewportSettingsFromNative();
 
-        // adjust the default scale to match the density
-        if (WebView.DEFAULT_SCALE_PERCENT != 100) {
-            float adjust = (float) WebView.DEFAULT_SCALE_PERCENT / 100.0f;
-            if (mViewportInitialScale > 0) {
-                mViewportInitialScale *= adjust;
+        // adjust the default scale to match the densityDpi
+        float adjust = 1.0f;
+        if (mViewportDensityDpi == -1) {
+            if (WebView.DEFAULT_SCALE_PERCENT != 100) {
+                adjust = WebView.DEFAULT_SCALE_PERCENT / 100.0f;
             }
-            if (mViewportMinimumScale > 0) {
-                mViewportMinimumScale *= adjust;
-            }
-            if (mViewportMaximumScale > 0) {
-                mViewportMaximumScale *= adjust;
-            }
+        } else if (mViewportDensityDpi > 0) {
+            adjust = (float) mContext.getResources().getDisplayMetrics().densityDpi
+                    / mViewportDensityDpi;
+        }
+        int defaultScale = (int) (adjust * 100);
+
+        if (mViewportInitialScale > 0) {
+            mViewportInitialScale *= adjust;
+        }
+        if (mViewportMinimumScale > 0) {
+            mViewportMinimumScale *= adjust;
+        }
+        if (mViewportMaximumScale > 0) {
+            mViewportMaximumScale *= adjust;
         }
 
         // infer the values if they are not defined.
         if (mViewportWidth == 0) {
             if (mViewportInitialScale == 0) {
-                mViewportInitialScale = WebView.DEFAULT_SCALE_PERCENT;
+                mViewportInitialScale = defaultScale;
             }
         }
         if (mViewportUserScalable == false) {
-            mViewportInitialScale = WebView.DEFAULT_SCALE_PERCENT;
-            mViewportMinimumScale = WebView.DEFAULT_SCALE_PERCENT;
-            mViewportMaximumScale = WebView.DEFAULT_SCALE_PERCENT;
+            mViewportInitialScale = defaultScale;
+            mViewportMinimumScale = defaultScale;
+            mViewportMaximumScale = defaultScale;
         }
-        if (mViewportMinimumScale > mViewportInitialScale) {
-            if (mViewportInitialScale == 0) {
-                mViewportInitialScale = mViewportMinimumScale;
-            } else {
-                mViewportMinimumScale = mViewportInitialScale;
-            }
+        if (mViewportMinimumScale > mViewportInitialScale
+                && mViewportInitialScale != 0) {
+            mViewportMinimumScale = mViewportInitialScale;
         }
-        if (mViewportMaximumScale > 0) {
-            if (mViewportMaximumScale < mViewportInitialScale) {
-                mViewportMaximumScale = mViewportInitialScale;
-            } else if (mViewportInitialScale == 0) {
-                mViewportInitialScale = mViewportMaximumScale;
-            }
+        if (mViewportMaximumScale > 0
+                && mViewportMaximumScale < mViewportInitialScale) {
+            mViewportMaximumScale = mViewportInitialScale;
         }
-        if (mViewportWidth < 0
-                && mViewportInitialScale == WebView.DEFAULT_SCALE_PERCENT) {
+        if (mViewportWidth < 0 && mViewportInitialScale == defaultScale) {
             mViewportWidth = 0;
         }
 
@@ -1899,7 +1910,7 @@
             // we call WebView method from WebCore thread. But not perfect
             // reference is better than no reference.
             webViewWidth = mWebView.getViewWidth();
-            viewportWidth = webViewWidth * 100 / WebView.DEFAULT_SCALE_PERCENT;
+            viewportWidth = (int) (webViewWidth / adjust);
             if (viewportWidth == 0) {
                 Log.w(LOGTAG, "Can't get the viewWidth after the first layout");
             }
@@ -1909,6 +1920,7 @@
         mRestoreState = new RestoreState();
         mRestoreState.mMinScale = mViewportMinimumScale / 100.0f;
         mRestoreState.mMaxScale = mViewportMaximumScale / 100.0f;
+        mRestoreState.mDefaultScale = adjust;
         mRestoreState.mScrollX = mRestoredX;
         mRestoreState.mScrollY = mRestoredY;
         mRestoreState.mMobileSite = (0 == mViewportWidth);
@@ -1930,8 +1942,7 @@
                 mRestoreState.mViewScale = mRestoreState.mTextWrapScale =
                         (float) webViewWidth / mViewportWidth;
             } else {
-                mRestoreState.mTextWrapScale =
-                        WebView.DEFAULT_SCALE_PERCENT / 100.0f;
+                mRestoreState.mTextWrapScale = adjust;
                 // 0 will trigger WebView to turn on zoom overview mode
                 mRestoreState.mViewScale = 0;
             }
diff --git a/core/java/com/android/internal/backup/BackupConstants.java b/core/java/com/android/internal/backup/BackupConstants.java
new file mode 100644
index 0000000..3ee11bd
--- /dev/null
+++ b/core/java/com/android/internal/backup/BackupConstants.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+package com.android.internal.backup;
+
+/**
+ * Constants used internally between the backup manager and its transports
+ */
+public class BackupConstants {
+    public static final int TRANSPORT_OK = 0;
+    public static final int TRANSPORT_ERROR = 1;
+    public static final int TRANSPORT_NOT_INITIALIZED = 2;
+}
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl
index 250bc91..a830ebd 100644
--- a/core/java/com/android/internal/backup/IBackupTransport.aidl
+++ b/core/java/com/android/internal/backup/IBackupTransport.aidl
@@ -22,24 +22,6 @@
 
 /** {@hide} */
 interface IBackupTransport {
-/* STOPSHIP - don't ship with this comment in place
-    Things the transport interface has to do:
-    1. set up the connection to the destination
-        - set up encryption
-        - for Google cloud, log in using the user's gaia credential or whatever
-        - for adb, just set up the all-in-one destination file
-    2. send each app's backup transaction
-        - parse the data file for key/value pointers etc
-        - send key/blobsize set to the Google cloud, get back quota ok/rejected response
-        - sd/adb doesn't preflight; no per-app quota
-        - app's entire change is essentially atomic
-        - cloud transaction encrypts then sends each key/value pair separately; we already
-          parsed the data when preflighting so we don't have to again here
-        - sd target streams raw data into encryption envelope then to sd?
-    3. shut down connection to destination
-        - cloud: tear down connection etc
-        - adb: close the file
-*/
     /**
      * Ask the transport where, on local device storage, to keep backup state blobs.
      * This is per-transport so that mock transports used for testing can coexist with
@@ -68,6 +50,17 @@
     long requestBackupTime();
 
     /**
+     * Initialize the server side storage for this device, erasing all stored data.
+     * The transport may send the request immediately, or may buffer it.  After
+     * this is called, {@link #finishBackup} must be called to ensure the request
+     * is sent and received successfully.
+     *
+     * @return One of {@link BackupConstants#TRANSPORT_OK} (OK so far) or
+     *   {@link BackupConstants#TRANSPORT_ERROR} (on network error or other failure).
+     */
+    int initializeDevice();
+
+    /**
      * Send one application's data to the backup destination.  The transport may send
      * the data immediately, or may buffer it.  After this is called, {@link #finishBackup}
      * must be called to ensure the data is sent and recorded successfully.
@@ -81,11 +74,12 @@
      *   will be erased prior to the storage of the data provided here.  The purpose of this
      *   is to provide a guarantee that no stale data exists in the restore set when the
      *   device begins providing backups.
-     * @return false if errors occurred (the backup should be aborted and rescheduled),
-     *   true if everything is OK so far (but {@link #finishBackup} must be called).
+     * @return one of {@link BackupConstants#TRANSPORT_OK} (OK so far),
+     *  {@link BackupConstants#TRANSPORT_ERROR} (on network error or other failure), or
+     *  {@link BackupConstants#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has
+     *  become lost due to inactive expiry or some other reason and needs re-initializing)
      */
-    boolean performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd,
-            boolean wipeAllFirst);
+    int performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd);
 
     /**
      * Erase the give application's data from the backup destination.  This clears
@@ -93,10 +87,9 @@
      * the app had never yet been backed up.  After this is called, {@link finishBackup}
      * must be called to ensure that the operation is recorded successfully.
      *
-     * @return false if errors occurred (the backup should be aborted and rescheduled),
-     *   true if everything is OK so far (but {@link #finishBackup} must be called).
+     * @return the same error codes as {@link #performBackup}.
      */
-    boolean clearBackupData(in PackageInfo packageInfo);
+    int clearBackupData(in PackageInfo packageInfo);
 
     /**
      * Finish sending application data to the backup destination.  This must be
@@ -104,10 +97,9 @@
      * all data is sent.  Only when this method returns true can a backup be assumed
      * to have succeeded.
      *
-     * @return false if errors occurred (the backup should be aborted and rescheduled),
-     *   true if everything is OK.
+     * @return the same error codes as {@link #performBackup}.
      */
-    boolean finishBackup();
+    int finishBackup();
 
     /**
      * Get the set of backups currently available over this transport.
@@ -125,10 +117,11 @@
      * @param token A backup token as returned by {@link #getAvailableRestoreSets}.
      * @param packages List of applications to restore (if data is available).
      *   Application data will be restored in the order given.
-     * @return false if errors occurred (the restore should be aborted and rescheduled),
-     *   true if everything is OK so far (go ahead and call {@link #nextRestorePackage}).
+     * @return One of {@link BackupConstants#TRANSPORT_OK} (OK so far, call
+     *   {@link #nextRestorePackage}) or {@link BackupConstants#TRANSPORT_ERROR}
+     *   (an error occurred, the restore should be aborted and rescheduled).
      */
-    boolean startRestore(long token, in PackageInfo[] packages);
+    int startRestore(long token, in PackageInfo[] packages);
 
     /**
      * Get the package name of the next application with data in the backup store.
@@ -141,10 +134,9 @@
     /**
      * Get the data for the application returned by {@link #nextRestorePackage}.
      * @param data An open, writable file into which the backup data should be stored.
-     * @return false if errors occurred (the restore should be aborted and rescheduled),
-     *   true if everything is OK so far (go ahead and call {@link #nextRestorePackage}).
+     * @return the same error codes as {@link #nextRestorePackage}.
      */
-    boolean getRestoreData(in ParcelFileDescriptor outFd);
+    int getRestoreData(in ParcelFileDescriptor outFd);
 
     /**
      * End a restore session (aborting any in-process data transfer as necessary),
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 981ea82..4fc3edc 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -47,25 +47,26 @@
     }
 
 
-    public String transportDirName() throws RemoteException {
+    public String transportDirName() {
         return TRANSPORT_DIR_NAME;
     }
 
-    public long requestBackupTime() throws RemoteException {
+    public long requestBackupTime() {
         // any time is a good time for local backup
         return 0;
     }
 
-    public boolean performBackup(PackageInfo packageInfo, ParcelFileDescriptor data,
-            boolean wipeAllFirst) throws RemoteException {
+    public int initializeDevice() {
+        if (DEBUG) Log.v(TAG, "wiping all data");
+        deleteContents(mDataDir);
+        return BackupConstants.TRANSPORT_OK;
+    }
+
+    public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) {
         if (DEBUG) Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName);
 
         File packageDir = new File(mDataDir, packageInfo.packageName);
         packageDir.mkdirs();
-        if (wipeAllFirst) {
-            if (DEBUG) Log.v(TAG, "wiping all data first");
-            deleteContents(mDataDir);
-        }
 
         // Each 'record' in the restore set is kept in its own file, named by
         // the record key.  Wind through the data file, extracting individual
@@ -99,7 +100,7 @@
                         entity.write(buf, 0, dataSize);
                     } catch (IOException e) {
                         Log.e(TAG, "Unable to update key file " + entityFile.getAbsolutePath());
-                        return false;
+                        return BackupConstants.TRANSPORT_ERROR;
                     } finally {
                         entity.close();
                     }
@@ -107,11 +108,11 @@
                     entityFile.delete();
                 }
             }
-            return true;
+            return BackupConstants.TRANSPORT_OK;
         } catch (IOException e) {
             // oops, something went wrong.  abort the operation and return error.
             Log.v(TAG, "Exception reading backup input:", e);
-            return false;
+            return BackupConstants.TRANSPORT_ERROR;
         }
     }
 
@@ -130,7 +131,7 @@
         }
     }
 
-    public boolean clearBackupData(PackageInfo packageInfo) {
+    public int clearBackupData(PackageInfo packageInfo) {
         if (DEBUG) Log.v(TAG, "clearBackupData() pkg=" + packageInfo.packageName);
 
         File packageDir = new File(mDataDir, packageInfo.packageName);
@@ -138,12 +139,12 @@
             f.delete();
         }
         packageDir.delete();
-        return true;
+        return BackupConstants.TRANSPORT_OK;
     }
 
-    public boolean finishBackup() throws RemoteException {
+    public int finishBackup() {
         if (DEBUG) Log.v(TAG, "finishBackup()");
-        return true;
+        return BackupConstants.TRANSPORT_OK;
     }
 
     // Restore handling
@@ -154,11 +155,11 @@
         return array;
     }
 
-    public boolean startRestore(long token, PackageInfo[] packages) {
+    public int startRestore(long token, PackageInfo[] packages) {
         if (DEBUG) Log.v(TAG, "start restore " + token);
         mRestorePackages = packages;
         mRestorePackage = -1;
-        return true;
+        return BackupConstants.TRANSPORT_OK;
     }
 
     public String nextRestorePackage() {
@@ -175,7 +176,7 @@
         return "";
     }
 
-    public boolean getRestoreData(ParcelFileDescriptor outFd) {
+    public int getRestoreData(ParcelFileDescriptor outFd) {
         if (mRestorePackages == null) throw new IllegalStateException("startRestore not called");
         if (mRestorePackage < 0) throw new IllegalStateException("nextRestorePackage not called");
         File packageDir = new File(mDataDir, mRestorePackages[mRestorePackage].packageName);
@@ -183,9 +184,9 @@
         // The restore set is the concatenation of the individual record blobs,
         // each of which is a file in the package's directory
         File[] blobs = packageDir.listFiles();
-        if (blobs == null) {
+        if (blobs == null) {  // nextRestorePackage() ensures the dir exists, so this is an error
             Log.e(TAG, "Error listing directory: " + packageDir);
-            return false;  // nextRestorePackage() ensures the dir exists, so this is an error
+            return BackupConstants.TRANSPORT_ERROR;
         }
 
         // We expect at least some data if the directory exists in the first place
@@ -206,10 +207,10 @@
                     in.close();
                 }
             }
-            return true;
+            return BackupConstants.TRANSPORT_OK;
         } catch (IOException e) {
             Log.e(TAG, "Unable to read backup records", e);
-            return false;
+            return BackupConstants.TRANSPORT_ERROR;
         }
     }
 
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 4987775..35d637d 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -63,6 +63,7 @@
     private static final String TAG = "ContactHeaderWidget";
 
     private TextView mDisplayNameView;
+    private View mAggregateBadge;
     private TextView mPhoneticNameView;
     private CheckBox mStarredView;
     private FasttrackBadgeWidget mPhotoView;
@@ -159,6 +160,8 @@
 
         mDisplayNameView = (TextView) findViewById(R.id.name);
         mDisplayNameView.setOnLongClickListener(this);
+        mAggregateBadge = findViewById(R.id.aggregate_badge);
+        mAggregateBadge.setVisibility(View.GONE);
 
         mPhoneticNameView = (TextView) findViewById(R.id.phonetic_name);
 
@@ -284,6 +287,13 @@
     }
 
     /**
+     * Turn on/off showing of the aggregate bage element.
+     */
+    public void showAggregateBadge(boolean showBagde) {
+        mAggregateBadge.setVisibility(showBagde ? View.VISIBLE : View.GONE);
+    }
+
+    /**
      * Turn on/off showing of the star element.
      */
     public void showStar(boolean showStar) {
@@ -310,6 +320,7 @@
      */
     public void setContactUri(Uri uri) {
         mContactUri = uri;
+        mPhotoView.assignContactUri(uri);
     }
 
     /**
diff --git a/core/res/res/anim/activity_close_enter.xml b/core/res/res/anim/activity_close_enter.xml
index 9d1ef53..f1258e8 100644
--- a/core/res/res/anim/activity_close_enter.xml
+++ b/core/res/res/anim/activity_close_enter.xml
@@ -21,5 +21,5 @@
         android:interpolator="@anim/decelerate_interpolator"
         android:zAdjustment="top">
 	<translate android:fromXDelta="-100%" android:toXDelta="0"
-        android:duration="@android:integer/config_mediumAnimTime"/>
+        android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/activity_close_exit.xml b/core/res/res/anim/activity_close_exit.xml
index 47cb6d6..bf3d8cd3 100644
--- a/core/res/res/anim/activity_close_exit.xml
+++ b/core/res/res/anim/activity_close_exit.xml
@@ -20,5 +20,5 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator">
 	<translate android:fromXDelta="0%" android:toXDelta="33%"
-        android:duration="@android:integer/config_mediumAnimTime"/>
+        android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/activity_open_enter.xml b/core/res/res/anim/activity_open_enter.xml
index e4c7e9b..a9ea381 100644
--- a/core/res/res/anim/activity_open_enter.xml
+++ b/core/res/res/anim/activity_open_enter.xml
@@ -20,5 +20,5 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator">
 	<translate android:fromXDelta="33%" android:toXDelta="0"
-        android:duration="@android:integer/config_mediumAnimTime"/>
+        android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/activity_open_exit.xml b/core/res/res/anim/activity_open_exit.xml
index 9d47b7f..b04b79e 100644
--- a/core/res/res/anim/activity_open_exit.xml
+++ b/core/res/res/anim/activity_open_exit.xml
@@ -21,5 +21,5 @@
         android:interpolator="@anim/decelerate_interpolator"
         android:zAdjustment="top">
 	<translate android:fromXDelta="0%" android:toXDelta="-100%"
-        android:duration="@android:integer/config_mediumAnimTime"/>
+        android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/dialog_enter.xml b/core/res/res/anim/dialog_enter.xml
index cc409e8..d4983c6 100644
--- a/core/res/res/anim/dialog_enter.xml
+++ b/core/res/res/anim/dialog_enter.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/fade_in.xml
-**
+/*
 ** Copyright 2007, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
diff --git a/core/res/res/anim/dialog_exit.xml b/core/res/res/anim/dialog_exit.xml
index 8bf8082..2aa629a 100644
--- a/core/res/res/anim/dialog_exit.xml
+++ b/core/res/res/anim/dialog_exit.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/fade_out.xml
-**
+/*
 ** Copyright 2007, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -17,6 +16,7 @@
 ** limitations under the License.
 */
 -->
+
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/accelerate_interpolator">
     <scale android:fromXScale="1.0" android:toXScale="0.9"
diff --git a/core/res/res/anim/recent_enter.xml b/core/res/res/anim/recent_enter.xml
index 54ae73b..8faa2c1 100644
--- a/core/res/res/anim/recent_enter.xml
+++ b/core/res/res/anim/recent_enter.xml
@@ -19,10 +19,10 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator">
-    <scale android:fromXScale="2.0" android:toXScale="1.0"
-           android:fromYScale="2.0" android:toYScale="1.0"
+    <scale android:fromXScale="0.9" android:toXScale="1.0"
+           android:fromYScale="0.9" android:toYScale="1.0"
            android:pivotX="50%" android:pivotY="50%"
-           android:duration="@android:integer/config_mediumAnimTime" />
+           android:duration="@android:integer/config_shortAnimTime" />
     <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
-            android:duration="@android:integer/config_mediumAnimTime"/>
+            android:duration="@android:integer/config_shortAnimTime" />
 </set>
diff --git a/core/res/res/anim/recent_exit.xml b/core/res/res/anim/recent_exit.xml
index 32d64a4..9399329 100644
--- a/core/res/res/anim/recent_exit.xml
+++ b/core/res/res/anim/recent_exit.xml
@@ -18,12 +18,11 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:interpolator="@anim/decelerate_interpolator"
-        android:zAdjustment="top">
-    <scale android:fromXScale="1.0" android:toXScale="2.0"
-           android:fromYScale="1.0" android:toYScale="2.0"
+        android:interpolator="@anim/accelerate_interpolator">
+    <scale android:fromXScale="1.0" android:toXScale="0.9"
+           android:fromYScale="1.0" android:toYScale="0.9"
            android:pivotX="50%" android:pivotY="50%"
-           android:duration="@android:integer/config_mediumAnimTime" />
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:duration="@android:integer/config_mediumAnimTime"/>
+           android:duration="@android:integer/config_shortAnimTime" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+            android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
index 98975fb..db331b1 100644
--- a/core/res/res/anim/task_open_exit.xml
+++ b/core/res/res/anim/task_open_exit.xml
@@ -18,8 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:interpolator="@anim/decelerate_interpolator"
-        android:zAdjustment="top">
+        android:interpolator="@anim/decelerate_interpolator">
     <scale android:fromXScale="1.0" android:toXScale="2.0"
            android:fromYScale="1.0" android:toYScale="2.0"
            android:pivotX="50%p" android:pivotY="50%p"
diff --git a/core/res/res/anim/translucent_enter.xml b/core/res/res/anim/translucent_enter.xml
index fb4c1c3..04852a8 100644
--- a/core/res/res/anim/translucent_enter.xml
+++ b/core/res/res/anim/translucent_enter.xml
@@ -20,7 +20,7 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator">
 	<translate android:fromXDelta="75%" android:toXDelta="0"
-        android:duration="@android:integer/config_mediumAnimTime"/>
+        android:duration="@android:integer/config_shortAnimTime"/>
     <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
-            android:duration="@android:integer/config_mediumAnimTime"/>
+            android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/translucent_exit.xml b/core/res/res/anim/translucent_exit.xml
index 1d424e1..adaf3d1 100644
--- a/core/res/res/anim/translucent_exit.xml
+++ b/core/res/res/anim/translucent_exit.xml
@@ -20,7 +20,7 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/accelerate_interpolator">
 	<translate android:fromXDelta="0%" android:toXDelta="75%"
-        android:duration="@android:integer/config_mediumAnimTime"/>
+        android:duration="@android:integer/config_shortAnimTime"/>
     <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:duration="@android:integer/config_mediumAnimTime"/>
+            android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/wallpaper_close_enter.xml b/core/res/res/anim/wallpaper_close_enter.xml
index e4c7e9b..0d13009 100644
--- a/core/res/res/anim/wallpaper_close_enter.xml
+++ b/core/res/res/anim/wallpaper_close_enter.xml
@@ -17,8 +17,22 @@
 */
 -->
 
+<!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator">
+    <scale android:fromXScale="2.0" android:toXScale="1.0"
+           android:fromYScale="2.0" android:toYScale="1.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+</set>
+
+<!-- This version is a variation on the inter-activity slide that
+    also scales the wallpaper. -->
+<!--
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator">
 	<translate android:fromXDelta="33%" android:toXDelta="0"
         android:duration="@android:integer/config_mediumAnimTime"/>
 </set>
+-->
diff --git a/core/res/res/anim/wallpaper_close_exit.xml b/core/res/res/anim/wallpaper_close_exit.xml
index 16edec1..5d91e30 100644
--- a/core/res/res/anim/wallpaper_close_exit.xml
+++ b/core/res/res/anim/wallpaper_close_exit.xml
@@ -17,6 +17,22 @@
 */
 -->
 
+<!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper.  The wallpaper here just stays fixed behind. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale="1.0" android:toXScale=".5"
+           android:fromYScale="1.0" android:toYScale=".5"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
+
+<!-- This version is a variation on the inter-activity slide that
+    also scales the wallpaper. -->
+<!--
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator"
         android:zAdjustment="top">
@@ -27,3 +43,4 @@
 	<translate android:fromXDelta="0%" android:toXDelta="-100%"
         android:duration="@android:integer/config_mediumAnimTime"/>
 </set>
+-->
diff --git a/core/res/res/anim/wallpaper_open_enter.xml b/core/res/res/anim/wallpaper_open_enter.xml
index af22b47..cf27cf0 100644
--- a/core/res/res/anim/wallpaper_open_enter.xml
+++ b/core/res/res/anim/wallpaper_open_enter.xml
@@ -17,6 +17,22 @@
 */
 -->
 
+<!-- This version zooms the new non-wallpaper up off the wallpaper the
+     wallpaper.  The wallpaper here just stays fixed behind. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale=".5" android:toXScale="1.0"
+           android:fromYScale=".5" android:toYScale="1.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
+
+<!-- This version is a variation on the inter-activity slide that
+    also scales the wallpaper. -->
+<!--
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator"
         android:zAdjustment="top">
@@ -27,3 +43,4 @@
 	<translate android:fromXDelta="-100%" android:toXDelta="0"
         android:duration="@android:integer/config_mediumAnimTime"/>
 </set>
+-->
diff --git a/core/res/res/anim/wallpaper_open_exit.xml b/core/res/res/anim/wallpaper_open_exit.xml
index 47cb6d6..b7a539c 100644
--- a/core/res/res/anim/wallpaper_open_exit.xml
+++ b/core/res/res/anim/wallpaper_open_exit.xml
@@ -17,8 +17,22 @@
 */
 -->
 
+<!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator">
+    <scale android:fromXScale="1.0" android:toXScale="2.0"
+           android:fromYScale="1.0" android:toYScale="2.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+</set>
+
+<!-- This version is a variation on the inter-activity slide that
+    also scales the wallpaper. -->
+<!--
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator">
 	<translate android:fromXDelta="0%" android:toXDelta="33%"
         android:duration="@android:integer/config_mediumAnimTime"/>
 </set>
+-->
diff --git a/core/res/res/drawable-hdpi/ic_aggregated.png b/core/res/res/drawable-hdpi/ic_aggregated.png
new file mode 100644
index 0000000..7ca15b1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_aggregated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_aggregated.png b/core/res/res/drawable-mdpi/ic_aggregated.png
new file mode 100644
index 0000000..7c2e2b0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_aggregated.png
Binary files differ
diff --git a/core/res/res/layout/contact_header.xml b/core/res/res/layout/contact_header.xml
index e800dfa..d19bb04 100644
--- a/core/res/res/layout/contact_header.xml
+++ b/core/res/res/layout/contact_header.xml
@@ -38,8 +38,24 @@
         android:layout_marginTop="5dip"
         android:orientation="vertical">
 
-        <!-- "Name" field is locale-specific. -->
-        <include layout="@layout/contact_header_name"/>
+        <LinearLayout
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:id="@+id/aggregate_badge"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingRight="3dip"
+                android:paddingTop="3dip"
+                android:src="@drawable/ic_aggregated"
+            />
+
+            <!-- "Name" field is locale-specific. -->
+            <include layout="@layout/contact_header_name"/>
+
+        </LinearLayout>
 
         <TextView android:id="@+id/status"
             android:layout_width="fill_parent"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e7b379a..c3b7a2c 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3486,13 +3486,29 @@
     <!-- Contacts meta-data attributes -->
     <!-- =============================== -->
 
+    <!-- TODO: remove this deprecated styleable -->
     <declare-styleable name="Icon">
         <attr name="icon" />
         <attr name="mimeType" />
     </declare-styleable>
 
+    <!-- TODO: remove this deprecated styleable -->
     <declare-styleable name="IconDefault">
         <attr name="icon" />
     </declare-styleable>
 
+    <!-- Maps a specific contact data MIME-type to styling information -->
+    <declare-styleable name="ContactsDataKind">
+        <!-- Mime-type handled by this mapping -->
+        <attr name="mimeType" />
+        <!-- Icon used to represent data of this kind -->
+        <attr name="icon" />
+        <!-- Column in data table that summarizes this data -->
+        <attr name="summaryColumn" format="string" />
+        <!-- Column in data table that contains details for this data -->
+        <attr name="detailColumn" format="string" />
+        <!-- Flag indicating that detail should be built from SocialProvider -->
+        <attr name="detailSocialSummary" format="boolean" />
+    </declare-styleable>
+
 </resources>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 2f09aca..15841a8 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -19,7 +19,7 @@
 -->
 <resources>
 	<drawable name="screen_background_light">#ffffffff</drawable>
-	<drawable name="screen_background_dark">#ff1a1a1a</drawable>
+	<drawable name="screen_background_dark">#ff000000</drawable>
     <drawable name="status_bar_closed_default_background">#ff000000</drawable>
     <drawable name="status_bar_opened_default_background">#ff000000</drawable>
     <drawable name="search_bar_default_color">#ff000000</drawable>
@@ -36,7 +36,7 @@
     <color name="white">#ffffffff</color>
     <color name="black">#ff000000</color>
     <color name="transparent">#00000000</color>
-    <color name="background_dark">#ff1a1a1a</color>
+    <color name="background_dark">#ff000000</color>
     <color name="bright_foreground_dark">#ffffffff</color>
     <color name="bright_foreground_dark_disabled">#80ffffff</color>
     <color name="bright_foreground_dark_inverse">#ff000000</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7695503..7aeaec4 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -27,13 +27,13 @@
     <bool name="config_sf_limitedAlpha">false</bool>
     
     <!-- The duration (in milliseconds) of a short animation. -->
-    <integer name="config_shortAnimTime">100</integer>
+    <integer name="config_shortAnimTime">150</integer>
     
     <!-- The duration (in milliseconds) of a medium-length animation. -->
-    <integer name="config_mediumAnimTime">150</integer>
+    <integer name="config_mediumAnimTime">250</integer>
     
     <!-- The duration (in milliseconds) of a long animation. -->
-    <integer name="config_longAnimTime">300</integer>
+    <integer name="config_longAnimTime">400</integer>
 
     <!-- XXXXX NOTE THE FOLLOWING RESOURCES USE THE WRONG NAMING CONVENTION.
          Please don't copy them, copy anything else. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 89581e6..b08a58a 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1166,6 +1166,9 @@
   <public type="attr" name="accountPreferences" />
   <public type="attr" name="textAppearanceSearchResultSubtitle" />
   <public type="attr" name="textAppearanceSearchResultTitle" />
+  <public type="attr" name="summaryColumn" />
+  <public type="attr" name="detailColumn" />
+  <public type="attr" name="detailSocialSummary" />
 
   <public type="style" name="Theme.Wallpaper" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a1a0102..e2f6981 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1200,6 +1200,106 @@
         <item>Jabber</item>
     </string-array>
 
+    <!-- Custom phone number type -->
+    <string name="phoneTypeCustom">Custom</string>
+    <!-- Home phone number type -->
+    <string name="phoneTypeHome">Home</string>
+    <!-- Mobile phone number type -->
+    <string name="phoneTypeMobile">Mobile</string>
+    <!-- Work phone number type -->
+    <string name="phoneTypeWork">Work</string>
+    <!-- Work fax phone number type -->
+    <string name="phoneTypeFaxWork">Work Fax</string>
+    <!-- Home fax phone number type -->
+    <string name="phoneTypeFaxHome">Home Fax</string>
+    <!-- Pager phone number type -->
+    <string name="phoneTypePager">Pager</string>
+    <!-- Other phone number type -->
+    <string name="phoneTypeOther">Other</string>
+    <!-- Callback phone number type -->
+    <string name="phoneTypeCallback">Callback</string>
+    <!-- Car phone number type -->
+    <string name="phoneTypeCar">Car</string>
+    <!-- Company main phone number type -->
+    <string name="phoneTypeCompanyMain">Company Main</string>
+    <!-- ISDN phone number type -->
+    <string name="phoneTypeIsdn">ISDN</string>
+    <!-- Main phone number type -->
+    <string name="phoneTypeMain">Main</string>
+    <!-- Other fax phone number type -->
+    <string name="phoneTypeOtherFax">Other Fax</string>
+    <!-- Radio phone number type -->
+    <string name="phoneTypeRadio">Radio</string>
+    <!-- Telex phone number type -->
+    <string name="phoneTypeTelex">Telex</string>
+    <!-- TTY TDD phone number type -->
+    <string name="phoneTypeTtyTdd">TTY TDD</string>
+    <!-- Work mobile phone number type -->
+    <string name="phoneTypeWorkMobile">Work Mobile</string>
+    <!-- Work pager phone number type -->
+    <string name="phoneTypeWorkPager">Work Pager</string>
+    <!-- Assistant phone number type -->
+    <string name="phoneTypeAssistant">Assistant</string>
+    <!-- MMS phone number type -->
+    <string name="phoneTypeMms">MMS</string>
+
+    <!-- Custom email type -->
+    <string name="emailTypeCustom">Custom</string>
+    <!-- Home email type -->
+    <string name="emailTypeHome">Home</string>
+    <!-- Work email type -->
+    <string name="emailTypeWork">Work</string>
+    <!-- Other email type -->
+    <string name="emailTypeOther">Other</string>
+    <!-- Mobile email type -->
+    <string name="emailTypeMobile">Mobile</string>
+
+    <!-- Custom postal address type -->
+    <string name="postalTypeCustom">Custom</string>
+    <!-- Home postal address type -->
+    <string name="postalTypeHome">Home</string>
+    <!-- Work postal address type -->
+    <string name="postalTypeWork">Work</string>
+    <!-- Other postal address type -->
+    <string name="postalTypeOther">Other</string>
+
+    <!-- Custom IM address type -->
+    <string name="imTypeCustom">Custom</string>
+    <!-- Home IM address type -->
+    <string name="imTypeHome">Home</string>
+    <!-- Work IM address type -->
+    <string name="imTypeWork">Work</string>
+    <!-- Other IM address type -->
+    <string name="imTypeOther">Other</string>
+
+    <!-- Custom IM address type -->
+    <string name="imProtocolCustom">Custom</string>
+    <!-- AIM IM protocol type -->
+    <string name="imProtocolAim">AIM</string>
+    <!-- MSN IM protocol type -->
+    <string name="imProtocolMsn">Windows Live</string>
+    <!-- Yahoo IM protocol type -->
+    <string name="imProtocolYahoo">Yahoo</string>
+    <!-- Skype IM protocol type -->
+    <string name="imProtocolSkype">Skype</string>
+    <!-- QQ IM protocol type -->
+    <string name="imProtocolQq">QQ</string>
+    <!-- Google Talk IM protocol type -->
+    <string name="imProtocolGoogleTalk">Google Talk</string>
+    <!-- ICQ IM protocol type -->
+    <string name="imProtocolIcq">ICQ</string>
+    <!-- Jabber IM protocol type -->
+    <string name="imProtocolJabber">Jabber</string>
+    <!-- NetMeeting IM protocol type -->
+    <string name="imProtocolNetMeeting">NetMeeting</string>
+
+    <!-- Work organization type -->
+    <string name="orgTypeWork">Work</string>
+    <!-- Other organization type -->
+    <string name="orgTypeOther">Other</string>
+    <!-- Custom organization type -->
+    <string name="orgTypeCustom">Custom</string>
+
     <!-- Instructions telling the user to enter their pin to unlock the keyguard.
          Displayed in one line in a large font.  -->
     <string name="keyguard_password_enter_pin_code">Enter PIN code</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 35db8ee..bc8ec45 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -58,6 +58,19 @@
         <item name="activityOpenExitAnimation">@anim/activity_open_exit</item>
         <item name="activityCloseEnterAnimation">@anim/activity_close_enter</item>
         <item name="activityCloseExitAnimation">@anim/activity_close_exit</item>
+        <item name="taskOpenEnterAnimation">@anim/activity_open_enter</item>
+        <item name="taskOpenExitAnimation">@anim/activity_open_exit</item>
+        <item name="taskCloseEnterAnimation">@anim/activity_close_enter</item>
+        <item name="taskCloseExitAnimation">@anim/activity_close_exit</item>
+        <item name="taskToFrontEnterAnimation">@anim/activity_open_enter</item>
+        <item name="taskToFrontExitAnimation">@anim/activity_open_exit</item>
+        <item name="taskToBackEnterAnimation">@anim/activity_close_enter</item>
+        <item name="taskToBackExitAnimation">@anim/activity_close_exit</item>
+        <!-- There is a good argument to be made that the user shouldn't
+             be aware of task transitions, so we are going to use the same
+             animation for them as we do for regular activity transitions. -->
+        <!-- These provide an alternative animation for task transitions. -->
+        <!--
         <item name="taskOpenEnterAnimation">@anim/task_open_enter</item>
         <item name="taskOpenExitAnimation">@anim/task_open_exit</item>
         <item name="taskCloseEnterAnimation">@anim/task_close_enter</item>
@@ -66,6 +79,7 @@
         <item name="taskToFrontExitAnimation">@anim/task_open_exit</item>
         <item name="taskToBackEnterAnimation">@anim/task_close_enter</item>
         <item name="taskToBackExitAnimation">@anim/task_close_exit</item>
+        -->
         <item name="wallpaperOpenEnterAnimation">@anim/wallpaper_open_enter</item>
         <item name="wallpaperOpenExitAnimation">@anim/wallpaper_open_exit</item>
         <item name="wallpaperCloseEnterAnimation">@anim/wallpaper_close_enter</item>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b29e571..fbdd247 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -354,7 +354,7 @@
     <style name="Theme.NoDisplay">
         <item name="android:windowBackground">@null</item>
         <item name="android:windowContentOverlay">@null</item>
-        <item name="android:windowIsTranslucent">false</item>
+        <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowAnimationStyle">@null</item>
         <item name="android:windowDisablePreview">true</item>
         <item name="android:windowNoDisplay">true</item>
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 30c81ab..957f2dd 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -48,50 +48,49 @@
     }
 
     public void data(int[] d) {
-        int size;
-        if(mType != null && mType.mElement != null) {
-            size = mType.mElement.mSize;
-            for(int ct=0; ct < mType.mValues.length; ct++) {
-                if(mType.mValues[ct] != 0) {
-                    size *= mType.mValues[ct];
-                }
-            }
-            if((d.length * 4) < size) {
-                throw new IllegalArgumentException("Array too small for allocation type.");
-            }
-            Log.e("rs", "Alloc data size=" + size);
-            mRS.nAllocationData(mID, d, size);
-            return;
-        }
-        mRS.nAllocationData(mID, d, d.length * 4);
+        subData1D(0, mType.getElementCount(), d);
+    }
+    public void data(short[] d) {
+        subData1D(0, mType.getElementCount(), d);
+    }
+    public void data(byte[] d) {
+        subData1D(0, mType.getElementCount(), d);
+    }
+    public void data(float[] d) {
+        subData1D(0, mType.getElementCount(), d);
     }
 
-    public void data(float[] d) {
-        int size;
-        if(mType != null && mType.mElement != null) {
-            size = mType.mElement.mSize;
-            for(int ct=0; ct < mType.mValues.length; ct++) {
-                if(mType.mValues[ct] != 0) {
-                    size *= mType.mValues[ct];
-                }
-            }
-            if((d.length * 4) < size) {
-                throw new IllegalArgumentException("Array too small for allocation type.");
-            }
-            Log.e("rs", "Alloc data size=" + size);
-            mRS.nAllocationData(mID, d, size);
-            return;
+    private void data1DChecks(int off, int count, int len, int dataSize) {
+        if((off < 0) || (count < 1) || ((off + count) > mType.getElementCount())) {
+            throw new IllegalArgumentException("Offset or Count out of bounds.");
         }
-        mRS.nAllocationData(mID, d, d.length * 4);
+        if((len) < dataSize) {
+            throw new IllegalArgumentException("Array too small for allocation type.");
+        }
     }
 
     public void subData1D(int off, int count, int[] d) {
-        mRS.nAllocationSubData1D(mID, off, count, d, count * 4);
+        int dataSize = mType.mElement.getSizeBytes() * count;
+        data1DChecks(off, count, d.length * 4, dataSize);
+        mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+    }
+    public void subData1D(int off, int count, short[] d) {
+        int dataSize = mType.mElement.getSizeBytes() * count;
+        data1DChecks(off, count, d.length * 2, dataSize);
+        mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+    }
+    public void subData1D(int off, int count, byte[] d) {
+        int dataSize = mType.mElement.getSizeBytes() * count;
+        data1DChecks(off, count, d.length, dataSize);
+        mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+    }
+    public void subData1D(int off, int count, float[] d) {
+        int dataSize = mType.mElement.getSizeBytes() * count;
+        data1DChecks(off, count, d.length * 4, dataSize);
+        mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
     }
 
-    public void subData1D(int off, int count, float[] d) {
-        mRS.nAllocationSubData1D(mID, off, count, d, d.length * 4);
-    }
+
 
     public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
         mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
@@ -213,11 +212,15 @@
     static public Allocation createSized(RenderScript rs, Element e, int count)
         throws IllegalArgumentException {
 
-        int id = rs.nAllocationCreateSized(e.mID, count);
+        Type.Builder b = new Type.Builder(rs, e);
+        b.add(Dimension.X, count);
+        Type t = b.create();
+
+        int id = rs.nAllocationCreateTyped(t.mID);
         if(id == 0) {
             throw new IllegalStateException("Bad element.");
         }
-        return new Allocation(id, rs, null);
+        return new Allocation(id, rs, t);
     }
 
     static public Allocation createFromBitmap(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips)
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 04c36fd..0a586c4 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -26,18 +26,40 @@
     int mSize;
     Entry[] mEntries;
 
+    int getSizeBytes() {
+        return mSize;
+    }
+    int getComponentCount() {
+        return mEntries.length;
+    }
+    Element.DataType getComponentDataType(int num) {
+        return mEntries[num].mType;
+    }
+    Element.DataKind getComponentDataKind(int num) {
+        return mEntries[num].mKind;
+    }
+    boolean getComponentIsNormalized(int num) {
+        return mEntries[num].mIsNormalized;
+    }
+    int getComponentBits(int num) {
+        return mEntries[num].mBits;
+    }
+    String getComponentName(int num) {
+        return mEntries[num].mName;
+    }
+
     static class Entry {
-        Element mElement;
+        //Element mElement;
         Element.DataType mType;
         Element.DataKind mKind;
         boolean mIsNormalized;
         int mBits;
         String mName;
 
-        Entry(Element e, int bits) {
-            mElement = e;
-            int mBits = bits;
-        }
+        //Entry(Element e, int bits) {
+            //mElement = e;
+            //int mBits = bits;
+        //}
 
         Entry(DataType dt, DataKind dk, boolean isNorm, int bits, String name) {
             mType = dt;
@@ -266,14 +288,11 @@
         int bits = 0;
         for (int ct=0; ct < e.mEntries.length; ct++) {
             Entry en = e.mEntries[ct];
-            if(en.mElement !=  null) {
+            //if(en.mElement !=  null) {
                 //rs.nElementAdd(en.mElement.mID);
-            } else {
-                int norm = 0;
-                if (en.mIsNormalized) {
-                    norm = 1;
-                }
-                rs.nElementAdd(en.mKind.mID, en.mType.mID, norm, en.mBits, en.mName);
+            //} else
+            {
+                rs.nElementAdd(en.mKind.mID, en.mType.mID, en.mIsNormalized, en.mBits, en.mName);
                 bits += en.mBits;
             }
         }
@@ -308,11 +327,11 @@
             mEntryCount++;
         }
 
-        public Builder add(Element e) throws IllegalArgumentException {
-            Entry en = new Entry(e, e.mSize * 8);
-            addEntry(en);
-            return this;
-        }
+        //public Builder add(Element e) throws IllegalArgumentException {
+            //Entry en = new Entry(e, e.mSize * 8);
+            //addEntry(en);
+            //return this;
+        //}
 
         public Builder add(Element.DataType dt, Element.DataKind dk, boolean isNormalized, int bits, String name) {
             Entry en = new Entry(dt, dk, isNormalized, bits, name);
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index d35c5e3..5831d13 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -80,7 +80,7 @@
     native int  nFileOpen(byte[] name);
 
     native void nElementBegin();
-    native void nElementAdd(int kind, int type, int norm, int bits, String s);
+    native void nElementAdd(int kind, int type, boolean norm, int bits, String s);
     native int  nElementCreate();
 
     native void nTypeBegin(int elementID);
@@ -90,17 +90,19 @@
     native void nTypeSetupFields(Type t, int[] types, int[] bits, Field[] IDs);
 
     native int  nAllocationCreateTyped(int type);
-    native int  nAllocationCreateSized(int elem, int count);
+    //native int  nAllocationCreateSized(int elem, int count);
     native int  nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp);
     native int  nAllocationCreateFromBitmapBoxed(int dstFmt, boolean genMips, Bitmap bmp);
     native int  nAllocationCreateFromAssetStream(int dstFmt, boolean genMips, int assetStream);
 
     native void nAllocationUploadToTexture(int alloc, int baseMioLevel);
     native void nAllocationUploadToBufferObject(int alloc);
-    native void nAllocationData(int id, int[] d, int sizeBytes);
-    native void nAllocationData(int id, float[] d, int sizeBytes);
+
     native void nAllocationSubData1D(int id, int off, int count, int[] d, int sizeBytes);
+    native void nAllocationSubData1D(int id, int off, int count, short[] d, int sizeBytes);
+    native void nAllocationSubData1D(int id, int off, int count, byte[] d, int sizeBytes);
     native void nAllocationSubData1D(int id, int off, int count, float[] d, int sizeBytes);
+
     native void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, int[] d, int sizeBytes);
     native void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, float[] d, int sizeBytes);
     native void nAllocationRead(int id, int[] d);
diff --git a/graphics/java/android/renderscript/SimpleMesh.java b/graphics/java/android/renderscript/SimpleMesh.java
index 5d87654..dc74c61 100644
--- a/graphics/java/android/renderscript/SimpleMesh.java
+++ b/graphics/java/android/renderscript/SimpleMesh.java
@@ -162,7 +162,6 @@
         }
 
         public SimpleMesh create() {
-            Log.e("rs", "SimpleMesh create");
             SimpleMesh sm = internalCreate(mRS, this);
             sm.mVertexTypes = new Type[mVertexTypeCount];
             for(int ct=0; ct < mVertexTypeCount; ct++) {
@@ -177,7 +176,7 @@
     public static class TriangleMeshBuilder {
         float mVtxData[];
         int mVtxCount;
-        int mIndexData[];
+        short mIndexData[];
         int mIndexCount;
         RenderScript mRS;
         Element mElement;
@@ -191,7 +190,7 @@
             mVtxCount = 0;
             mIndexCount = 0;
             mVtxData = new float[128];
-            mIndexData = new int[128];
+            mIndexData = new short[128];
             mVtxSize = vtxSize;
             mNorm = norm;
             mTex = tex;
@@ -268,13 +267,13 @@
 
         public void addTriangle(int idx1, int idx2, int idx3) {
             if((mIndexCount + 3) >= mIndexData.length) {
-                int t[] = new int[mIndexData.length * 2];
+                short t[] = new short[mIndexData.length * 2];
                 System.arraycopy(mIndexData, 0, t, 0, mIndexData.length);
                 mIndexData = t;
             }
-            mIndexData[mIndexCount++] = idx1;
-            mIndexData[mIndexCount++] = idx2;
-            mIndexData[mIndexCount++] = idx3;
+            mIndexData[mIndexCount++] = (short)idx1;
+            mIndexData[mIndexCount++] = (short)idx2;
+            mIndexData[mIndexCount++] = (short)idx3;
         }
 
         public SimpleMesh create() {
@@ -309,10 +308,6 @@
             vertexAlloc.data(mVtxData);
             vertexAlloc.uploadToBufferObject();
 
-            // This is safe because length is a pow2
-            for(int ct=0; ct < (mIndexCount+1); ct += 2) {
-                mIndexData[ct >> 1] = mIndexData[ct] | (mIndexData[ct+1] << 16);
-            }
             indexAlloc.data(mIndexData);
             indexAlloc.uploadToBufferObject();
 
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index b6b7adf..df60990 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -23,13 +23,74 @@
  *
  **/
 public class Type extends BaseObj {
-    Dimension[] mDimensions;
-    int[] mValues;
+    int mDimX;
+    int mDimY;
+    int mDimZ;
+    boolean mDimLOD;
+    boolean mDimFaces;
+    int mElementCount;
     Element mElement;
+
     private int mNativeCache;
     Class mJavaClass;
 
 
+    public int getX() {
+        return mDimX;
+    }
+    public int getY() {
+        return mDimY;
+    }
+    public int getZ() {
+        return mDimZ;
+    }
+    public boolean getLOD() {
+        return mDimLOD;
+    }
+    public boolean getFaces() {
+        return mDimFaces;
+    }
+    public int getElementCount() {
+        return mElementCount;
+    }
+
+    void calcElementCount() {
+        boolean hasLod = getLOD();
+        int x = getX();
+        int y = getY();
+        int z = getZ();
+        int faces = 1;
+        if(getFaces()) {
+            faces = 6;
+        }
+        if(x == 0) {
+            x = 1;
+        }
+        if(y == 0) {
+            y = 1;
+        }
+        if(z == 0) {
+            z = 1;
+        }
+
+        int count = x * y * z * faces;
+        if(hasLod && (x > 1) && (y > 1) && (z > 1)) {
+            if(x > 1) {
+                x >>= 1;
+            }
+            if(y > 1) {
+                y >>= 1;
+            }
+            if(z > 1) {
+                z >>= 1;
+            }
+
+            count += x * y * z * faces;
+        }
+        mElementCount = count;
+    }
+
+
     Type(int id, RenderScript rs) {
         super(rs);
         mID = id;
@@ -131,12 +192,25 @@
         public Type create() {
             Type t = internalCreate(mRS, this);
             t.mElement = mElement;
-            t.mDimensions = new Dimension[mEntryCount];
-            t.mValues = new int[mEntryCount];
+
             for(int ct=0; ct < mEntryCount; ct++) {
-                t.mDimensions[ct] = mEntries[ct].mDim;
-                t.mValues[ct] = mEntries[ct].mValue;
+                if(mEntries[ct].mDim == Dimension.X) {
+                    t.mDimX = mEntries[ct].mValue;
+                }
+                if(mEntries[ct].mDim == Dimension.Y) {
+                    t.mDimY = mEntries[ct].mValue;
+                }
+                if(mEntries[ct].mDim == Dimension.Z) {
+                    t.mDimZ = mEntries[ct].mValue;
+                }
+                if(mEntries[ct].mDim == Dimension.LOD) {
+                    t.mDimLOD = mEntries[ct].mValue != 0;
+                }
+                if(mEntries[ct].mDim == Dimension.FACE) {
+                    t.mDimFaces = mEntries[ct].mValue != 0;
+                }
             }
+            t.calcElementCount();
             return t;
         }
     }
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index c7b5448..56a4223 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -181,7 +181,7 @@
 
 
 static void
-nElementAdd(JNIEnv *_env, jobject _this, jint kind, jint type, jint norm, jint bits, jstring name)
+nElementAdd(JNIEnv *_env, jobject _this, jint kind, jint type, jboolean norm, jint bits, jstring name)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     const char* n = NULL;
@@ -359,14 +359,6 @@
     return (jint) rsAllocationCreateTyped(con, (RsElement)e);
 }
 
-static jint
-nAllocationCreateSized(JNIEnv *_env, jobject _this, jint e, jint count)
-{
-    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
-    LOG_API("nAllocationCreateSized, con(%p), e(%p), count(%i)", con, (RsElement)e, count);
-    return (jint) rsAllocationCreateSized(con, (RsElement)e, count);
-}
-
 static void
 nAllocationUploadToTexture(JNIEnv *_env, jobject _this, jint a, jint mip)
 {
@@ -476,44 +468,44 @@
 
 
 static void
-nAllocationData_i(JNIEnv *_env, jobject _this, jint alloc, jintArray data, int sizeBytes)
-{
-    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
-    jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAllocationData(con, (RsAllocation)alloc, ptr, sizeBytes);
-    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData_f(JNIEnv *_env, jobject _this, jint alloc, jfloatArray data, int sizeBytes)
-{
-    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
-    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAllocationData(con, (RsAllocation)alloc, ptr, sizeBytes);
-    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
 nAllocationSubData1D_i(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jintArray data, int sizeBytes)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len);
+    LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
     jint *ptr = _env->GetIntArrayElements(data, NULL);
     rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
     _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
 }
 
 static void
+nAllocationSubData1D_s(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jshortArray data, int sizeBytes)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocation1DSubData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
+    jshort *ptr = _env->GetShortArrayElements(data, NULL);
+    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
+    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationSubData1D_b(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jbyteArray data, int sizeBytes)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocation1DSubData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
+    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
+    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
+    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
 nAllocationSubData1D_f(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jfloatArray data, int sizeBytes)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len);
+    LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
     jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
     rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
     _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
@@ -1323,7 +1315,7 @@
 {"nFileOpen",                      "([B)I",                                (void*)nFileOpen },
 
 {"nElementBegin",                  "()V",                                  (void*)nElementBegin },
-{"nElementAdd",                    "(IIIILjava/lang/String;)V",            (void*)nElementAdd },
+{"nElementAdd",                    "(IIZILjava/lang/String;)V",            (void*)nElementAdd },
 {"nElementCreate",                 "()I",                                  (void*)nElementCreate },
 
 {"nTypeBegin",                     "(I)V",                                 (void*)nTypeBegin },
@@ -1333,15 +1325,14 @@
 {"nTypeSetupFields",               "(Landroid/renderscript/Type;[I[I[Ljava/lang/reflect/Field;)V", (void*)nTypeSetupFields },
 
 {"nAllocationCreateTyped",         "(I)I",                                 (void*)nAllocationCreateTyped },
-{"nAllocationCreateSized",         "(II)I",                                (void*)nAllocationCreateSized },
 {"nAllocationCreateFromBitmap",    "(IZLandroid/graphics/Bitmap;)I",       (void*)nAllocationCreateFromBitmap },
 {"nAllocationCreateFromBitmapBoxed","(IZLandroid/graphics/Bitmap;)I",      (void*)nAllocationCreateFromBitmapBoxed },
 {"nAllocationCreateFromAssetStream","(IZI)I",                              (void*)nAllocationCreateFromAssetStream },
 {"nAllocationUploadToTexture",     "(II)V",                                (void*)nAllocationUploadToTexture },
 {"nAllocationUploadToBufferObject","(I)V",                                 (void*)nAllocationUploadToBufferObject },
-{"nAllocationData",                "(I[II)V",                              (void*)nAllocationData_i },
-{"nAllocationData",                "(I[FI)V",                              (void*)nAllocationData_f },
 {"nAllocationSubData1D",           "(III[II)V",                            (void*)nAllocationSubData1D_i },
+{"nAllocationSubData1D",           "(III[SI)V",                            (void*)nAllocationSubData1D_s },
+{"nAllocationSubData1D",           "(III[BI)V",                            (void*)nAllocationSubData1D_b },
 {"nAllocationSubData1D",           "(III[FI)V",                            (void*)nAllocationSubData1D_f },
 {"nAllocationSubData2D",           "(IIIII[II)V",                          (void*)nAllocationSubData2D_i },
 {"nAllocationSubData2D",           "(IIIII[FI)V",                          (void*)nAllocationSubData2D_f },
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index b47e399..a47534b 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -92,12 +92,12 @@
         return contains(key.getBytes());
     }
 
-    public byte[][] scan(byte[] prefix) {
+    public byte[][] saw(byte[] prefix) {
         return execute('s', prefix);
     }
 
-    public String[] scan(String prefix) {
-        byte[][] values = scan(prefix.getBytes());
+    public String[] saw(String prefix) {
+        byte[][] values = saw(prefix.getBytes());
         if (values == null) {
             return null;
         }
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index e534447..6500791 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1227,44 +1227,46 @@
             enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove);
        }
 
-
-        // output audio to hardware
-        if (mSuspended) {
-            usleep(kMaxBufferRecoveryInUsecs);
+        if (LIKELY(enabledTracks)) {
+            // mix buffers...
+            mAudioMixer->process(curBuf);
+            sleepTime = 0;
+            standbyTime = systemTime() + kStandbyTimeInNsecs;
         } else {
-            if (LIKELY(enabledTracks)) {
-                // mix buffers...
-                mAudioMixer->process(curBuf);
+            sleepTime += kBufferRecoveryInUsecs;
+            if (sleepTime > kMaxBufferRecoveryInUsecs) {
+                sleepTime = kMaxBufferRecoveryInUsecs;
+            }
+            // There was nothing to mix this round, which means all
+            // active tracks were late. Sleep a little bit to give
+            // them another chance. If we're too late, write 0s to audio
+            // hardware to avoid underrun.
+            if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs) {
+                memset (curBuf, 0, mixBufferSize);
                 sleepTime = 0;
-                standbyTime = systemTime() + kStandbyTimeInNsecs;
-            } else {
-                sleepTime += kBufferRecoveryInUsecs;
-                // There was nothing to mix this round, which means all
-                // active tracks were late. Sleep a little bit to give
-                // them another chance. If we're too late, write 0s to audio
-                // hardware to avoid underrun.
-                if (mBytesWritten == 0 || sleepTime < kMaxBufferRecoveryInUsecs) {
-                    usleep(kBufferRecoveryInUsecs);
-                } else {
-                    memset (curBuf, 0, mixBufferSize);
-                    sleepTime = 0;
-                }
             }
-            // sleepTime == 0 means PCM data were written to mMixBuffer[]
-            if (sleepTime == 0) {
-                mLastWriteTime = systemTime();
-                mInWrite = true;
-                int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
-                if (bytesWritten > 0) mBytesWritten += bytesWritten;
-                mNumWrites++;
-                mInWrite = false;
-                mStandby = false;
-                nsecs_t delta = systemTime() - mLastWriteTime;
-                if (delta > maxPeriod) {
-                    LOGW("write blocked for %llu msecs", ns2ms(delta));
-                    mNumDelayedWrites++;
-                }
+        }
+
+        if (mSuspended) {
+            sleepTime = kMaxBufferRecoveryInUsecs;
+        }
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
+            mLastWriteTime = systemTime();
+            mInWrite = true;
+            LOGV("mOutput->write() thread %p frames %d", this, mFrameCount);
+            int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
+            if (bytesWritten > 0) mBytesWritten += bytesWritten;
+            mNumWrites++;
+            mInWrite = false;
+            mStandby = false;
+            nsecs_t delta = systemTime() - mLastWriteTime;
+            if (delta > maxPeriod) {
+                LOGW("write blocked for %llu msecs, thread %p", ns2ms(delta), this);
+                mNumDelayedWrites++;
             }
+        } else {
+            usleep(sleepTime);
         }
 
         // finally let go of all our tracks, without the lock held
@@ -1718,50 +1720,55 @@
             }
        }
 
-        // output audio to hardware
-        if (mSuspended) {
-            usleep(kMaxBufferRecoveryInUsecs);
+        if (activeTrack != 0) {
+            AudioBufferProvider::Buffer buffer;
+            size_t frameCount = mFrameCount;
+            curBuf = (int8_t *)mMixBuffer;
+            // output audio to hardware
+            while(frameCount) {
+                buffer.frameCount = frameCount;
+                activeTrack->getNextBuffer(&buffer);
+                if (UNLIKELY(buffer.raw == 0)) {
+                    memset(curBuf, 0, frameCount * mFrameSize);
+                    break;
+                }
+                memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
+                frameCount -= buffer.frameCount;
+                curBuf += buffer.frameCount * mFrameSize;
+                activeTrack->releaseBuffer(&buffer);
+            }
+            sleepTime = 0;
+            standbyTime = systemTime() + kStandbyTimeInNsecs;
         } else {
-            if (activeTrack != 0) {
-                AudioBufferProvider::Buffer buffer;
-                size_t frameCount = mFrameCount;
-                curBuf = (int8_t *)mMixBuffer;
-                // output audio to hardware
-                while(frameCount) {
-                    buffer.frameCount = frameCount;
-                    activeTrack->getNextBuffer(&buffer);
-                    if (UNLIKELY(buffer.raw == 0)) {
-                        memset(curBuf, 0, frameCount * mFrameSize);
-                        break;
-                    }
-                    memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
-                    frameCount -= buffer.frameCount;
-                    curBuf += buffer.frameCount * mFrameSize;
-                    activeTrack->releaseBuffer(&buffer);
-                }
+            sleepTime += kBufferRecoveryInUsecs;
+            if (sleepTime > kMaxBufferRecoveryInUsecs) {
+                sleepTime = kMaxBufferRecoveryInUsecs;
+            }
+            // There was nothing to mix this round, which means all
+            // active tracks were late. Sleep a little bit to give
+            // them another chance. If we're too late, write 0s to audio
+            // hardware to avoid underrun.
+            if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs &&
+                AudioSystem::isLinearPCM(mFormat)) {
+                memset (mMixBuffer, 0, mFrameCount * mFrameSize);
                 sleepTime = 0;
-                standbyTime = systemTime() + kStandbyTimeInNsecs;
-            } else {
-                sleepTime += kBufferRecoveryInUsecs;
-                if (mBytesWritten == 0 || !AudioSystem::isLinearPCM(mFormat) ||
-                    sleepTime < kMaxBufferRecoveryInUsecs) {
-                    usleep(kBufferRecoveryInUsecs);
-                } else {
-                    memset (mMixBuffer, 0, mFrameCount * mFrameSize);
-                    sleepTime = 0;
-                }
             }
+        }
 
-            // sleepTime == 0 means PCM data were written to mMixBuffer[]
-            if (sleepTime == 0) {
-                mLastWriteTime = systemTime();
-                mInWrite = true;
-                int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
-                if (bytesWritten) mBytesWritten += bytesWritten;
-                mNumWrites++;
-                mInWrite = false;
-                mStandby = false;
-            }
+        if (mSuspended) {
+            sleepTime = kMaxBufferRecoveryInUsecs;
+        }
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
+            mLastWriteTime = systemTime();
+            mInWrite = true;
+            int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
+            if (bytesWritten) mBytesWritten += bytesWritten;
+            mNumWrites++;
+            mInWrite = false;
+            mStandby = false;
+        } else {
+            usleep(sleepTime);
         }
 
         // finally let go of removed track, without the lock held
@@ -1913,38 +1920,40 @@
             }
 
             enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove);
-       }
+        }
 
-        bool mustSleep = true;
         if (LIKELY(enabledTracks)) {
             // mix buffers...
             mAudioMixer->process(curBuf);
-            if (!mSuspended) {
-                for (size_t i = 0; i < outputTracks.size(); i++) {
-                    outputTracks[i]->write(curBuf, mFrameCount);
-                    mustSleep = false;
-                }
-                mStandby = false;
-                mBytesWritten += mixBufferSize;
-            }
+            sleepTime = 0;
+            standbyTime = systemTime() + kStandbyTimeInNsecs;
         } else {
-            // flush remaining overflow buffers in output tracks
-            for (size_t i = 0; i < outputTracks.size(); i++) {
-                if (outputTracks[i]->isActive()) {
-                    outputTracks[i]->write(curBuf, 0);
-                    standbyTime = systemTime() + kStandbyTimeInNsecs;
-                    mustSleep = false;
-                }
+            sleepTime += kBufferRecoveryInUsecs;
+            if (sleepTime > kMaxBufferRecoveryInUsecs) {
+                sleepTime = kMaxBufferRecoveryInUsecs;
+            }
+            // There was nothing to mix this round, which means all
+            // active tracks were late. Sleep a little bit to give
+            // them another chance. If we're too late, write 0s to audio
+            // hardware to avoid underrun.
+            if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs) {
+                memset (curBuf, 0, mixBufferSize);
+                sleepTime = 0;
             }
         }
-        if (mustSleep) {
-//            LOGV("threadLoop() sleeping %d", sleepTime);
-            usleep(sleepTime);
-            if (sleepTime < kMaxBufferRecoveryInUsecs) {
-                sleepTime += kBufferRecoveryInUsecs;
+
+        if (mSuspended) {
+            sleepTime = kMaxBufferRecoveryInUsecs;
+        }
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
+            for (size_t i = 0; i < outputTracks.size(); i++) {
+                outputTracks[i]->write(curBuf, mFrameCount);
             }
+            mStandby = false;
+            mBytesWritten += mixBufferSize;
         } else {
-            sleepTime = kBufferRecoveryInUsecs;
+            usleep(sleepTime);
         }
 
         // finally let go of all our tracks, without the lock held
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index a34889a..493e777 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -250,7 +250,9 @@
           GraphicPlane&     graphicPlane(int dpy);
 
             void        waitForEvent();
+public:     // hack to work around gcc 4.0.3 bug
             void        signalEvent();
+private:
             void        signalDelayedEvent(nsecs_t delay);
 
             void        handleConsoleEvents();
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 37a3bd5..3ac5df5 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -736,6 +736,28 @@
                     if (time != -1) {
                         values.put(Images.Media.DATE_TAKEN, time);
                     }
+
+                    int orientation = exif.getAttributeInt(
+                        ExifInterface.TAG_ORIENTATION, -1);
+                    if (orientation != -1) {
+                        // We only recognize a subset of orientation tag values.
+                        int degree;
+                        switch(orientation) {
+                            case ExifInterface.ORIENTATION_ROTATE_90:
+                                degree = 90;
+                                break;
+                            case ExifInterface.ORIENTATION_ROTATE_180:
+                                degree = 180;
+                                break;
+                            case ExifInterface.ORIENTATION_ROTATE_270:
+                                degree = 270;
+                                break;
+                            default:
+                                degree = 0;
+                                break;
+                        }
+                        values.put(Images.Media.ORIENTATION, degree);
+                    }
                 }
             }
 
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 022da0c..b3a19e3 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -271,18 +271,52 @@
      * @param renderer the renderer to use to perform OpenGL drawing.
      */
     public void setRenderer(Renderer renderer) {
-        if (mGLThread != null) {
-            throw new IllegalStateException(
-                    "setRenderer has already been called for this instance.");
-        }
+        checkRenderThreadState();
         if (mEGLConfigChooser == null) {
             mEGLConfigChooser = new SimpleEGLConfigChooser(true);
         }
+        if (mEGLContextFactory == null) {
+            mEGLContextFactory = new DefaultContextFactory();
+        }
+        if (mEGLWindowSurfaceFactory == null) {
+            mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();
+        }
         mGLThread = new GLThread(renderer);
         mGLThread.start();
     }
 
     /**
+     * @hide
+     * Install a custom EGLContextFactory.
+     * <p>If this method is
+     * called, it must be called before {@link #setRenderer(Renderer)}
+     * is called.
+     * <p>
+     * If this method is not called, then by default
+     * a context will be created with no shared context and
+     * with a null attribute list.
+     */
+    public void setContextFactory(EGLContextFactory factory) {
+        checkRenderThreadState();
+        mEGLContextFactory = factory;
+    }
+
+    /**
+     * @hide
+     * Install a custom EGLWindowSurfaceFactory.
+     * <p>If this method is
+     * called, it must be called before {@link #setRenderer(Renderer)}
+     * is called.
+     * <p>
+     * If this method is not called, then by default
+     * a window surface will be created with a null attribute list.
+     */
+    public void setWindowSurfaceFactory(EGLWindowSurfaceFactory factory) {
+        checkRenderThreadState();
+        mEGLWindowSurfaceFactory = factory;
+    }
+
+    /**
      * Install a custom EGLConfigChooser.
      * <p>If this method is
      * called, it must be called before {@link #setRenderer(Renderer)}
@@ -294,10 +328,7 @@
      * @param configChooser
      */
     public void setEGLConfigChooser(EGLConfigChooser configChooser) {
-        if (mGLThread != null) {
-            throw new IllegalStateException(
-                    "setRenderer has already been called for this instance.");
-        }
+        checkRenderThreadState();
         mEGLConfigChooser = configChooser;
     }
 
@@ -578,6 +609,56 @@
     }
 
     /**
+     * @hide
+     * An interface for customizing the eglCreateContext and eglDestroyContext calls.
+     * <p>
+     * This interface must be implemented by clients wishing to call
+     * {@link GLSurfaceView#setEGLContextFactory(EGLContextFactory)}
+     */
+    public interface EGLContextFactory {
+        EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig);
+        void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context);
+    }
+
+    private static class DefaultContextFactory implements EGLContextFactory {
+
+        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) {
+            return egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, null);
+        }
+
+        public void destroyContext(EGL10 egl, EGLDisplay display,
+                EGLContext context) {
+            egl.eglDestroyContext(display, context);
+        }
+    }
+
+    /**
+     * @hide
+     * An interface for customizing the eglCreateWindowSurface and eglDestroySurface calls.
+     * <p>
+     * This interface must be implemented by clients wishing to call
+     * {@link GLSurfaceView#setEGLContextCreator(EGLContextCreator)}
+     */
+    public interface EGLWindowSurfaceFactory {
+        EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display, EGLConfig config,
+                Object nativeWindow);
+        void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface);
+    }
+
+    private static class DefaultWindowSurfaceFactory implements EGLWindowSurfaceFactory {
+
+        public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
+                EGLConfig config, Object nativeWindow) {
+            return egl.eglCreateWindowSurface(display, config, nativeWindow, null);
+        }
+
+        public void destroySurface(EGL10 egl, EGLDisplay display,
+                EGLSurface surface) {
+            egl.eglDestroySurface(display, surface);
+        }
+    }
+
+    /**
      * An interface for choosing an EGLConfig configuration from a list of
      * potential configurations.
      * <p>
@@ -751,8 +832,7 @@
             * Create an OpenGL ES context. This must be done only once, an
             * OpenGL context is a somewhat heavy object.
             */
-            mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig,
-                    EGL10.EGL_NO_CONTEXT, null);
+            mEglContext = mEGLContextFactory.createContext(mEgl, mEglDisplay, mEglConfig);
 
             mEglSurface = null;
         }
@@ -774,14 +854,14 @@
                  */
                 mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
                         EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
-                mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+                mEGLWindowSurfaceFactory.destroySurface(mEgl, mEglDisplay, mEglSurface);
             }
 
             /*
              * Create an EGL surface we can render into.
              */
-            mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay,
-                    mEglConfig, holder, null);
+            mEglSurface = mEGLWindowSurfaceFactory.createWindowSurface(mEgl,
+                    mEglDisplay, mEglConfig, holder);
 
             /*
              * Before we can issue GL commands, we need to make sure
@@ -790,7 +870,6 @@
             mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
                     mEglContext);
 
-
             GL gl = mEglContext.getGL();
             if (mGLWrapper != null) {
                 gl = mGLWrapper.wrap(gl);
@@ -826,16 +905,19 @@
             return mEgl.eglGetError() != EGL11.EGL_CONTEXT_LOST;
         }
 
-        public void finish() {
+        public void destroySurface() {
             if (mEglSurface != null) {
                 mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
                         EGL10.EGL_NO_SURFACE,
                         EGL10.EGL_NO_CONTEXT);
-                mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+                mEGLWindowSurfaceFactory.destroySurface(mEgl, mEglDisplay, mEglSurface);
                 mEglSurface = null;
             }
+        }
+
+        public void finish() {
             if (mEglContext != null) {
-                mEgl.eglDestroyContext(mEglDisplay, mEglContext);
+                mEGLContextFactory.destroyContext(mEgl, mEglDisplay, mEglContext);
                 mEglContext = null;
             }
             if (mEglDisplay != null) {
@@ -895,78 +977,93 @@
 
         private void guardedRun() throws InterruptedException {
             mEglHelper = new EglHelper();
-            mEglHelper.start();
+            try {
+                mEglHelper.start();
 
-            GL10 gl = null;
-            boolean tellRendererSurfaceCreated = true;
-            boolean tellRendererSurfaceChanged = true;
-
-            /*
-             * This is our main activity thread's loop, we go until
-             * asked to quit.
-             */
-            while (!mDone) {
+                GL10 gl = null;
+                boolean tellRendererSurfaceCreated = true;
+                boolean tellRendererSurfaceChanged = true;
 
                 /*
-                 *  Update the asynchronous state (window size)
+                 * This is our main activity thread's loop, we go until
+                 * asked to quit.
                  */
-                int w, h;
-                boolean changed;
-                boolean needStart = false;
-                synchronized (this) {
-                    Runnable r;
-                    while ((r = getEvent()) != null) {
-                        r.run();
-                    }
-                    if (mPaused) {
-                        mEglHelper.finish();
-                        needStart = true;
-                    }
-                    while (needToWait()) {
-                        wait();
-                    }
-                    if (mDone) {
-                        break;
-                    }
-                    changed = mSizeChanged;
-                    w = mWidth;
-                    h = mHeight;
-                    mSizeChanged = false;
-                    mRequestRender = false;
-                }
-                if (needStart) {
-                    mEglHelper.start();
-                    tellRendererSurfaceCreated = true;
-                    changed = true;
-                }
-                if (changed) {
-                    gl = (GL10) mEglHelper.createSurface(getHolder());
-                    tellRendererSurfaceChanged = true;
-                }
-                if (tellRendererSurfaceCreated) {
-                    mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig);
-                    tellRendererSurfaceCreated = false;
-                }
-                if (tellRendererSurfaceChanged) {
-                    mRenderer.onSurfaceChanged(gl, w, h);
-                    tellRendererSurfaceChanged = false;
-                }
-                if ((w > 0) && (h > 0)) {
-                    /* draw a frame here */
-                    mRenderer.onDrawFrame(gl);
+                while (!mDone) {
 
                     /*
-                     * Once we're done with GL, we need to call swapBuffers()
-                     * to instruct the system to display the rendered frame
+                     *  Update the asynchronous state (window size)
                      */
-                    mEglHelper.swap();
-                }
-             }
+                    int w, h;
+                    boolean changed;
+                    boolean needStart = false;
+                    synchronized (this) {
+                        Runnable r;
+                        while ((r = getEvent()) != null) {
+                            r.run();
+                        }
+                        if (mPaused) {
+                            mEglHelper.destroySurface();
+                            mEglHelper.finish();
+                            needStart = true;
+                        }
+                        while (needToWait()) {
+                            if (!mHasSurface) {
+                                if (!mWaitingForSurface) {
+                                    mEglHelper.destroySurface();
+                                    mWaitingForSurface = true;
+                                    notify();
+                                }
+                            }
+                            wait();
+                        }
+                        if (mDone) {
+                            break;
+                        }
+                        changed = mSizeChanged;
+                        w = mWidth;
+                        h = mHeight;
+                        mSizeChanged = false;
+                        mRequestRender = false;
+                        if (mHasSurface && mWaitingForSurface) {
+                            changed = true;
+                            mWaitingForSurface = false;
+                        }
+                    }
+                    if (needStart) {
+                        mEglHelper.start();
+                        tellRendererSurfaceCreated = true;
+                        changed = true;
+                    }
+                    if (changed) {
+                        gl = (GL10) mEglHelper.createSurface(getHolder());
+                        tellRendererSurfaceChanged = true;
+                    }
+                    if (tellRendererSurfaceCreated) {
+                        mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig);
+                        tellRendererSurfaceCreated = false;
+                    }
+                    if (tellRendererSurfaceChanged) {
+                        mRenderer.onSurfaceChanged(gl, w, h);
+                        tellRendererSurfaceChanged = false;
+                    }
+                    if ((w > 0) && (h > 0)) {
+                        /* draw a frame here */
+                        mRenderer.onDrawFrame(gl);
 
-            /*
-             * clean-up everything...
-             */
-            mEglHelper.finish();
+                        /*
+                         * Once we're done with GL, we need to call swapBuffers()
+                         * to instruct the system to display the rendered frame
+                         */
+                        mEglHelper.swap();
+                    }
+                 }
+            } finally {
+                /*
+                 * clean-up everything...
+                 */
+                mEglHelper.destroySurface();
+                mEglHelper.finish();
+            }
         }
 
         private boolean needToWait() {
@@ -1021,6 +1118,13 @@
             synchronized(this) {
                 mHasSurface = false;
                 notify();
+                while(!mWaitingForSurface && isAlive()) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                        Thread.currentThread().interrupt();
+                    }
+                }
             }
         }
 
@@ -1083,6 +1187,7 @@
         private boolean mDone;
         private boolean mPaused;
         private boolean mHasSurface;
+        private boolean mWaitingForSurface;
         private int mWidth;
         private int mHeight;
         private int mRenderMode;
@@ -1124,11 +1229,21 @@
         private StringBuilder mBuilder = new StringBuilder();
     }
 
+
+    private void checkRenderThreadState() {
+        if (mGLThread != null) {
+            throw new IllegalStateException(
+                    "setRenderer has already been called for this instance.");
+        }
+    }
+
     private static final Semaphore sEglSemaphore = new Semaphore(1);
     private boolean mSizeChanged = true;
 
     private GLThread mGLThread;
     private EGLConfigChooser mEGLConfigChooser;
+    private EGLContextFactory mEGLContextFactory;
+    private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
     private GLWrapper mGLWrapper;
     private int mDebugFlags;
 }
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index d5f1c61..db1b5f1 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -29,7 +29,7 @@
     <integer name="def_screen_brightness">102</integer>
     <bool name="def_screen_brightness_automatic_mode">false</bool>
     <fraction name="def_window_animation_scale">100%</fraction>
-    <fraction name="def_window_transition_scale">0%</fraction>
+    <fraction name="def_window_transition_scale">100%</fraction>
     
     <bool name="def_bluetooth_on">false</bool>
     <bool name="def_install_non_market_apps">false</bool>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index f99eb58..c561078 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -71,7 +71,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 40;
+    private static final int DATABASE_VERSION = 41;
 
     private Context mContext;
 
@@ -481,6 +481,27 @@
             upgradeVersion = 40;
         }
 
+        if (upgradeVersion == 40) {
+            /*
+             * All animations are now turned on by default!
+             */
+            db.beginTransaction();
+            try {
+                db.execSQL("DELETE FROM system WHERE name='"
+                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
+                db.execSQL("DELETE FROM system WHERE name='"
+                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
+                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                        + " VALUES(?,?);");
+                loadDefaultAnimationSettings(stmt);
+                stmt.close();
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+            }
+            upgradeVersion = 41;
+        }
+
         if (upgradeVersion != currentVersion) {
             Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
                     + ", must wipe the settings provider");
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
index 13b4952..9909905 100644
--- a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
@@ -17,7 +17,7 @@
 package com.android.server.vpn;
 
 import android.net.vpn.L2tpIpsecProfile;
-import android.security.CertTool;
+import android.security.Credentials;
 
 import java.io.IOException;
 
@@ -30,16 +30,18 @@
     @Override
     protected void connect(String serverIp, String username, String password)
             throws IOException {
+        L2tpIpsecProfile p = getProfile();
         // IPSEC
         DaemonProxy ipsec = startDaemon(IPSEC);
         ipsec.sendCommand(serverIp, L2tpService.L2TP_PORT,
-                getUserkeyPath(), getUserCertPath(), getCaCertPath());
+                Credentials.USER_PRIVATE_KEY + p.getUserCertificate(),
+                Credentials.USER_CERTIFICATE + p.getUserCertificate(),
+                Credentials.CA_CERTIFICATE + p.getCaCertificate());
         ipsec.closeControlSocket();
 
         sleep(2000); // 2 seconds
 
         // L2TP
-        L2tpIpsecProfile p = getProfile();
         MtpdHelper.sendCommand(this, L2tpService.L2TP_DAEMON, serverIp,
                 L2tpService.L2TP_PORT,
                 (p.isSecretEnabled() ? p.getSecretString() : null),
@@ -51,19 +53,4 @@
         stopDaemon(IPSEC);
         stopDaemon(MtpdHelper.MTPD);
     }
-
-    private String getCaCertPath() {
-        return CertTool.getInstance().getCaCertificate(
-                getProfile().getCaCertificate());
-    }
-
-    private String getUserCertPath() {
-        return CertTool.getInstance().getUserCertificate(
-                getProfile().getUserCertificate());
-    }
-
-    private String getUserkeyPath() {
-        return CertTool.getInstance().getUserPrivateKey(
-                getProfile().getUserCertificate());
-    }
 }
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 854a6f9..1dc51c8 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -57,6 +57,7 @@
 import android.backup.IRestoreSession;
 import android.backup.RestoreSet;
 
+import com.android.internal.backup.BackupConstants;
 import com.android.internal.backup.LocalTransport;
 import com.android.internal.backup.IBackupTransport;
 
@@ -101,6 +102,7 @@
     private static final int BACKUP_AGENT_FAILURE_EVENT = 2823;
     private static final int BACKUP_PACKAGE_EVENT = 2824;
     private static final int BACKUP_SUCCESS_EVENT = 2825;
+    private static final int BACKUP_RESET_EVENT = 2826;
 
     private static final int RESTORE_START_EVENT = 2830;
     private static final int RESTORE_TRANSPORT_FAILURE_EVENT = 2831;
@@ -406,6 +408,47 @@
         }
     }
 
+    // Reset all of our bookkeeping, in response to having been told that
+    // the backend data has been wiped [due to idle expiry, for example],
+    // so we must re-upload all saved settings.
+    void resetBackupState(File stateFileDir) {
+        synchronized (mQueueLock) {
+            // Wipe the "what we've ever backed up" tracking
+            try {
+                // close the ever-stored journal...
+                if (mEverStoredStream != null) {
+                    mEverStoredStream.close();
+                }
+                // ... so we can delete it and start over
+                mEverStored.delete();
+                mEverStoredStream = new RandomAccessFile(mEverStored, "rwd");
+            } catch (IOException e) {
+                Log.e(TAG, "Unable to open known-stored file!");
+                mEverStoredStream = null;
+            }
+            mEverStoredApps.clear();
+
+            // Remove all the state files
+            for (File sf : stateFileDir.listFiles()) {
+                sf.delete();
+            }
+
+            // Enqueue a new backup of every participant
+            int N = mBackupParticipants.size();
+            for (int i=0; i<N; i++) {
+                int uid = mBackupParticipants.keyAt(i);
+                HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i);
+                for (ApplicationInfo app: participants) {
+                    try {
+                        dataChanged(app.packageName);
+                    } catch (RemoteException e) {
+                        // can't happen; we're in the same process
+                    }
+                }
+            }
+        }
+    }
+
     // Add a transport to our set of available backends
     private void registerTransport(String name, IBackupTransport transport) {
         synchronized (mTransports) {
@@ -877,39 +920,57 @@
 
             try {
                 EventLog.writeEvent(BACKUP_START_EVENT, mTransport.transportDirName());
+                int status = BackupConstants.TRANSPORT_OK;
+
+                // If we haven't stored anything yet, we need to do an init operation.
+                if (status == BackupConstants.TRANSPORT_OK && mEverStoredApps.size() == 0) {
+                    status = mTransport.initializeDevice();
+                }
 
                 // The package manager doesn't have a proper <application> etc, but since
                 // it's running here in the system process we can just set up its agent
                 // directly and use a synthetic BackupRequest.  We always run this pass
                 // because it's cheap and this way we guarantee that we don't get out of
                 // step even if we're selecting among various transports at run time.
-                PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
-                        mPackageManager, allAgentPackages());
-                BackupRequest pmRequest = new BackupRequest(new ApplicationInfo(), false);
-                pmRequest.appInfo.packageName = PACKAGE_MANAGER_SENTINEL;
-
-                // If we haven't stored anything yet, we need to do an init
-                // operation along with recording the metadata blob.
-                boolean needInit = (mEverStoredApps.size() == 0);
-                processOneBackup(pmRequest, IBackupAgent.Stub.asInterface(pmAgent.onBind()),
-                        mTransport, needInit);
-
-                // Now run all the backups in our queue
-                int count = mQueue.size();
-                doQueuedBackups(mTransport);
-
-                // Finally, tear down the transport
-                if (mTransport.finishBackup()) {
-                    int millis = (int) (SystemClock.elapsedRealtime() - startRealtime);
-                    EventLog.writeEvent(BACKUP_SUCCESS_EVENT, count, millis);
-                } else {
-                    EventLog.writeEvent(BACKUP_TRANSPORT_FAILURE_EVENT, "");
-                    Log.e(TAG, "Transport error in finishBackup()");
+                if (status == BackupConstants.TRANSPORT_OK) {
+                    PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
+                            mPackageManager, allAgentPackages());
+                    BackupRequest pmRequest = new BackupRequest(new ApplicationInfo(), false);
+                    pmRequest.appInfo.packageName = PACKAGE_MANAGER_SENTINEL;
+                    status = processOneBackup(pmRequest,
+                            IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
                 }
 
-                if (!mJournal.delete()) {
+                if (status == BackupConstants.TRANSPORT_OK) {
+                    // Now run all the backups in our queue
+                    status = doQueuedBackups(mTransport);
+                }
+
+                if (status == BackupConstants.TRANSPORT_OK) {
+                    // Tell the transport to finish everything it has buffered
+                    status = mTransport.finishBackup();
+                    if (status == BackupConstants.TRANSPORT_OK) {
+                        int millis = (int) (SystemClock.elapsedRealtime() - startRealtime);
+                        EventLog.writeEvent(BACKUP_SUCCESS_EVENT, mQueue.size(), millis);
+                    } else {
+                        EventLog.writeEvent(BACKUP_TRANSPORT_FAILURE_EVENT, "");
+                        Log.e(TAG, "Transport error in finishBackup()");
+                    }
+                }
+
+                // When we succeed at everything, we can remove the journal
+                if (status == BackupConstants.TRANSPORT_OK && !mJournal.delete()) {
                     Log.e(TAG, "Unable to remove backup journal file " + mJournal);
                 }
+
+                if (status == BackupConstants.TRANSPORT_NOT_INITIALIZED) {
+                    // The backend reports that our dataset has been wiped.  We need to
+                    // reset all of our bookkeeping and instead run a new backup pass for
+                    // everything.
+                    EventLog.writeEvent(BACKUP_RESET_EVENT, mTransport.transportDirName());
+                    resetBackupState(mStateDir);
+                    backupNow();
+                }
             } catch (Exception e) {
                 Log.e(TAG, "Error in backup thread", e);
             } finally {
@@ -918,7 +979,7 @@
             }
         }
 
-        private void doQueuedBackups(IBackupTransport transport) {
+        private int doQueuedBackups(IBackupTransport transport) {
             for (BackupRequest request : mQueue) {
                 Log.d(TAG, "starting agent for backup of " + request);
 
@@ -938,25 +999,26 @@
                 try {
                     agent = bindToAgentSynchronous(request.appInfo, mode);
                     if (agent != null) {
-                        processOneBackup(request, agent, transport, false);
+                        int result = processOneBackup(request, agent, transport);
+                        if (result != BackupConstants.TRANSPORT_OK) return result;
                     }
-
-                    // unbind even on timeout, just in case
-                    mActivityManager.unbindBackupAgent(request.appInfo);
                 } catch (SecurityException ex) {
                     // Try for the next one.
                     Log.d(TAG, "error in bind/backup", ex);
-                } catch (RemoteException e) {
-                    Log.v(TAG, "bind/backup threw");
-                    e.printStackTrace();
+                } finally {
+                    try {  // unbind even on timeout, just in case
+                        mActivityManager.unbindBackupAgent(request.appInfo);
+                    } catch (RemoteException e) {}
                 }
             }
+
+            return BackupConstants.TRANSPORT_OK;
         }
 
-        void processOneBackup(BackupRequest request, IBackupAgent agent,
-                IBackupTransport transport, boolean doInit) {
+        private int processOneBackup(BackupRequest request, IBackupAgent agent,
+                IBackupTransport transport) {
             final String packageName = request.appInfo.packageName;
-            if (DEBUG) Log.d(TAG, "processOneBackup doBackup(" + doInit + ") on " + packageName);
+            if (DEBUG) Log.d(TAG, "processOneBackup doBackup() on " + packageName);
 
             File savedStateName = new File(mStateDir, packageName);
             File backupDataName = new File(mDataDir, packageName + ".data");
@@ -1007,7 +1069,7 @@
                 EventLog.writeEvent(BACKUP_AGENT_FAILURE_EVENT, packageName, e.toString());
                 backupDataName.delete();
                 newStateName.delete();
-                return;
+                return BackupConstants.TRANSPORT_ERROR;
             } finally {
                 try { if (savedState != null) savedState.close(); } catch (IOException e) {}
                 try { if (backupData != null) backupData.close(); } catch (IOException e) {}
@@ -1016,20 +1078,23 @@
             }
 
             // Now propagate the newly-backed-up data to the transport
+            int result = BackupConstants.TRANSPORT_OK;
             try {
                 int size = (int) backupDataName.length();
                 if (size > 0) {
-                    backupData = ParcelFileDescriptor.open(backupDataName,
-                            ParcelFileDescriptor.MODE_READ_ONLY);
+                    if (result == BackupConstants.TRANSPORT_OK) {
+                        backupData = ParcelFileDescriptor.open(backupDataName,
+                                ParcelFileDescriptor.MODE_READ_ONLY);
+                        result = transport.performBackup(packInfo, backupData);
+                    }
 
                     // TODO - We call finishBackup() for each application backed up, because
                     // we need to know now whether it succeeded or failed.  Instead, we should
                     // hold off on finishBackup() until the end, which implies holding off on
                     // renaming *all* the output state files (see below) until that happens.
 
-                    if (!transport.performBackup(packInfo, backupData, doInit) ||
-                        !transport.finishBackup()) {
-                        throw new Exception("Backup transport failed");
+                    if (result == BackupConstants.TRANSPORT_OK) {
+                        result = transport.finishBackup();
                     }
                 } else {
                     if (DEBUG) Log.i(TAG, "no backup data written; not calling transport");
@@ -1038,16 +1103,22 @@
                 // After successful transport, delete the now-stale data
                 // and juggle the files so that next time we supply the agent
                 // with the new state file it just created.
-                backupDataName.delete();
-                newStateName.renameTo(savedStateName);
-                EventLog.writeEvent(BACKUP_PACKAGE_EVENT, packageName, size);
+                if (result == BackupConstants.TRANSPORT_OK) {
+                    backupDataName.delete();
+                    newStateName.renameTo(savedStateName);
+                    EventLog.writeEvent(BACKUP_PACKAGE_EVENT, packageName, size);
+                } else {
+                    EventLog.writeEvent(BACKUP_TRANSPORT_FAILURE_EVENT, packageName);
+                }
             } catch (Exception e) {
                 Log.e(TAG, "Transport error backing up " + packageName, e);
                 EventLog.writeEvent(BACKUP_TRANSPORT_FAILURE_EVENT, packageName);
-                return;
+                result = BackupConstants.TRANSPORT_ERROR;
             } finally {
                 try { if (backupData != null) backupData.close(); } catch (IOException e) {}
             }
+
+            return result;
         }
     }
 
@@ -1172,7 +1243,8 @@
                     }
                 }
 
-                if (!mTransport.startRestore(mToken, restorePackages.toArray(new PackageInfo[0]))) {
+                if (mTransport.startRestore(mToken, restorePackages.toArray(new PackageInfo[0])) !=
+                        BackupConstants.TRANSPORT_OK) {
                     Log.e(TAG, "Error starting restore operation");
                     EventLog.writeEvent(RESTORE_TRANSPORT_FAILURE_EVENT);
                     return;
@@ -1372,7 +1444,7 @@
                             ParcelFileDescriptor.MODE_CREATE |
                             ParcelFileDescriptor.MODE_TRUNCATE);
 
-                if (!mTransport.getRestoreData(backupData)) {
+                if (mTransport.getRestoreData(backupData) != BackupConstants.TRANSPORT_OK) {
                     Log.e(TAG, "Error getting restore data for " + packageName);
                     EventLog.writeEvent(RESTORE_TRANSPORT_FAILURE_EVENT);
                     return;
@@ -1590,7 +1662,6 @@
         if (DEBUG) Log.v(TAG, "Scheduling immediate backup pass");
         synchronized (mQueueLock) {
             try {
-                if (DEBUG) Log.v(TAG, "sending immediate backup broadcast");
                 mRunBackupIntent.send();
             } catch (PendingIntent.CanceledException e) {
                 // should never happen
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 656d6ba..b2e3a8c 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1862,9 +1862,10 @@
                 Log.d(TAG, "setKeyboardVisibility: " + visible);
             }
             mKeyboardVisible = visible;
-            // don't signal user activity when closing keyboard if the screen is off.
-            // otherwise, we want to make sure the backlights are adjusted.
-            if (visible || (mPowerState & SCREEN_ON_BIT) != 0) {
+            // don't signal user activity if the screen is off; other code
+            // will take care of turning on due to a true change to the lid
+            // switch and synchronized with the lock screen.
+            if ((mPowerState & SCREEN_ON_BIT) != 0) {
                 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
             }
         }
@@ -2130,7 +2131,9 @@
         long milliseconds = event.timestamp / 1000000;
         synchronized (mLocks) {
             float distance = event.values[0];
-            if (distance >= 0.0 && distance < PROXIMITY_THRESHOLD) {
+            // compare against getMaximumRange to support sensors that only return 0 or 1
+            if (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
+                    distance < mProximitySensor.getMaximumRange()) {
                 if (mSpew) {
                     Log.d(TAG, "onSensorChanged: proximity active, distance: " + distance);
                 }
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index bbf2a24..3c76cf2 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -372,7 +372,7 @@
     // perform or TRANSIT_NONE if we are not waiting.  If we are waiting,
     // mOpeningApps and mClosingApps are the lists of tokens that will be
     // made visible or hidden at the next transition.
-    int mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE;
+    int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
     boolean mAppTransitionReady = false;
     boolean mAppTransitionRunning = false;
     boolean mAppTransitionTimeout = false;
@@ -932,7 +932,7 @@
                             + " layer=" + highestTarget.mAnimLayer
                             + " new layer=" + w.mAnimLayer);
 
-                    if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+                    if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
                         // If we are currently setting up for an animation,
                         // hold everything until we can find out what will happen.
                         mInputMethodTargetWaitingAnim = true;
@@ -1270,7 +1270,7 @@
             }
         }
 
-        if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+        if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
             // If we are currently waiting for an app transition, and either
             // the current target or the next target are involved with it,
             // then hold off on doing anything with the wallpaper.
@@ -2542,7 +2542,7 @@
                                 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
                         break;
                 }
-                a = loadAnimation(lp, animAttr);
+                a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
                 if (DEBUG_ANIM) Log.v(TAG, "applyAnimation: wtoken=" + wtoken
                         + " anim=" + a
                         + " animAttr=0x" + Integer.toHexString(animAttr)
@@ -2990,7 +2990,8 @@
                     TAG, "Prepare app transition: transit=" + transit
                     + " mNextAppTransition=" + mNextAppTransition);
             if (!mDisplayFrozen) {
-                if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
+                if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
+                        || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
                     mNextAppTransition = transit;
                 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
                         && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
@@ -3025,7 +3026,7 @@
         synchronized(mWindowMap) {
             if (DEBUG_APP_TRANSITIONS) Log.v(
                     TAG, "Execute app transition: mNextAppTransition=" + mNextAppTransition);
-            if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+            if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
                 mAppTransitionReady = true;
                 final long origId = Binder.clearCallingIdentity();
                 performLayoutAndPlaceSurfacesLocked();
@@ -3228,7 +3229,7 @@
 
             boolean runningAppAnimation = false;
 
-            if (transit != WindowManagerPolicy.TRANSIT_NONE) {
+            if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
                 if (wtoken.animation == sDummyAnimation) {
                     wtoken.animation = null;
                 }
@@ -3328,7 +3329,7 @@
 
             // If we are preparing an app transition, then delay changing
             // the visibility of this token until we execute that transition.
-            if (!mDisplayFrozen && mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+            if (!mDisplayFrozen && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
                 // Already in requested state, don't do anything more.
                 if (wtoken.hiddenRequested != visible) {
                     return;
@@ -3367,7 +3368,7 @@
             }
 
             final long origId = Binder.clearCallingIdentity();
-            setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_NONE, true);
+            setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
             wtoken.updateReportedVisibilityLocked();
             Binder.restoreCallingIdentity(origId);
         }
@@ -3493,13 +3494,13 @@
             mTokenList.remove(basewtoken);
             if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
                 if (DEBUG_APP_TRANSITIONS) Log.v(TAG, "Removing app token: " + wtoken);
-                delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_NONE, true);
+                delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
                 wtoken.inPendingTransaction = false;
                 mOpeningApps.remove(wtoken);
                 wtoken.waitingToShow = false;
                 if (mClosingApps.contains(wtoken)) {
                     delayed = true;
-                } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+                } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
                     mClosingApps.add(wtoken);
                     wtoken.waitingToHide = true;
                     delayed = true;
@@ -3781,7 +3782,7 @@
                 AppWindowToken wt = findAppWindowToken(tokens.get(i));
                 if (wt != null) {
                     mAppTokens.add(wt);
-                    if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+                    if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
                         mToTopApps.remove(wt);
                         mToBottomApps.remove(wt);
                         mToTopApps.add(wt);
@@ -3791,7 +3792,7 @@
                 }
             }
             
-            if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
+            if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
                 moveAppWindowsLocked(tokens, mAppTokens.size());
             }
         }
@@ -3813,7 +3814,7 @@
                 AppWindowToken wt = findAppWindowToken(tokens.get(i));
                 if (wt != null) {
                     mAppTokens.add(pos, wt);
-                    if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+                    if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
                         mToTopApps.remove(wt);
                         mToBottomApps.remove(wt);
                         mToBottomApps.add(i, wt);
@@ -3824,7 +3825,7 @@
                 }
             }
             
-            if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
+            if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
                 moveAppWindowsLocked(tokens, 0);
             }
         }
@@ -7459,7 +7460,7 @@
          */
         boolean isReadyForDisplay() {
             if (mRootToken.waitingToShow &&
-                    mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+                    mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
                 return false;
             }
             final AppWindowToken atoken = mAppToken;
@@ -8530,7 +8531,7 @@
 
                 case APP_TRANSITION_TIMEOUT: {
                     synchronized (mWindowMap) {
-                        if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+                        if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
                             if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
                                     "*** APP TRANSITION TIMEOUT");
                             mAppTransitionReady = true;
@@ -9074,9 +9075,9 @@
                         if (DEBUG_APP_TRANSITIONS) Log.v(TAG, "**** GOOD TO GO");
                         int transit = mNextAppTransition;
                         if (mSkipAppTransitionAnimation) {
-                            transit = WindowManagerPolicy.TRANSIT_NONE;
+                            transit = WindowManagerPolicy.TRANSIT_UNSET;
                         }
-                        mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE;
+                        mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
                         mAppTransitionReady = false;
                         mAppTransitionRunning = true;
                         mAppTransitionTimeout = false;
@@ -10092,8 +10093,8 @@
         }
 
         mDisplayFrozen = true;
-        if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
-            mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE;
+        if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
+            mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
             mAppTransitionReady = true;
         }
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d4f7207e..82664eb 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -458,6 +458,13 @@
             = new ArrayList<HistoryRecord>();
 
     /**
+     * Animations that for the current transition have requested not to
+     * be considered for the transition animation.
+     */
+    final ArrayList<HistoryRecord> mNoAnimActivities
+            = new ArrayList<HistoryRecord>();
+    
+    /**
      * List of intents that were used to start the most recent tasks.
      */
     final ArrayList<TaskRecord> mRecentTasks
@@ -2249,6 +2256,7 @@
         next.resumeKeyDispatchingLocked();
         ensureActivitiesVisibleLocked(null, 0);
         mWindowManager.executeAppTransition();
+        mNoAnimActivities.clear();
 
         // Mark the point when the activity is resuming
         // TODO: To be more accurate, the mark should be before the onCreate,
@@ -2565,6 +2573,7 @@
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
             mWindowManager.executeAppTransition();
+            mNoAnimActivities.clear();
             return false;
         }
 
@@ -2575,6 +2584,7 @@
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
             mWindowManager.executeAppTransition();
+            mNoAnimActivities.clear();
             return false;
         }
         
@@ -2637,17 +2647,25 @@
             if (prev.finishing) {
                 if (DEBUG_TRANSITION) Log.v(TAG,
                         "Prepare close transition: prev=" + prev);
-                mWindowManager.prepareAppTransition(prev.task == next.task
-                        ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
-                        : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
+                if (mNoAnimActivities.contains(prev)) {
+                    mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+                } else {
+                    mWindowManager.prepareAppTransition(prev.task == next.task
+                            ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
+                            : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
+                }
                 mWindowManager.setAppWillBeHidden(prev);
                 mWindowManager.setAppVisibility(prev, false);
             } else {
                 if (DEBUG_TRANSITION) Log.v(TAG,
                         "Prepare open transition: prev=" + prev);
-                mWindowManager.prepareAppTransition(prev.task == next.task
-                        ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
-                        : WindowManagerPolicy.TRANSIT_TASK_OPEN);
+                if (mNoAnimActivities.contains(next)) {
+                    mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+                } else {
+                    mWindowManager.prepareAppTransition(prev.task == next.task
+                            ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
+                            : WindowManagerPolicy.TRANSIT_TASK_OPEN);
+                }
             }
             if (false) {
                 mWindowManager.setAppWillBeHidden(prev);
@@ -2656,7 +2674,11 @@
         } else if (mHistory.size() > 1) {
             if (DEBUG_TRANSITION) Log.v(TAG,
                     "Prepare open transition: no previous");
-            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
+            if (mNoAnimActivities.contains(next)) {
+                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+            } else {
+                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
+            }
         }
 
         if (next.app != null && next.app.thread != null) {
@@ -2699,6 +2721,7 @@
                     mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
                 }
                 mWindowManager.executeAppTransition();
+                mNoAnimActivities.clear();
                 return true;
             }
             
@@ -2859,9 +2882,18 @@
             }
             if (DEBUG_TRANSITION) Log.v(TAG,
                     "Prepare open transition: starting " + r);
-            mWindowManager.prepareAppTransition(newTask
-                    ? WindowManagerPolicy.TRANSIT_TASK_OPEN
-                    : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
+            if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
+                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+                mNoAnimActivities.add(r);
+            } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
+                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN);
+                mNoAnimActivities.remove(r);
+            } else {
+                mWindowManager.prepareAppTransition(newTask
+                        ? WindowManagerPolicy.TRANSIT_TASK_OPEN
+                        : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
+                mNoAnimActivities.remove(r);
+            }
             mWindowManager.addAppToken(
                     addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
             boolean doShow = true;
@@ -3336,7 +3368,7 @@
                         if (callerAtFront) {
                             // We really do want to push this one into the
                             // user's face, right now.
-                            moveTaskToFrontLocked(taskTop.task);
+                            moveTaskToFrontLocked(taskTop.task, r);
                         }
                     }
                     // If the caller has requested that the target task be
@@ -6922,14 +6954,14 @@
                 for (int i=0; i<N; i++) {
                     TaskRecord tr = mRecentTasks.get(i);
                     if (tr.taskId == task) {
-                        moveTaskToFrontLocked(tr);
+                        moveTaskToFrontLocked(tr, null);
                         return;
                     }
                 }
                 for (int i=mHistory.size()-1; i>=0; i--) {
                     HistoryRecord hr = (HistoryRecord)mHistory.get(i);
                     if (hr.task.taskId == task) {
-                        moveTaskToFrontLocked(hr.task);
+                        moveTaskToFrontLocked(hr.task, null);
                         return;
                     }
                 }
@@ -6939,7 +6971,7 @@
         }
     }
 
-    private final void moveTaskToFrontLocked(TaskRecord tr) {
+    private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) {
         if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr);
 
         final int task = tr.taskId;
@@ -6950,10 +6982,6 @@
             return;
         }
 
-        if (DEBUG_TRANSITION) Log.v(TAG,
-                "Prepare to front transition: task=" + tr);
-        mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
-        
         ArrayList moved = new ArrayList();
 
         // Applying the affinities may have removed entries from the history,
@@ -6982,6 +7010,19 @@
             pos--;
         }
 
+        if (DEBUG_TRANSITION) Log.v(TAG,
+                "Prepare to front transition: task=" + tr);
+        if (reason != null &&
+                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
+            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+            HistoryRecord r = topRunningActivityLocked(null);
+            if (r != null) {
+                mNoAnimActivities.add(r);
+            }
+        } else {
+            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
+        }
+        
         mWindowManager.moveAppTokensToTop(moved);
         if (VALIDATE_TOKENS) {
             mWindowManager.validateAppTokens(mHistory);
@@ -7007,7 +7048,7 @@
                 }
             }
             final long origId = Binder.clearCallingIdentity();
-            moveTaskToBackLocked(task);
+            moveTaskToBackLocked(task, null);
             Binder.restoreCallingIdentity(origId);
         }
     }
@@ -7026,7 +7067,7 @@
             final long origId = Binder.clearCallingIdentity();
             int taskId = getTaskForActivityLocked(token, !nonRoot);
             if (taskId >= 0) {
-                return moveTaskToBackLocked(taskId);
+                return moveTaskToBackLocked(taskId, null);
             }
             Binder.restoreCallingIdentity(origId);
         }
@@ -7044,7 +7085,7 @@
      * @param task The taskId to collect and move to the bottom.
      * @return Returns true if the move completed, false if not.
      */
-    private final boolean moveTaskToBackLocked(int task) {
+    private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) {
         Log.i(TAG, "moveTaskToBack: " + task);
         
         // If we have a watcher, preflight the move before committing to it.  First check
@@ -7095,6 +7136,16 @@
             pos++;
         }
 
+        if (reason != null &&
+                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
+            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+            HistoryRecord r = topRunningActivityLocked(null);
+            if (r != null) {
+                mNoAnimActivities.add(r);
+            }
+        } else {
+            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
+        }
         mWindowManager.moveAppTokensToBottom(moved);
         if (VALIDATE_TOKENS) {
             mWindowManager.validateAppTokens(mHistory);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 9ac78eb..a410f0e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -538,12 +538,15 @@
                 if (!mPendingRadioPowerOffAfterDataOff) {
                     DataConnectionTracker.State currentState = dcTracker.getState();
                     if (currentState != DataConnectionTracker.State.CONNECTED
-                            && currentState != DataConnectionTracker.State.DISCONNECTING) {
+                            && currentState != DataConnectionTracker.State.DISCONNECTING
+                            && currentState != DataConnectionTracker.State.INITING) {
                         if (DBG) log("Data disconnected, turn off radio right away.");
                         cm.setRadioPower(false, null);
                     }
-                    else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 5000)) {
-                        if (DBG) log("Wait 5 sec for data to be disconnected, then turn off radio.");
+                    else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
+                        if (DBG) {
+                            log("Wait up to 30 sec for data to disconnect, then turn off radio.");
+                        }
                         mPendingRadioPowerOffAfterDataOff = true;
                     } else {
                         Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
diff --git a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java
index 74ac865f..861e37b 100644
--- a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java
+++ b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java
@@ -12,7 +12,8 @@
 
     private static final String LOGTAG = "PowerMeasurement";
     private static final String PKG_NAME = "com.android.browserpowertest";
-    private static final String TESTING_URL = "http://www.espn.com";
+    private static final String TESTING_URL =
+        "http://75.17.48.204:10088/nyt/index.html";
     private static final int TIME_OUT = 2 * 60 * 1000;
     private static final int DELAY = 0;
 
@@ -46,6 +47,24 @@
                 pageErrorFlag);
         Log.v(LOGTAG, "Page is loaded in " + activity.getPageLoadTime() + " ms.");
 
+        // Force to clean up the cache dir so that it get back to the clean
+        // state
+        Runtime fileRemoval = Runtime.getRuntime();
+        String cmdBecomeSu = "su";
+        boolean clearCacheSuccess = false;
+        try{
+            Process runsum = fileRemoval.exec(cmdBecomeSu);
+            int exitVal = runsum.waitFor();
+            String rmfile = "rm -r /data/data/com.android.browserpowertest/cache";
+            Process removal = fileRemoval.exec(rmfile);
+            exitVal = removal.waitFor();
+            if (exitVal == 0) {
+                clearCacheSuccess = true;
+            }
+        } catch ( Exception e){
+            assertTrue("Fails to clear the cahche", false);   
+        }
+        assertTrue("Fails to clear the cahche", clearCacheSuccess);
         activity.finish();
     }
 }
diff --git a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
index 7426d33..20ea4d7 100644
--- a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -257,19 +257,19 @@
 
     @SmallTest
     public void testToCallerIDIndexable() throws Exception {
-        assertEquals("14145", PhoneNumberUtils.toCallerIDMinMatch("17005554141"));
-        assertEquals("14145", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141"));
-        assertEquals("14145", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234"));
-        assertEquals("14145", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234"));
+        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("17005554141"));
+        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141"));
+        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234"));
+        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234"));
 
         //this seems wrong, or at least useless
-        assertEquals("NN145", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN"));
+        assertEquals("NN14555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN"));
 
         //<shrug> -- these are all not useful, but not terribly wrong
         assertEquals("", PhoneNumberUtils.toCallerIDMinMatch(""));
         assertEquals("0032", PhoneNumberUtils.toCallerIDMinMatch("2300"));
         assertEquals("0032+", PhoneNumberUtils.toCallerIDMinMatch("+2300"));
-        assertEquals("#130#", PhoneNumberUtils.toCallerIDMinMatch("*#031#"));
+        assertEquals("#130#*", PhoneNumberUtils.toCallerIDMinMatch("*#031#"));
     }
 
     @SmallTest
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 954930e..01bc919 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -71,7 +71,7 @@
     /** {@hide} */
     public EnterpriseField phase2 = new EnterpriseField("phase2");
     /** {@hide} */
-    public EnterpriseField identity = new EnterpriseField("anonymous_identity");
+    public EnterpriseField identity = new EnterpriseField("identity");
     /** {@hide} */
     public EnterpriseField anonymous_identity = new EnterpriseField("anonymous_identity");
     /** {@hide} */
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index e3d8bf4..5638480 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -907,6 +907,7 @@
                             }
                         }
                     } else if (newState == SupplicantState.DISCONNECTED) {
+                        mHaveIpAddress = false;
                         if (isDriverStopped() || mDisconnectExpected) {
                             handleDisconnectedState(DetailedState.DISCONNECTED);
                         } else {
@@ -1007,20 +1008,17 @@
                     setNotificationVisible(false, 0, false, 0);
                     boolean wasDisconnectPending = mDisconnectPending;
                     cancelDisconnect();
-                    if (!TextUtils.equals(mWifiInfo.getSSID(), mLastSsid)) {
-                        /*
-                         * The connection is fully configured as far as link-level
-                         * connectivity is concerned, but we may still need to obtain
-                         * an IP address. But do this only if we are connecting to
-                         * a different network than we were connected to previously.
-                         */
-                        if (wasDisconnectPending) {
-                            DetailedState saveState = getNetworkInfo().getDetailedState();
-                            handleDisconnectedState(DetailedState.DISCONNECTED);
-                            setDetailedStateInternal(saveState);
-                        }
-                        configureInterface();
+                    /*
+                     * The connection is fully configured as far as link-level
+                     * connectivity is concerned, but we may still need to obtain
+                     * an IP address.
+                     */
+                    if (wasDisconnectPending) {
+                        DetailedState saveState = getNetworkInfo().getDetailedState();
+                        handleDisconnectedState(DetailedState.DISCONNECTED);
+                        setDetailedStateInternal(saveState);
                     }
+                    configureInterface();
                     mLastBssid = result.BSSID;
                     mLastSsid = mWifiInfo.getSSID();
                     mLastNetworkId = result.networkId;