Merge change I27009b08 into eclair

* changes:
  Fix EVDO SNR signal bar calculation
diff --git a/Android.mk b/Android.mk
index 90f2acb..1428454 100644
--- a/Android.mk
+++ b/Android.mk
@@ -216,6 +216,7 @@
 	frameworks/base/core/java/android/net/Uri.aidl \
 	frameworks/base/core/java/android/os/Bundle.aidl \
 	frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \
+	frameworks/base/core/java/android/os/ParcelUuid.aidl \
 	frameworks/base/core/java/android/view/KeyEvent.aidl \
 	frameworks/base/core/java/android/view/MotionEvent.aidl \
 	frameworks/base/core/java/android/view/Surface.aidl \
diff --git a/api/current.xml b/api/current.xml
index d8ab697..d063ada 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3485,6 +3485,17 @@
  visibility="public"
 >
 </field>
+<field name="fadeScrollbars"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843434"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="fadingEdge"
  type="int"
  transient="false"
@@ -6763,6 +6774,28 @@
  visibility="public"
 >
 </field>
+<field name="scrollbarDefaultDelayBeforeFade"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843433"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="scrollbarFadeDuration"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843432"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="scrollbarSize"
  type="int"
  transient="false"
@@ -26029,6 +26062,17 @@
  visibility="public"
 >
 </field>
+<field name="ACTION_REQUEST_ENABLE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.adapter.action.REQUEST_ENABLE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="ACTION_SCAN_MODE_CHANGED"
  type="java.lang.String"
  transient="false"
@@ -27528,87 +27572,6 @@
 >
 </method>
 </class>
-<class name="ParcelUuid"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="android.os.Parcelable">
-</implements>
-<constructor name="ParcelUuid"
- type="android.bluetooth.ParcelUuid"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="uuid" type="java.util.UUID">
-</parameter>
-</constructor>
-<method name="describeContents"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="fromString"
- return="android.bluetooth.ParcelUuid"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="uuid" type="java.lang.String">
-</parameter>
-</method>
-<method name="getUuid"
- return="java.util.UUID"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="writeToParcel"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="dest" type="android.os.Parcel">
-</parameter>
-<parameter name="flags" type="int">
-</parameter>
-</method>
-<field name="CREATOR"
- type="android.os.Parcelable.Creator"
- transient="false"
- volatile="false"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
 </package>
 <package name="android.content"
 >
@@ -105536,6 +105499,87 @@
 </parameter>
 </constructor>
 </class>
+<class name="ParcelUuid"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<constructor name="ParcelUuid"
+ type="android.os.ParcelUuid"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uuid" type="java.util.UUID">
+</parameter>
+</constructor>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="fromString"
+ return="android.os.ParcelUuid"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uuid" type="java.lang.String">
+</parameter>
+</method>
+<method name="getUuid"
+ return="java.util.UUID"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
 <interface name="Parcelable"
  abstract="true"
  static="false"
@@ -113883,6 +113927,17 @@
  visibility="public"
 >
 </field>
+<field name="OFFICE_LOCATION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;data9&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="PHONETIC_NAME"
  type="java.lang.String"
  transient="false"
@@ -115053,6 +115108,27 @@
  visibility="public"
 >
 </field>
+<field name="CONTENT_VCARD_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;text/x-vcard&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CONTENT_VCARD_URI"
+ type="android.net.Uri"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="ContactsContract.Contacts.AggregationSuggestions"
  extends="java.lang.Object"
@@ -155242,6 +155318,30 @@
 <parameter name="views" type="java.util.ArrayList&lt;android.view.View&gt;">
 </parameter>
 </method>
+<method name="awakenScrollBars"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="awakenScrollBars"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="startDelay" type="int">
+</parameter>
+</method>
 <method name="bringToFront"
  return="void"
  abstract="false"
@@ -156891,6 +156991,17 @@
  visibility="public"
 >
 </method>
+<method name="isScrollbarFadingEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isSelected"
  return="boolean"
  abstract="false"
@@ -158343,6 +158454,19 @@
 <parameter name="isScrollContainer" type="boolean">
 </parameter>
 </method>
+<method name="setScrollbarFadingEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fadeScrollbars" type="boolean">
+</parameter>
+</method>
 <method name="setSelected"
  return="void"
  abstract="false"
@@ -159676,6 +159800,17 @@
  visibility="public"
 >
 </method>
+<method name="getScrollBarFadeDuration"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getScrollBarSize"
  return="int"
  abstract="false"
@@ -159687,6 +159822,17 @@
  visibility="public"
 >
 </method>
+<method name="getScrollDefaultDelay"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getScrollFriction"
  return="float"
  abstract="false"
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 68be2e8..1e9d5a1 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -1709,14 +1709,17 @@
         public boolean dispatchKeyEventPreIme(KeyEvent event) {
             if (DBG) Log.d(LOG_TAG, "onKeyPreIme(" + event + ")");
             if (mSearchDialog != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
-                if (event.getAction() == KeyEvent.ACTION_DOWN
-                        && event.getRepeatCount() == 0) {
-                    getKeyDispatcherState().startTracking(event, this);
-                    return true;
-                } else if (event.getAction() == KeyEvent.ACTION_UP
-                        && !event.isCanceled() && getKeyDispatcherState().isTracking(event)) {
-                    mSearchDialog.onBackPressed();
-                    return true;
+                KeyEvent.DispatcherState state = getKeyDispatcherState();
+                if (state != null) {
+                    if (event.getAction() == KeyEvent.ACTION_DOWN
+                            && event.getRepeatCount() == 0) {
+                        state.startTracking(event, this);
+                        return true;
+                    } else if (event.getAction() == KeyEvent.ACTION_UP
+                            && !event.isCanceled() && state.isTracking(event)) {
+                        mSearchDialog.onBackPressed();
+                        return true;
+                    }
                 }
             }
             return super.dispatchKeyEventPreIme(event);
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index f0876f4..9851750 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -27,9 +27,9 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.server.search.SearchableInfo;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
-import android.text.TextUtils;
 
 import java.util.List;
 
@@ -1591,6 +1591,13 @@
     public final static String SUGGEST_NEVER_MAKE_SHORTCUT = "_-1";
 
     /**
+     * Query parameter added to suggestion queries to limit the number of suggestions returned.
+     *
+     * @hide Pending API council approval
+     */
+    public final static String SUGGEST_PARAMETER_LIMIT = "limit";
+
+    /**
      * If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION},
      * the search dialog will switch to a different suggestion source when the
      * suggestion is clicked. 
@@ -1980,6 +1987,21 @@
      * @hide because SearchableInfo is not part of the API.
      */
     public Cursor getSuggestions(SearchableInfo searchable, String query) {
+        return getSuggestions(searchable, query, -1);
+    }
+
+    /**
+     * Gets a cursor with search suggestions.
+     *
+     * @param searchable Information about how to get the suggestions.
+     * @param query The search text entered (so far).
+     * @param limit The query limit to pass to the suggestion provider. This is advisory,
+     *        the returned cursor may contain more rows. Pass {@code -1} for no limit.
+     * @return a cursor with suggestions, or <code>null</null> the suggestion query failed.
+     *
+     * @hide because SearchableInfo is not part of the API.
+     */
+    public Cursor getSuggestions(SearchableInfo searchable, String query, int limit) {
         if (searchable == null) {
             return null;
         }
@@ -1991,7 +2013,9 @@
 
         Uri.Builder uriBuilder = new Uri.Builder()
                 .scheme(ContentResolver.SCHEME_CONTENT)
-                .authority(authority);
+                .authority(authority)
+                .query("")  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
+                .fragment("");  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
 
         // if content path provided, insert it now
         final String contentPath = searchable.getSuggestPath();
@@ -1999,7 +2023,7 @@
             uriBuilder.appendEncodedPath(contentPath);
         }
 
-        // append standard suggestion query path 
+        // append standard suggestion query path
         uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);
 
         // get the query selection, may be null
@@ -2012,10 +2036,11 @@
             uriBuilder.appendPath(query);
         }
 
-        Uri uri = uriBuilder
-                .query("")     // TODO: Remove, workaround for a bug in Uri.writeToParcel()
-                .fragment("")  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
-                .build();
+        if (limit > 0) {
+            uriBuilder.appendQueryParameter(SUGGEST_PARAMETER_LIMIT, String.valueOf(limit));
+        }
+
+        Uri uri = uriBuilder.build();
 
         // finally, make the query
         return mContext.getContentResolver().query(uri, null, selection, selArgs, null);
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index 9234a9c..12be97c 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -58,6 +58,7 @@
 
     private static final boolean DBG = false;
     private static final String LOG_TAG = "SuggestionsAdapter";
+    private static final int QUERY_LIMIT = 50;
 
     private SearchManager mSearchManager;
     private SearchDialog mSearchDialog;
@@ -186,7 +187,7 @@
             mSearchDialog.getWindow().getDecorView().post(mStartSpinnerRunnable);
         }
         try {
-            final Cursor cursor = mSearchManager.getSuggestions(mSearchable, query);
+            final Cursor cursor = mSearchManager.getSuggestions(mSearchable, query, QUERY_LIMIT);
             // trigger fill window so the spinner stays up until the results are copied over and
             // closer to being ready
             if (!mGlobalSearchMode && cursor != null) cursor.getCount();
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 3aaed38..e3ec2cc 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -105,6 +106,8 @@
 
     /**
      * Activity Action: Show a system activity that requests discoverable mode.
+     * <p>This activity will also request the user to turn on Bluetooth if it
+     * is not currently enabled.
      * <p>Discoverable mode is equivalent to {@link
      * #SCAN_MODE_CONNECTABLE_DISCOVERABLE}. It allows remote devices to see
      * this Bluetooth adapter when they perform a discovery.
@@ -120,7 +123,7 @@
      * value if the user rejected discoverability.
      * <p>Applications can also listen for {@link #ACTION_SCAN_MODE_CHANGED}
      * for global notification whenever the scan mode changes.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_REQUEST_DISCOVERABLE =
@@ -136,6 +139,24 @@
             "android.bluetooth.adapter.extra.DISCOVERABLE_DURATION";
 
     /**
+     * Activity Action: Show a system activity that allows the user to turn on
+     * Bluetooth.
+     * <p>This system activity will return once Bluetooth has completed turning
+     * on, or the user has decided not to turn Bluetooth on.
+     * <p>Notification of the result of this activity is posted using the
+     * {@link android.app.Activity#onActivityResult} callback. The
+     * <code>resultCode</code>
+     * will be negative if the user did not turn on Bluetooth, and non-negative
+     * if Bluetooth has been turned on.
+     * <p>Applications can also listen for {@link #ACTION_STATE_CHANGED}
+     * for global notification whenever Bluetooth is turned on or off.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_REQUEST_ENABLE =
+            "android.bluetooth.adapter.action.REQUEST_ENABLE";
+
+    /**
      * Broadcast Action: Indicates the Bluetooth scan mode of the local Adapter
      * has changed.
      * <p>Always contains the extra fields {@link #EXTRA_SCAN_MODE} and {@link
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index c714f69..d5393ed 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -22,6 +22,7 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
@@ -228,9 +229,9 @@
 
     /**
      * Broadcast Action: This intent is used to broadcast the {@link UUID}
-     * wrapped as a {@link ParcelUuid} of the remote device after it has been
-     * fetched. This intent is sent only when the UUIDs of the remote device
-     * are requested to be fetched using Service Discovery Protocol
+     * wrapped as a {@link android.os.ParcelUuid} of the remote device after it
+     * has been fetched. This intent is sent only when the UUIDs of the remote
+     * device are requested to be fetched using Service Discovery Protocol
      * <p> Always contains the extra field {@link #EXTRA_DEVICE}
      * <p> Always contains the extra filed {@link #EXTRA_UUID}
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
@@ -309,8 +310,8 @@
 
     /**
      * Used as an extra field in {@link #ACTION_UUID} intents,
-     * Contains the {@link ParcelUuid}s of the remote device which is a parcelable
-     * version of {@link UUID}.
+     * Contains the {@link android.os.ParcelUuid}s of the remote device which
+     * is a parcelable version of {@link UUID}.
      * @hide
      */
     public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 24ad06a..da0564a 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -16,6 +16,8 @@
 
 package android.bluetooth;
 
+import android.os.ParcelUuid;
+
 import java.util.Arrays;
 import java.util.HashSet;
 
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 1bc2f96..2f77ba4 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -16,7 +16,7 @@
 
 package android.bluetooth;
 
-import android.bluetooth.ParcelUuid;
+import android.os.ParcelUuid;
 
 /**
  * System private API for talking with the Bluetooth service.
diff --git a/core/java/android/bluetooth/ParcelUuid.aidl b/core/java/android/os/ParcelUuid.aidl
similarity index 95%
rename from core/java/android/bluetooth/ParcelUuid.aidl
rename to core/java/android/os/ParcelUuid.aidl
index 70bcc4b..f7e080a 100644
--- a/core/java/android/bluetooth/ParcelUuid.aidl
+++ b/core/java/android/os/ParcelUuid.aidl
@@ -14,6 +14,6 @@
 ** limitations under the License.
 */
 
-package android.bluetooth;
+package android.os;
 
 parcelable ParcelUuid;
diff --git a/core/java/android/bluetooth/ParcelUuid.java b/core/java/android/os/ParcelUuid.java
similarity index 97%
rename from core/java/android/bluetooth/ParcelUuid.java
rename to core/java/android/os/ParcelUuid.java
index 27166a0..88fcfc5 100644
--- a/core/java/android/bluetooth/ParcelUuid.java
+++ b/core/java/android/os/ParcelUuid.java
@@ -14,10 +14,7 @@
  * limitations under the License.
  */
 
-package android.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
+package android.os;
 
 import java.util.UUID;
 
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index e01bd3c..40b4fc4 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -23,6 +23,7 @@
 import android.content.Entity.NamedContentValues;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteException;
+import android.net.Uri;
 import android.os.RemoteException;
 import android.provider.CallLog;
 import android.provider.CallLog.Calls;
@@ -81,7 +82,7 @@
 public class VCardComposer {
     private static final String LOG_TAG = "vcard.VCardComposer";
 
-    private final static String DEFAULT_EMAIL_TYPE = Constants.ATTR_TYPE_INTERNET;
+    private static final String DEFAULT_EMAIL_TYPE = Constants.ATTR_TYPE_INTERNET;
 
     public static final String FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO =
         "Failed to get database information";
@@ -94,6 +95,14 @@
 
     public static final String NO_ERROR = "No error";
 
+    private static final Uri sDataRequestUri;
+
+    static {
+        Uri.Builder builder = RawContacts.CONTENT_URI.buildUpon();
+        builder.appendQueryParameter(Data.FOR_EXPORT_ONLY, "1");
+        sDataRequestUri = builder.build();
+    }
+
     public static interface OneEntryHandler {
         public boolean onInit(Context context);
 
@@ -116,7 +125,7 @@
         @SuppressWarnings("hiding")
         private static final String LOG_TAG = "vcard.VCardComposer.HandlerForOutputStream";
 
-        private OutputStream mOutputStream; // mWriter will close this.
+        final private OutputStream mOutputStream; // mWriter will close this.
         private Writer mWriter;
 
         private boolean mOnTerminateIsCalled = false;
@@ -301,8 +310,8 @@
 
     private boolean mIsCallLogComposer = false;
 
-    private static final String[] sRawContactsProjection = new String[] {
-        RawContacts._ID,
+    private static final String[] sContactsProjection = new String[] {
+        Contacts._ID,
     };
 
     /** The projection to use when querying the call log table */
@@ -442,7 +451,7 @@
             mCursor = mContentResolver.query(CallLog.Calls.CONTENT_URI, sCallLogProjection,
                     selection, selectionArgs, null);
         } else {
-            mCursor = mContentResolver.query(RawContacts.CONTENT_URI, sRawContactsProjection,
+            mCursor = mContentResolver.query(Contacts.CONTENT_URI, sContactsProjection,
                     selection, selectionArgs, null);
         }
 
@@ -451,7 +460,7 @@
             return false;
         }
 
-        if (mCursor.getCount() == 0 || !mCursor.moveToFirst()) {
+        if (getCount() == 0 || !mCursor.moveToFirst()) {
             try {
                 mCursor.close();
             } catch (SQLiteException e) {
@@ -604,23 +613,19 @@
     }
 
     private String createOneEntryInternal(final String contactId) {
-        final StringBuilder builder = new StringBuilder();
-        appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD);
-        if (mIsV30) {
-            appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V30);
-        } else {
-            appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V21);
-        }
-
         final Map<String, List<ContentValues>> contentValuesListMap =
-            new HashMap<String, List<ContentValues>>();
-
-        final String selection = Data.RAW_CONTACT_ID + "=?";
+                new HashMap<String, List<ContentValues>>();
+        final String selection = Data.CONTACT_ID + "=?";
         final String[] selectionArgs = new String[] {contactId};
+        // The resolver may return the entity iterator with no data. It is possiible.
+        // e.g. If all the data in the contact of the given contact id are not exportable ones,
+        //      they are hidden from the view of this method, though contact id itself exists.
+        boolean dataExists = false;
         EntityIterator entityIterator = null;
         try {
             entityIterator = mContentResolver.queryEntities(
-                    RawContacts.CONTENT_URI, selection, selectionArgs, null);
+                    sDataRequestUri, selection, selectionArgs, null);
+            dataExists = entityIterator.hasNext();
             while (entityIterator.hasNext()) {
                 Entity entity = entityIterator.next();
                 for (NamedContentValues namedContentValues : entity
@@ -648,7 +653,18 @@
             }
         }
 
-        // TODO: consolidate order? (low priority)
+        if (!dataExists) {
+            return "";
+        }
+
+        final StringBuilder builder = new StringBuilder();
+        appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD);
+        if (mIsV30) {
+            appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V30);
+        } else {
+            appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V21);
+        }
+
         appendStructuredNames(builder, contentValuesListMap);
         appendNickNames(builder, contentValuesListMap);
         appendPhones(builder, contentValuesListMap);
@@ -660,7 +676,7 @@
         appendOrganizations(builder, contentValuesListMap);
         appendPhotos(builder, contentValuesListMap);
         appendNotes(builder, contentValuesListMap);
-        // TODO: GroupMembership... What?
+        // TODO: GroupMembership
 
         if (mIsDoCoMo) {
             appendVCardLine(builder, VCARD_PROPERTY_X_CLASS, VCARD_DATA_PUBLIC);
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index b54ad5d..7854423 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -16,16 +16,14 @@
 
 package android.provider;
 
+import com.android.internal.telephony.CallerInfo;
+import com.android.internal.telephony.Connection;
+
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.net.Uri;
-import android.provider.Contacts.People;
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.Connection;
-
 import android.text.TextUtils;
-import android.util.Log;
 
 /**
  * The CallLog provider contains information about placed and received calls.
@@ -179,7 +177,7 @@
             }
             
             if ((ci != null) && (ci.person_id > 0)) {
-                People.markAsContacted(resolver, ci.person_id);
+                ContactsContract.Contacts.markAsContacted(resolver, ci.person_id);
             }
             
             Uri result = resolver.insert(CONTENT_URI, values);
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index c7bce0f..1b13f52 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -318,6 +318,17 @@
                 "lookup");
 
         /**
+         * Base {@link Uri} for referencing a single {@link Contacts} entry,
+         * created by appending {@link #LOOKUP_KEY} using
+         * {@link Uri#withAppendedPath(Uri, String)}. Provides
+         * {@link OpenableColumns} columns when queried, or returns the
+         * referenced contact formatted as a vCard when opened through
+         * {@link ContentResolver#openAssetFileDescriptor(Uri, String)}.
+         */
+        public static final Uri CONTENT_VCARD_URI = Uri.withAppendedPath(CONTENT_URI,
+                "as_vcard");
+
+        /**
          * Builds a {@link #CONTENT_LOOKUP_URI} style {@link Uri} describing the
          * requested {@link Contacts} entry.
          *
@@ -435,6 +446,12 @@
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact";
 
         /**
+         * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
+         * person.
+         */
+        public static final String CONTENT_VCARD_TYPE = "text/x-vcard";
+
+        /**
          * A sub-directory of a single contact that contains all of the constituent raw contact
          * {@link Data} rows.
          */
@@ -805,6 +822,22 @@
         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/data";
 
         /**
+         * If {@link #FOR_EXPORT_ONLY} is explicitly set to "1", returned Cursor toward
+         * Data.CONTENT_URI contains only exportable data.
+         *
+         * This flag is useful (currently) only for vCard exporter in Contacts app, which
+         * needs to exclude "un-exportable" data from available data to export, while
+         * Contacts app itself has priviledge to access all data including "un-expotable"
+         * ones and providers return all of them regardless of the callers' intention.
+         * <P>Type: INTEGER</p>
+         *
+         * @hide Maybe available only in Eclair and not really ready for public use.
+         * TODO: remove, or implement this feature completely. As of now (Eclair),
+         * we only use this flag in queryEntities(), not query().
+         */
+        public static final String FOR_EXPORT_ONLY = "for_export_only";
+
+        /**
          * Build a {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}
          * style {@link Uri} for the parent {@link android.provider.ContactsContract.Contacts}
          * entry of the given {@link Data} entry.
@@ -1617,6 +1650,12 @@
             public static final String PHONETIC_NAME = DATA8;
 
             /**
+             * The office location of this organization.
+             * <P>Type: TEXT</P>
+             */
+            public static final String OFFICE_LOCATION = DATA9;
+
+            /**
              * Return the string resource that best describes the given
              * {@link #TYPE}. Will always return a valid resource.
              */
diff --git a/core/java/android/provider/Im.java b/core/java/android/provider/Im.java
index d3e2820..025d5c2 100644
--- a/core/java/android/provider/Im.java
+++ b/core/java/android/provider/Im.java
@@ -540,7 +540,7 @@
          * The content:// style URL for contacts who have an open chat session
          */
         public static final Uri CONTENT_URI_CHAT_CONTACTS =
-            Uri.parse("content://com.google.android.providers.talk/contacts/chatting");
+            Uri.parse("content://com.google.android.providers.talk/contacts_chatting");
 
         /**
          * The content:// style URL for contacts who have been blocked
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index be8c777..0fc2e7e 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -27,7 +27,7 @@
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetoothA2dp;
-import android.bluetooth.ParcelUuid;
+import android.os.ParcelUuid;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index f3bc3a6..037e9d3 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -21,7 +21,7 @@
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothUuid;
-import android.bluetooth.ParcelUuid;
+import android.os.ParcelUuid;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 8b9ba84..4e926a6 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -30,7 +30,7 @@
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetooth;
-import android.bluetooth.ParcelUuid;
+import android.os.ParcelUuid;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index f936f65..e1f2823 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -36,6 +36,18 @@
     public static final int VIRTUAL_KEY = 1;
     
     /**
+     * This is a private constant.  Feel free to renumber as desired.
+     * @hide
+     */
+    public static final int SAFE_MODE_DISABLED = 10000;
+    
+    /**
+     * This is a private constant.  Feel free to renumber as desired.
+     * @hide
+     */
+    public static final int SAFE_MODE_ENABLED = 10001;
+    
+    /**
      * Flag for {@link View#performHapticFeedback(int, int)
      * View.performHapticFeedback(int, int)}: Ignore the setting in the
      * view for whether to perform haptic feedback, do it always.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 642f0fa..ed32af2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -24,6 +24,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Interpolator;
 import android.graphics.LinearGradient;
 import android.graphics.Matrix;
 import android.graphics.Paint;
@@ -58,6 +59,7 @@
 import android.view.accessibility.AccessibilityEventSource;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
@@ -514,7 +516,8 @@
  * The framework provides basic support for views that wish to internally
  * scroll their content. This includes keeping track of the X and Y scroll
  * offset as well as mechanisms for drawing scrollbars. See
- * {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)} for more details.
+ * {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)}, and 
+ * {@link #awakenScrollBars()} for more details.
  * </p>
  *
  * <a name="Tags"></a>
@@ -571,6 +574,8 @@
  * @attr ref android.R.styleable#View_scrollbarSize
  * @attr ref android.R.styleable#View_scrollbarStyle
  * @attr ref android.R.styleable#View_scrollbars
+ * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
+ * @attr ref android.R.styleable#View_scrollbarFadeDuration
  * @attr ref android.R.styleable#View_scrollbarTrackHorizontal
  * @attr ref android.R.styleable#View_scrollbarThumbHorizontal
  * @attr ref android.R.styleable#View_scrollbarThumbVertical
@@ -2214,12 +2219,28 @@
     protected void initializeScrollbars(TypedArray a) {
         initScrollCache();
 
-        if (mScrollCache.scrollBar == null) {
-            mScrollCache.scrollBar = new ScrollBarDrawable();
-        }
-
         final ScrollabilityCache scrollabilityCache = mScrollCache;
+        
+        if (scrollabilityCache.scrollBar == null) {
+            scrollabilityCache.scrollBar = new ScrollBarDrawable();
+        }
+        
+        final boolean fadeScrollbars = a.getBoolean(R.styleable.View_fadeScrollbars, false);
 
+        if (!fadeScrollbars) {
+            scrollabilityCache.state = ScrollabilityCache.ON;
+        }
+        scrollabilityCache.fadeScrollBars = fadeScrollbars;
+        
+        
+        scrollabilityCache.scrollBarFadeDuration = a.getInt(
+                R.styleable.View_scrollbarFadeDuration, ViewConfiguration
+                        .getScrollBarFadeDuration());
+        scrollabilityCache.scrollBarDefaultDelayBeforeFade = a.getInt(
+                R.styleable.View_scrollbarDefaultDelayBeforeFade,
+                ViewConfiguration.getScrollDefaultDelay());
+
+                
         scrollabilityCache.scrollBarSize = a.getDimensionPixelSize(
                 com.android.internal.R.styleable.View_scrollbarSize,
                 ViewConfiguration.get(mContext).getScaledScrollBarSize());
@@ -2263,7 +2284,7 @@
      */
     private void initScrollCache() {
         if (mScrollCache == null) {
-            mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext));
+            mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext), this);
         }
     }
 
@@ -4671,7 +4692,9 @@
             mScrollX = x;
             mScrollY = y;
             onScrollChanged(mScrollX, mScrollY, oldX, oldY);
-            invalidate();
+            if (!awakenScrollBars()) {
+                invalidate();
+            }
         }
     }
 
@@ -4687,6 +4710,116 @@
     }
 
     /**
+     * <p>Trigger the scrollbars to draw. When invoked this method starts an
+     * animation to fade the scrollbars out after a default delay. If a subclass
+     * provides animated scrolling, the start delay should equal the duration
+     * of the scrolling animation.</p>
+     *
+     * <p>The animation starts only if at least one of the scrollbars is
+     * enabled, as specified by {@link #isHorizontalScrollBarEnabled()} and
+     * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
+     * this method returns true, and false otherwise. If the animation is
+     * started, this method calls {@link #invalidate()}; in that case the
+     * caller should not call {@link #invalidate()}.</p>
+     *
+     * <p>This method should be invoked every time a subclass directly updates
+     * the scroll parameters.</p>
+     *
+     * <p>This method is automatically invoked by {@link #scrollBy(int, int)}
+     * and {@link #scrollTo(int, int)}.</p>
+     *
+     * @return true if the animation is played, false otherwise
+     *
+     * @see #awakenScrollBars(int)
+     * @see #scrollBy(int, int)
+     * @see #scrollTo(int, int)
+     * @see #isHorizontalScrollBarEnabled()
+     * @see #isVerticalScrollBarEnabled()
+     * @see #setHorizontalScrollBarEnabled(boolean)
+     * @see #setVerticalScrollBarEnabled(boolean)
+     */
+    protected boolean awakenScrollBars() {
+        return mScrollCache != null &&
+                awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade);
+    }
+
+    /**
+     * <p>
+     * Trigger the scrollbars to draw. When invoked this method starts an
+     * animation to fade the scrollbars out after a fixed delay. If a subclass
+     * provides animated scrolling, the start delay should equal the duration of
+     * the scrolling animation.
+     * </p>
+     * 
+     * <p>
+     * The animation starts only if at least one of the scrollbars is enabled,
+     * as specified by {@link #isHorizontalScrollBarEnabled()} and
+     * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
+     * this method returns true, and false otherwise. If the animation is
+     * started, this method calls {@link #invalidate()}; in that case the caller
+     * should not call {@link #invalidate()}.
+     * </p>
+     * 
+     * <p>
+     * This method should be invoked everytime a subclass directly updates the
+     * scroll parameters.
+     * </p>
+     * 
+     * @param startDelay the delay, in milliseconds, after which the animation
+     *        should start; when the delay is 0, the animation starts
+     *        immediately
+     * @return true if the animation is played, false otherwise
+     * 
+     * @see #scrollBy(int, int)
+     * @see #scrollTo(int, int)
+     * @see #isHorizontalScrollBarEnabled()
+     * @see #isVerticalScrollBarEnabled()
+     * @see #setHorizontalScrollBarEnabled(boolean)
+     * @see #setVerticalScrollBarEnabled(boolean)
+     */
+    protected boolean awakenScrollBars(int startDelay) {
+        final ScrollabilityCache scrollCache = mScrollCache;
+        
+        if (scrollCache == null || !scrollCache.fadeScrollBars) {
+            return false;
+        }
+
+        if (scrollCache.scrollBar == null) {
+            scrollCache.scrollBar = new ScrollBarDrawable();
+        }
+
+        if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) {
+
+            // Invalidate to show the scrollbars
+            invalidate();
+
+            if (scrollCache.state == ScrollabilityCache.OFF) {
+                // FIXME: this is copied from WindowManagerService.
+                // We should get this value from the system when it
+                // is possible to do so.
+                final int KEY_REPEAT_FIRST_DELAY = 750;
+                startDelay = Math.max(KEY_REPEAT_FIRST_DELAY, startDelay);
+            }
+
+            // Tell mScrollCache when we should start fading. This may
+            // extend the fade start time if one was already scheduled
+            long fadeStartTime = AnimationUtils.currentAnimationTimeMillis() + startDelay;
+            scrollCache.fadeStartTime = fadeStartTime;
+            scrollCache.state = ScrollabilityCache.ON;
+
+            // Schedule our fader to run, unscheduling any old ones first
+            if (mAttachInfo != null) {
+                mAttachInfo.mHandler.removeCallbacks(scrollCache);
+                mAttachInfo.mHandler.postAtTime(scrollCache, fadeStartTime);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
      * Mark the the area defined by dirty as needing to be drawn. If the view is
      * visible, {@link #onDraw} will be called at some point in the future.
      * This must be called from a UI thread. To call from a non-UI thread, call
@@ -5177,7 +5310,34 @@
     private void recomputePadding() {
         setPadding(mPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
     }
-
+    
+    /**
+     * Define whether scrollbars will fade when the view is not scrolling.
+     * 
+     * @param fadeScrollbars wheter to enable fading
+     * 
+     */
+    public void setScrollbarFadingEnabled(boolean fadeScrollbars) {
+        initScrollCache();
+        final ScrollabilityCache scrollabilityCache = mScrollCache;
+        scrollabilityCache.fadeScrollBars = fadeScrollbars;
+        if (fadeScrollbars) {
+            scrollabilityCache.state = ScrollabilityCache.OFF;
+        } else {
+            scrollabilityCache.state = ScrollabilityCache.ON;
+        }
+    }
+    
+    /**
+     * 
+     * Returns true if scrollbars will fade when this view is not scrolling
+     * 
+     * @return true if scrollbar fading is enabled
+     */
+    public boolean isScrollbarFadingEnabled() {
+        return mScrollCache != null && mScrollCache.fadeScrollBars; 
+    }
+    
     /**
      * <p>Specify the style of the scrollbars. The scrollbars can be overlaid or
      * inset. When inset, they add to the padding of the view. And the scrollbars
@@ -5344,11 +5504,49 @@
      * scrollbars are painted only if they have been awakened first.</p>
      *
      * @param canvas the canvas on which to draw the scrollbars
+     * 
+     * @see #awakenScrollBars(int)
      */
     private void onDrawScrollBars(Canvas canvas) {
         // scrollbars are drawn only when the animation is running
         final ScrollabilityCache cache = mScrollCache;
         if (cache != null) {
+            
+            int state = cache.state;
+            
+            if (state == ScrollabilityCache.OFF) {
+                return;
+            }
+            
+            boolean invalidate = false;
+            
+            if (state == ScrollabilityCache.FADING) {
+                // We're fading -- get our fade interpolation
+                if (cache.interpolatorValues == null) {
+                    cache.interpolatorValues = new float[1];
+                }
+                
+                float[] values = cache.interpolatorValues;
+                
+                // Stops the animation if we're done
+                if (cache.scrollBarInterpolator.timeToValues(values) ==
+                        Interpolator.Result.FREEZE_END) {
+                    cache.state = ScrollabilityCache.OFF;
+                } else {
+                    cache.scrollBar.setAlpha(Math.round(values[0]));
+                }
+                
+                // This will make the scroll bars inval themselves after 
+                // drawing. We only want this when we're fading so that
+                // we prevent excessive redraws
+                invalidate = true;
+            } else {
+                // We're just on -- but we may have been fading before so
+                // reset alpha
+                cache.scrollBar.setAlpha(255);
+            }
+
+            
             final int viewFlags = mViewFlags;
 
             final boolean drawHorizontalScrollBar =
@@ -5371,19 +5569,22 @@
                 final int scrollY = mScrollY;
                 final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
 
+                int left, top, right, bottom;
+                
                 if (drawHorizontalScrollBar) {
-                    scrollBar.setParameters(
-                                            computeHorizontalScrollRange(),
+                    scrollBar.setParameters(computeHorizontalScrollRange(),
                                             computeHorizontalScrollOffset(),
                                             computeHorizontalScrollExtent(), false);
-                    final int top = scrollY + height - size - (mUserPaddingBottom & inside);
                     final int verticalScrollBarGap = drawVerticalScrollBar ?
-                                                getVerticalScrollbarWidth() : 0;
-                    onDrawHorizontalScrollBar(canvas, scrollBar,
-                        scrollX + (mPaddingLeft & inside),
-                        top,
-                        scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap,
-                        top + size);
+                            getVerticalScrollbarWidth() : 0;
+                    top = scrollY + height - size - (mUserPaddingBottom & inside);                         
+                    left = scrollX + (mPaddingLeft & inside);
+                    right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
+                    bottom = top + size;
+                    onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom);
+                    if (invalidate) {
+                        invalidate(left, top, right, bottom);
+                    }
                 }
 
                 if (drawVerticalScrollBar) {
@@ -5391,12 +5592,14 @@
                                             computeVerticalScrollOffset(),
                                             computeVerticalScrollExtent(), true);
                     // TODO: Deal with RTL languages to position scrollbar on left
-                    final int left = scrollX + width - size - (mUserPaddingRight & inside);
-                    onDrawVerticalScrollBar(canvas, scrollBar,
-                             left,
-                             scrollY + (mPaddingTop & inside),
-                             left + size,
-                             scrollY + height - (mUserPaddingBottom & inside));
+                    left = scrollX + width - size - (mUserPaddingRight & inside);
+                    top = scrollY + (mPaddingTop & inside);
+                    right = left + size;
+                    bottom = scrollY + height - (mUserPaddingBottom & inside);
+                    onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom);
+                    if (invalidate) {
+                        invalidate(left, top, right, bottom);
+                    }
                 }
             }
         }
@@ -5424,7 +5627,7 @@
      * @see #computeHorizontalScrollExtent()
      * @see #computeHorizontalScrollOffset()
      * @see android.widget.ScrollBarDrawable
-     *  @hide
+     * @hide
      */
     protected void onDrawHorizontalScrollBar(Canvas canvas,
                                              Drawable scrollBar,
@@ -8731,21 +8934,62 @@
      * is supported. This avoids keeping too many unused fields in most
      * instances of View.</p>
      */
-    private static class ScrollabilityCache {
+    private static class ScrollabilityCache implements Runnable {
+                
+        /**
+         * Scrollbars are not visible
+         */
+        public static final int OFF = 0;
+
+        /**
+         * Scrollbars are visible
+         */
+        public static final int ON = 1;
+
+        /**
+         * Scrollbars are fading away
+         */
+        public static final int FADING = 2;
+
+        public boolean fadeScrollBars;
+        
         public int fadingEdgeLength;
+        public int scrollBarDefaultDelayBeforeFade;
+        public int scrollBarFadeDuration;
 
         public int scrollBarSize;
         public ScrollBarDrawable scrollBar;
+        public float[] interpolatorValues;
+        public View host;
 
         public final Paint paint;
         public final Matrix matrix;
         public Shader shader;
 
+        public final Interpolator scrollBarInterpolator = new Interpolator(1, 2);
+
+        private final float[] mOpaque = {255.0f};
+        private final float[] mTransparent = {0.0f};
+        
+        /**
+         * When fading should start. This time moves into the future every time
+         * a new scroll happens. Measured based on SystemClock.uptimeMillis()
+         */
+        public long fadeStartTime;
+
+
+        /**
+         * The current state of the scrollbars: ON, OFF, or FADING
+         */
+        public int state = OFF;
+
         private int mLastColor;
 
-        public ScrollabilityCache(ViewConfiguration configuration) {
+        public ScrollabilityCache(ViewConfiguration configuration, View host) {
             fadingEdgeLength = configuration.getScaledFadingEdgeLength();
             scrollBarSize = configuration.getScaledScrollBarSize();
+            scrollBarDefaultDelayBeforeFade = configuration.getScrollDefaultDelay();
+            scrollBarFadeDuration = configuration.getScrollBarFadeDuration();
 
             paint = new Paint();
             matrix = new Matrix();
@@ -8755,6 +8999,7 @@
 
             paint.setShader(shader);
             paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+            this.host = host;
         }
 
         public void setFadeColor(int color) {
@@ -8770,5 +9015,32 @@
                 paint.setXfermode(null);
             }
         }
+        
+        public void run() {
+            long now = AnimationUtils.currentAnimationTimeMillis();
+            if (now >= fadeStartTime) {
+
+                // the animation fades the scrollbars out by changing
+                // the opacity (alpha) from fully opaque to fully
+                // transparent
+                int nextFrame = (int) now;
+                int framesCount = 0;
+
+                Interpolator interpolator = scrollBarInterpolator;
+
+                // Start opaque
+                interpolator.setKeyFrame(framesCount++, nextFrame, mOpaque);
+
+                // End transparent
+                nextFrame += scrollBarFadeDuration;
+                interpolator.setKeyFrame(framesCount, nextFrame, mTransparent);
+
+                state = FADING;
+
+                // Kick off the fade animation
+                host.invalidate();
+            }
+        }
+
     }
 }
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 3776463..993048f 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -31,6 +31,16 @@
     private static final int SCROLL_BAR_SIZE = 10;
 
     /**
+     * Duration of the fade when scrollbars fade away in milliseconds
+     */
+    private static final int SCROLL_BAR_FADE_DURATION = 250;
+
+    /**
+     * Default delay before the scrollbars fade in milliseconds
+     */
+    private static final int SCROLL_BAR_DEFAULT_DELAY = 300;
+
+    /**
      * Defines the length of the fading edges in pixels
      */
     private static final int FADING_EDGE_LENGTH = 12;
@@ -221,6 +231,20 @@
     }
 
     /**
+     * @return Duration of the fade when scrollbars fade away in milliseconds
+     */
+    public static int getScrollBarFadeDuration() {
+        return SCROLL_BAR_FADE_DURATION;
+    }
+
+    /**
+     * @return Default delay before the scrollbars fade in milliseconds
+     */
+    public static int getScrollDefaultDelay() {
+        return SCROLL_BAR_DEFAULT_DELAY;
+    }
+    
+    /**
      * @return the length of the fading edges in pixels
      *
      * @deprecated Use {@link #getScaledFadingEdgeLength()} instead.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index b3125b2..78999fa 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -813,7 +813,7 @@
             boolean displayEnabled);
     
     /**
-     * Called when the system is mostly done booting to dentermine whether
+     * Called when the system is mostly done booting to determine whether
      * the system should go into safe mode.
      */
     public boolean detectSafeMode();
diff --git a/core/java/android/webkit/GoogleLocationSettingManager.java b/core/java/android/webkit/GoogleLocationSettingManager.java
index 1b6e77c..508df3b 100644
--- a/core/java/android/webkit/GoogleLocationSettingManager.java
+++ b/core/java/android/webkit/GoogleLocationSettingManager.java
@@ -200,7 +200,11 @@
 
         @Override
         public void onChange(boolean selfChange) {
-            maybeApplySetting(mContext);
+            // This may come after the call to doNotObserve() above,
+            // so mContext may be null.
+            if (mContext != null) {
+                maybeApplySetting(mContext);
+            }
         }
     }
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 0b84848..603f67a 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2480,6 +2480,7 @@
             //        Log.d(LOGTAG, "startScroll: " + dx + " " + dy);
             mScroller.startScroll(mScrollX, mScrollY, dx, dy,
                     animationDuration > 0 ? animationDuration : computeDuration(dx, dy));
+            awakenScrollBars(mScroller.getDuration());
             invalidate();
         } else {
             abortAnimation(); // just in case
@@ -4326,6 +4327,7 @@
         // resume the webcore update.
         final int time = mScroller.getDuration();
         mPrivateHandler.sendEmptyMessageDelayed(RESUME_WEBCORE_UPDATE, time);
+        awakenScrollBars(time);
         invalidate();
     }
 
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index b242b58..165794a 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2444,7 +2444,9 @@
         if (spaceAbove >= absIncrementalDeltaY && spaceBelow >= absIncrementalDeltaY) {
             hideSelector();
             offsetChildrenTopAndBottom(incrementalDeltaY);
-            invalidate();
+            if (!awakenScrollBars()) {
+                invalidate();
+            }
             mMotionViewNewTop = mMotionViewOriginalTop + deltaY;
         } else {
             final int firstPosition = mFirstPosition;
@@ -2527,6 +2529,7 @@
             mBlockLayoutRequests = false;
 
             invokeOnItemScrollListener();
+            awakenScrollBars();
         }
     }
 
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 33e83c3..70555dc 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1150,7 +1150,7 @@
                mSelectedTop = sel.getTop();
             } else if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
                 View child = getChildAt(mMotionPosition - mFirstPosition);
-                positionSelector(child);
+                if (child != null) positionSelector(child);                
             } else {
                 mSelectedTop = 0;
                 mSelectorRect.setEmpty();
@@ -1340,8 +1340,23 @@
      */
     @Override
     void setSelectionInt(int position) {
+        int previousSelectedPosition = mNextSelectedPosition;
+
         setNextSelectedPositionInt(position);
         layoutChildren();
+        
+        final int next = mStackFromBottom ? mItemCount - 1  - mNextSelectedPosition : 
+            mNextSelectedPosition;
+        final int previous = mStackFromBottom ? mItemCount - 1
+                - previousSelectedPosition : previousSelectedPosition;
+
+        final int nextRow = next / mNumColumns;
+        final int previousRow = previous / mNumColumns;
+
+        if (nextRow != previousRow) {
+            awakenScrollBars();
+        }
+
     }
 
     @Override
@@ -1471,6 +1486,7 @@
         if (nextPage >= 0) {
             setSelectionInt(nextPage);
             invokeOnItemScrollListener();
+            awakenScrollBars();
             return true;
         }
 
@@ -1497,6 +1513,10 @@
             invokeOnItemScrollListener();
             moved = true;
         }
+        
+        if (moved) {
+            awakenScrollBars();
+        }
 
         return moved;
     }
@@ -1563,6 +1583,10 @@
             invokeOnItemScrollListener();
         }
 
+        if (moved) {
+            awakenScrollBars();
+        }
+        
         return moved;
     }
 
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 46e514c..52f56a7 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -829,6 +829,7 @@
         long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
         if (duration > ANIMATED_SCROLL_GAP) {
             mScroller.startScroll(mScrollX, mScrollY, dx, dy);
+            awakenScrollBars(mScroller.getDuration());
             invalidate();
         } else {
             if (!mScroller.isFinished()) {
@@ -1172,6 +1173,7 @@
                 mScrollViewMovedFocus = false;
             }
     
+            awakenScrollBars(mScroller.getDuration());
             invalidate();
         }
     }
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 41c9267..7c8151e 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1567,7 +1567,7 @@
             } else {
                 if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
                     View child = getChildAt(mMotionPosition - mFirstPosition);
-                    positionSelector(child);
+                    if (child != null) positionSelector(child);
                 } else {
                     mSelectedTop = 0;
                     mSelectorRect.setEmpty();
@@ -1818,13 +1818,29 @@
 
     /**
      * Makes the item at the supplied position selected.
-     *
+     * 
      * @param position the position of the item to select
      */
     @Override
     void setSelectionInt(int position) {
         setNextSelectedPositionInt(position);
+        boolean awakeScrollbars = false;
+
+        final int selectedPosition = mSelectedPosition;
+
+        if (selectedPosition >= 0) {
+            if (position == selectedPosition - 1) {
+                awakeScrollbars = true;
+            } else if (position == selectedPosition + 1) {
+                awakeScrollbars = true;
+            }
+        }
+
         layoutChildren();
+
+        if (awakeScrollbars) {
+            awakenScrollBars();
+        }
     }
 
     /**
@@ -2084,7 +2100,9 @@
 
                 setSelectionInt(position);
                 invokeOnItemScrollListener();
-                invalidate();
+                if (!awakenScrollBars()) {
+                    invalidate();
+                }
 
                 return true;
             }
@@ -2125,7 +2143,8 @@
             }
         }
 
-        if (moved) {
+        if (moved && !awakenScrollBars()) {
+            awakenScrollBars();
             invalidate();
         }
 
@@ -2270,7 +2289,9 @@
                 positionSelector(selectedView);
                 mSelectedTop = selectedView.getTop();
             }
-            invalidate();
+            if (!awakenScrollBars()) {
+                invalidate();
+            }
             invokeOnItemScrollListener();
             return true;
         }
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 8ef65db..6771711 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -143,7 +143,7 @@
                                     Intent.FLAG_ACTIVITY_NEW_TASK,
                                     Intent.FLAG_ACTIVITY_NEW_TASK, 0);
                         } catch (IntentSender.SendIntentException e) {
-                            throw new ActionException(e.toString());
+                            android.util.Log.e(LOG_TAG, "Cannot send pending intent: ", e);
                         }
                     }
                 };
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 31c7814..24d97a5 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -832,6 +832,7 @@
         long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
         if (duration > ANIMATED_SCROLL_GAP) {
             mScroller.startScroll(mScrollX, mScrollY, dx, dy);
+            awakenScrollBars(mScroller.getDuration());
             invalidate();
         } else {
             if (!mScroller.isFinished()) {
@@ -1175,6 +1176,7 @@
                 mScrollViewMovedFocus = false;
             }
     
+            awakenScrollBars(mScroller.getDuration());
             invalidate();
         }
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3c61c1c..37ef153 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2884,6 +2884,9 @@
             setTransformationMethod(PasswordTransformationMethod.getInstance());
             setTypefaceByIndex(MONOSPACE, 0);
         } else if (isVisiblePassword) {
+            if (mTransformation == PasswordTransformationMethod.getInstance()) {
+                forceUpdate = true;
+            }
             setTypefaceByIndex(MONOSPACE, 0);
         } else if (wasPassword || wasVisiblePassword) {
             // not in password mode, clean up typeface and transformation
@@ -5572,6 +5575,7 @@
 
                 if (duration > ANIMATED_SCROLL_GAP) {
                     mScroller.startScroll(mScrollX, mScrollY, dx, dy);
+                    awakenScrollBars(mScroller.getDuration());
                     invalidate();
                 } else {
                     if (!mScroller.isFinished()) {
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index d7311c2..0d25728 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -24,22 +24,26 @@
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.graphics.Rect;
 import android.net.Uri;
 import android.os.SystemClock;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.PhoneLookup;
-import android.provider.ContactsContract.Presence;
 import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.StatusUpdates;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.CheckBox;
@@ -67,7 +71,7 @@
     private FasttrackBadgeWidget mPhotoView;
     private ImageView mPresenceView;
     private TextView mStatusView;
-    private TextView mStatusDateView;
+    private TextView mStatusAttributionView;
     private int mNoPhotoResource;
     private QueryHandler mQueryHandler;
 
@@ -99,6 +103,8 @@
             Contacts.CONTACT_PRESENCE,
             Contacts.CONTACT_STATUS,
             Contacts.CONTACT_STATUS_TIMESTAMP,
+            Contacts.CONTACT_STATUS_RES_PACKAGE,
+            Contacts.CONTACT_STATUS_LABEL,
         };
         int _ID = 0;
         int LOOKUP_KEY = 1;
@@ -110,6 +116,8 @@
         int CONTACT_PRESENCE_STATUS = 5;
         int CONTACT_STATUS = 6;
         int CONTACT_STATUS_TIMESTAMP = 7;
+        int CONTACT_STATUS_RES_PACKAGE = 8;
+        int CONTACT_STATUS_LABEL = 9;
     }
 
     //Projection used for looking up contact id from phone number
@@ -168,7 +176,7 @@
         mPresenceView = (ImageView) findViewById(R.id.presence);
 
         mStatusView = (TextView)findViewById(R.id.status);
-        mStatusDateView = (TextView)findViewById(R.id.status_date);
+        mStatusAttributionView = (TextView)findViewById(R.id.status_date);
 
         // Set the photo with a random "no contact" image
         long now = SystemClock.elapsedRealtime();
@@ -287,7 +295,7 @@
      * Manually set the presence.
      */
     public void setPresence(int presence) {
-        mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence));
+        mPresenceView.setImageResource(StatusUpdates.getPresenceIconResourceId(presence));
     }
 
     /**
@@ -345,6 +353,7 @@
      */
     public void setExcludeMimes(String[] excludeMimes) {
         mExcludeMimes = excludeMimes;
+        mPhotoView.setExcludeMimes(excludeMimes);
     }
 
     /**
@@ -431,7 +440,7 @@
         //Set the presence status
         if (!c.isNull(ContactQuery.CONTACT_PRESENCE_STATUS)) {
             int presence = c.getInt(ContactQuery.CONTACT_PRESENCE_STATUS);
-            mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence));
+            mPresenceView.setImageResource(StatusUpdates.getPresenceIconResourceId(presence));
             mPresenceView.setVisibility(View.VISIBLE);
         } else {
             mPresenceView.setVisibility(View.GONE);
@@ -443,6 +452,8 @@
             mStatusView.setText(status);
             mStatusView.setVisibility(View.VISIBLE);
 
+            CharSequence timestamp = null;
+
             if (!c.isNull(ContactQuery.CONTACT_STATUS_TIMESTAMP)) {
                 long date = c.getLong(ContactQuery.CONTACT_STATUS_TIMESTAMP);
 
@@ -450,18 +461,63 @@
                 // times.
                 int flags = DateUtils.FORMAT_ABBREV_RELATIVE;
 
-                mStatusDateView.setText(DateUtils.getRelativeTimeSpanString(date, System
-                        .currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, flags));
-                mStatusDateView.setVisibility(View.VISIBLE);
+                timestamp = DateUtils.getRelativeTimeSpanString(date,
+                        System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, flags);
+            }
+
+            String label = null;
+
+            if (!c.isNull(ContactQuery.CONTACT_STATUS_LABEL)) {
+                String resPackage = c.getString(ContactQuery.CONTACT_STATUS_RES_PACKAGE);
+                int labelResource = c.getInt(ContactQuery.CONTACT_STATUS_LABEL);
+                Resources resources;
+                if (TextUtils.isEmpty(resPackage)) {
+                    resources = getResources();
+                } else {
+                    PackageManager pm = getContext().getPackageManager();
+                    try {
+                        resources = pm.getResourcesForApplication(resPackage);
+                    } catch (NameNotFoundException e) {
+                        Log.w(TAG, "Contact status update resource package not found: "
+                                + resPackage);
+                        resources = null;
+                    }
+                }
+
+                if (resources != null) {
+                    try {
+                        label = resources.getString(labelResource);
+                    } catch (NotFoundException e) {
+                        Log.w(TAG, "Contact status update resource not found: " + resPackage + "@"
+                                + labelResource);
+                    }
+                }
+            }
+
+            CharSequence attribution;
+            if (timestamp != null && label != null) {
+                attribution = getContext().getString(
+                        R.string.contact_status_update_attribution_with_date,
+                        timestamp, label);
+            } else if (timestamp == null && label != null) {
+                attribution = getContext().getString(
+                        R.string.contact_status_update_attribution,
+                        label);
+            } else if (timestamp != null) {
+                attribution = timestamp;
             } else {
-                mStatusDateView.setVisibility(View.GONE);
+                attribution = null;
+            }
+            if (attribution != null) {
+                mStatusAttributionView.setText(attribution);
+                mStatusAttributionView.setVisibility(View.VISIBLE);
+            } else {
+                mStatusAttributionView.setVisibility(View.GONE);
             }
         } else {
             mStatusView.setVisibility(View.GONE);
-            mStatusDateView.setVisibility(View.GONE);
+            mStatusAttributionView.setVisibility(View.GONE);
         }
-
-        // TODO add support for status update source, e.g. "via Google Talk"
     }
 
     public void onClick(View view) {
diff --git a/core/res/res/drawable-hdpi/tab_selected.9.png b/core/res/res/drawable-hdpi/tab_selected.9.png
index 29d45a17..f036b9a 100644
--- a/core/res/res/drawable-hdpi/tab_selected.9.png
+++ b/core/res/res/drawable-hdpi/tab_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selected_v4.9.png b/core/res/res/drawable-hdpi/tab_selected_v4.9.png
index 77d0f344..50fcb52 100644
--- a/core/res/res/drawable-hdpi/tab_selected_v4.9.png
+++ b/core/res/res/drawable-hdpi/tab_selected_v4.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_unselected.9.png b/core/res/res/drawable-hdpi/tab_unselected.9.png
index f5781ab..c3a1f30 100644
--- a/core/res/res/drawable-hdpi/tab_unselected.9.png
+++ b/core/res/res/drawable-hdpi/tab_unselected.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_unselected_v4.9.png b/core/res/res/drawable-hdpi/tab_unselected_v4.9.png
index 43b1ee5..c56254c 100644
--- a/core/res/res/drawable-hdpi/tab_unselected_v4.9.png
+++ b/core/res/res/drawable-hdpi/tab_unselected_v4.9.png
Binary files differ
diff --git a/core/res/res/layout-ja/contact_header_name.xml b/core/res/res/layout-ja/contact_header_name.xml
index faf1b87..7c0f63e 100644
--- a/core/res/res/layout-ja/contact_header_name.xml
+++ b/core/res/res/layout-ja/contact_header_name.xml
@@ -29,6 +29,8 @@
         android:ellipsize="end"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textStyle="bold"
+        android:shadowColor="#BB000000"
+        android:shadowRadius="2.75"
         />
 
     <TextView android:id="@+id/phonetic_name"
diff --git a/core/res/res/layout/contact_header_name.xml b/core/res/res/layout/contact_header_name.xml
index a763c22..4a53252 100644
--- a/core/res/res/layout/contact_header_name.xml
+++ b/core/res/res/layout/contact_header_name.xml
@@ -24,4 +24,6 @@
     android:singleLine="true"
     android:ellipsize="end"
     android:layout_gravity="center_vertical"
+    android:shadowColor="#BB000000"
+    android:shadowRadius="2.75"
     />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f5b8ab6..6f109df 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1162,6 +1162,12 @@
              set, else it will be false. -->
         <attr name="isScrollContainer" format="boolean" />
 
+          <!-- Defines whether to fade out scrollbars when they are not in use. -->
+         <attr name="fadeScrollbars" format="boolean" />
+         <!-- Defines the delay in milliseconds that a scrollbar takes to fade out. -->
+         <attr name="scrollbarFadeDuration" format="integer" />
+         <!-- Defines the delay in milliseconds that a scrollbar waits before fade out. -->
+        <attr name="scrollbarDefaultDelayBeforeFade" format="integer" />
         <!-- Sets the width of vertical scrollbars and height of horizontal scrollbars. -->
         <attr name="scrollbarSize" format="dimension" />
         <!-- Defines the horizontal scrollbar thumb drawable. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 907fd8f..498b5cf 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -124,6 +124,24 @@
         <item>30</item>
     </integer-array>
 
+    <!-- Vibrator pattern for feedback about booting with safe mode disabled -->
+    <integer-array name="config_safeModeDisabledVibePattern">
+        <item>0</item>
+        <item>1</item>
+        <item>20</item>
+        <item>21</item>
+    </integer-array>
+
+    <!-- Vibrator pattern for feedback about booting with safe mode disabled -->
+    <integer-array name="config_safeModeEnabledVibePattern">
+        <item>0</item>
+        <item>1</item>
+        <item>20</item>
+        <item>21</item>
+        <item>500</item>
+        <item>600</item>
+    </integer-array>
+
     <bool name="config_use_strict_phone_number_comparation">false</bool>
 
     <!-- Display low battery warning when battery level dips to this value -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 257e0f2..97fb80a 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1172,7 +1172,10 @@
   <public type="attr" name="thumbnail" />
   <public type="attr" name="detachWallpaper" />
   <public type="attr" name="finishOnCloseSystemDialogs" />
-
+  <public type="attr" name="scrollbarFadeDuration" />
+  <public type="attr" name="scrollbarDefaultDelayBeforeFade" />
+  <public type="attr" name="fadeScrollbars" />
+  
   <public type="style" name="Theme.Wallpaper" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar.Fullscreen" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2a55d85..7f97bd1 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1299,6 +1299,12 @@
     <string name="orgTypeOther">Other</string>
     <!-- Custom organization type -->
     <string name="orgTypeCustom">Custom</string>
+    
+    <!-- Attbution of a contact status update, when the time of update is unknown -->
+    <string name="contact_status_update_attribution">Via <xliff:g id="source" example="Google Talk">%1$s</xliff:g></string>
+
+    <!-- Attbution of a contact status update, when the time of update is known -->
+    <string name="contact_status_update_attribution_with_date"><xliff:g id="date" example="3 hours ago">%1$s</xliff:g> via <xliff:g id="source" example="Google Talk">%2$s</xliff:g></string>
 
     <!-- Instructions telling the user to enter their pin to unlock the keyguard.
          Displayed in one line in a large font.  -->
@@ -2082,5 +2088,4 @@
 
     <!-- Do Not Translate: Alternate eri.xml -->
     <string name="alternate_eri_file">/data/eri.xml</string>
-
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index c0ca21b..5ddbce2 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -126,6 +126,8 @@
         <item name="panelTextAppearance">?android:attr/textAppearanceInverse</item>
 
         <!-- Scrollbar attributes -->
+        <item name="scrollbarFadeDuration">250</item>
+        <item name="scrollbarDefaultDelayBeforeFade">300</item> 
         <item name="scrollbarSize">10dip</item>
         <item name="scrollbarThumbHorizontal">@android:drawable/scrollbar_handle_horizontal</item>
         <item name="scrollbarThumbVertical">@android:drawable/scrollbar_handle_vertical</item>
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index c626d5d..e802ec5 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -66,8 +66,8 @@
             mRS = null;
             mID = 0;
             mDestroyed = true;
-            Log.v(RenderScript.LOG_TAG,
-                  getClass() + " auto finalizing object without having released the RS reference.");
+            //Log.v(RenderScript.LOG_TAG, getClass() +
+            // " auto finalizing object without having released the RS reference.");
         }
         super.finalize();
     }
diff --git a/include/ui/CameraParameters.h b/include/ui/CameraParameters.h
index 9c3d4f0..9e4e140 100644
--- a/include/ui/CameraParameters.h
+++ b/include/ui/CameraParameters.h
@@ -215,15 +215,17 @@
     // Values for flash mode settings.
     // Flash will not be fired.
     static const char FLASH_MODE_OFF[];
-    // Flash will be fired automatically when required. The timing is decided by
-    // camera driver.
+    // Flash will be fired automatically when required. The flash may be fired
+    // during preview, auto-focus, or snapshot depending on the driver.
     static const char FLASH_MODE_AUTO[];
-    // Flash will always be fired. The timing is decided by camera driver.
+    // Flash will always be fired during snapshot. The flash may also be
+    // fired during preview or auto-focus depending on the driver.
     static const char FLASH_MODE_ON[];
     // Flash will be fired in red-eye reduction mode.
     static const char FLASH_MODE_RED_EYE[];
-    // Constant emission of light. This can be used for video recording.
-    static const char FLASH_MODE_VIDEO_LIGHT[];
+    // Constant emission of light during preview, auto-focus and snapshot.
+    // This can also be used for video recording.
+    static const char FLASH_MODE_TORCH[];
 
     // Values for scene mode settings.
     static const char SCENE_MODE_AUTO[];
diff --git a/libs/rs/java/Film/res/raw/filmimage.c b/libs/rs/java/Film/res/raw/filmimage.c
index 3bd9496..d154c68 100644
--- a/libs/rs/java/Film/res/raw/filmimage.c
+++ b/libs/rs/java/Film/res/raw/filmimage.c
@@ -4,7 +4,7 @@
 #pragma stateVertex(orthoWindow)
 #pragma stateRaster(flat)
 #pragma stateFragment(PgmFragBackground)
-#pragma stateFragmentStore(MyBlend)
+#pragma stateStore(MyBlend)
 
 
 int main(void* con, int ft, int launchID) {
diff --git a/libs/rs/java/Film/res/raw/filmstrip.c b/libs/rs/java/Film/res/raw/filmstrip.c
index 8fbfee1..bf75675 100644
--- a/libs/rs/java/Film/res/raw/filmstrip.c
+++ b/libs/rs/java/Film/res/raw/filmstrip.c
@@ -3,7 +3,7 @@
 #pragma version(1)
 #pragma stateVertex(PVBackground)
 #pragma stateFragment(PFBackground)
-#pragma stateFragmentStore(PSBackground)
+#pragma stateStore(PSBackground)
 
 #define STATE_TRIANGLE_OFFSET_COUNT 0
 #define STATE_LAST_FOCUS 1
@@ -33,7 +33,7 @@
     drawSimpleMesh(NAMED_mesh);
 
     // Start of images.
-    bindProgramFragmentStore(NAMED_PSImages);
+    bindProgramStore(NAMED_PSImages);
     bindProgramFragment(NAMED_PFImages);
     bindProgramVertex(NAMED_PVImages);
 
diff --git a/libs/rs/java/Fountain/res/raw/fountain.c b/libs/rs/java/Fountain/res/raw/fountain.c
index 86f0f99..f218f9b 100644
--- a/libs/rs/java/Fountain/res/raw/fountain.c
+++ b/libs/rs/java/Fountain/res/raw/fountain.c
@@ -1,8 +1,5 @@
 // Fountain test script
 #pragma version(1)
-#pragma stateVertex(default)
-#pragma stateFragment(default)
-#pragma stateFragmentStore(default)
 
 int newPart = 0;
 
diff --git a/libs/rs/java/Rollo/res/raw/rollo.c b/libs/rs/java/Rollo/res/raw/rollo.c
index 6376715..b31be81 100644
--- a/libs/rs/java/Rollo/res/raw/rollo.c
+++ b/libs/rs/java/Rollo/res/raw/rollo.c
@@ -1,7 +1,7 @@
 #pragma version(1)
 #pragma stateVertex(PV)
 #pragma stateFragment(PF)
-#pragma stateFragmentStore(PFS)
+#pragma stateStore(PFS)
 
 // Scratch buffer layout
 #define SCRATCH_FADE 0
@@ -105,7 +105,7 @@
     if ((zoom < 1.1f) && (zoom > 0.9f)) {
         bindProgramVertex(NAMED_PVOrtho);
         bindProgramFragment(NAMED_PFText);
-        bindProgramFragmentStore(NAMED_PFSText);
+        bindProgramStore(NAMED_PFSText);
 
         rot = drawRot * scale;
         index = 0;
@@ -144,7 +144,7 @@
 
         bindProgramVertex(NAMED_PV);
         bindProgramFragment(NAMED_PF);
-        bindProgramFragmentStore(NAMED_PFS);
+        bindProgramStore(NAMED_PFS);
     }
 
     // Draw the selected icon
diff --git a/libs/rs/java/Rollo/res/raw/rollo2.c b/libs/rs/java/Rollo/res/raw/rollo2.c
index 256fa3c..5b5cb2d 100644
--- a/libs/rs/java/Rollo/res/raw/rollo2.c
+++ b/libs/rs/java/Rollo/res/raw/rollo2.c
@@ -1,7 +1,7 @@
 #pragma version(1)
 #pragma stateVertex(PV)
 #pragma stateFragment(PF)
-#pragma stateFragmentStore(PFS)
+#pragma stateStore(PFS)
 
 // Scratch buffer layout
 #define SCRATCH_FADE 0
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 70add92..169d5d4 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -103,12 +103,14 @@
     ObjectBaseRef<ProgramFragment> frag(mFragment);
     ObjectBaseRef<ProgramVertex> vtx(mVertex);
     ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore);
+    ObjectBaseRef<ProgramRaster> raster(mRaster);
 
     bool ret = s->run(this, launchID);
 
     mFragment.set(frag);
     mVertex.set(vtx);
     mFragmentStore.set(store);
+    mRaster.set(raster);
     return ret;
 }
 
@@ -124,7 +126,6 @@
     eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight);
     glViewport(0, 0, mEGL.mWidth, mEGL.mHeight);
     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    //glEnable(GL_POINT_SMOOTH);
 
     glClearColor(mRootScript->mEnviroment.mClearColor[0],
                  mRootScript->mEnviroment.mClearColor[1],
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 0067fc8..8aa4542 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -51,7 +51,7 @@
 
         ObjectBaseRef<ProgramVertex> mVertex;
         ObjectBaseRef<ProgramFragment> mFragment;
-        //ObjectBaseRef<ProgramRaster> mRaster;
+        ObjectBaseRef<ProgramRaster> mRaster;
         ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
         InvokeFunc_t mInvokables[MAX_SCRIPT_BANKS];
         const char * mScriptText;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index e63ed24..20088da 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -72,6 +72,9 @@
     if (mEnviroment.mVertex.get()) {
         rsc->setVertex(mEnviroment.mVertex.get());
     }
+    if (mEnviroment.mRaster.get()) {
+        rsc->setRaster(mEnviroment.mRaster.get());
+    }
 
     if (launchIndex == 0) {
         mEnviroment.mStartTimeMillis
@@ -175,6 +178,7 @@
     s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
     s->mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
     s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
+    s->mEnviroment.mRaster.set(rsc->getDefaultProgramRaster());
 
     if (s->mProgram.mScript) {
         const static int pragmaMax = 16;
@@ -204,6 +208,18 @@
             }
 
             if (!strcmp(str[ct], "stateRaster")) {
+                if (!strcmp(str[ct+1], "default")) {
+                    continue;
+                }
+                if (!strcmp(str[ct+1], "parent")) {
+                    s->mEnviroment.mRaster.clear();
+                    continue;
+                }
+                ProgramRaster * pr = (ProgramRaster *)rsc->lookupName(str[ct+1]);
+                if (pr != NULL) {
+                    s->mEnviroment.mRaster.set(pr);
+                    continue;
+                }
                 LOGE("Unreconized value %s passed to stateRaster", str[ct+1]);
             }
 
@@ -223,7 +239,7 @@
                 LOGE("Unreconized value %s passed to stateFragment", str[ct+1]);
             }
 
-            if (!strcmp(str[ct], "stateFragmentStore")) {
+            if (!strcmp(str[ct], "stateStore")) {
                 if (!strcmp(str[ct+1], "default")) {
                     continue;
                 }
@@ -237,7 +253,7 @@
                     s->mEnviroment.mFragmentStore.set(pfs);
                     continue;
                 }
-                LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]);
+                LOGE("Unreconized value %s passed to stateStore", str[ct+1]);
             }
 
         }
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index f5f182f..2f195a5 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -672,6 +672,23 @@
     glDrawArrays(GL_LINES, 0, 2);
 }
 
+static void SC_drawPoint(float x, float y, float z)
+{
+    GET_TLS();
+    rsc->setupCheck();
+
+    float vtx[] = { x, y, z };
+
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glVertexPointer(3, GL_FLOAT, 0, vtx);
+
+    glDisableClientState(GL_NORMAL_ARRAY);
+    glDisableClientState(GL_COLOR_ARRAY);
+
+    glDrawArrays(GL_POINTS, 0, 1);
+}
+
 static void SC_drawQuadTexCoords(float x1, float y1, float z1,
                                  float u1, float v1,
                                  float x2, float y2, float z2,
@@ -1131,6 +1148,8 @@
         "void", "(int)" },
     { "bindProgramFragmentStore", (void *)&SC_bindProgramFragmentStore,
         "void", "(int)" },
+    { "bindProgramStore", (void *)&SC_bindProgramFragmentStore,
+        "void", "(int)" },
     { "bindProgramVertex", (void *)&SC_bindProgramVertex,
         "void", "(int)" },
     { "bindSampler", (void *)&SC_bindSampler,
@@ -1155,6 +1174,8 @@
         "void", "(float x1, float y1, float z1, float u1, float v1, float x2, float y2, float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3, float x4, float y4, float z4, float u4, float v4)" },
     { "drawLine", (void *)&SC_drawLine,
         "void", "(float x1, float y1, float z1, float x2, float y2, float z2)" },
+    { "drawPoint", (void *)&SC_drawPoint,
+        "void", "(float x1, float y1, float z1)" },
     { "drawSimpleMesh", (void *)&SC_drawSimpleMesh,
         "void", "(int ism)" },
     { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange,
diff --git a/libs/ui/CameraParameters.cpp b/libs/ui/CameraParameters.cpp
index 9200a97..8f1749d 100644
--- a/libs/ui/CameraParameters.cpp
+++ b/libs/ui/CameraParameters.cpp
@@ -89,7 +89,7 @@
 const char CameraParameters::FLASH_MODE_AUTO[] = "auto";
 const char CameraParameters::FLASH_MODE_ON[] = "on";
 const char CameraParameters::FLASH_MODE_RED_EYE[] = "red-eye";
-const char CameraParameters::FLASH_MODE_VIDEO_LIGHT[] = "video-light";
+const char CameraParameters::FLASH_MODE_TORCH[] = "torch";
 
 // Values for scene mode settings.
 const char CameraParameters::SCENE_MODE_AUTO[] = "auto";
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
index 61a8a29..9927edaa 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
@@ -61,9 +61,8 @@
     }
 
     // Test frame capture
-    // Suppressing until 1259652 is fixed.
-    @Suppress
-    public static void disableTestThumbnailCapture() throws Exception {
+    @LargeTest
+    public static void testThumbnailCapture() throws Exception {
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
         Log.v(TAG, "Thumbnail processing starts");
         long startedAt = System.currentTimeMillis();
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index 9345de5..2361db5 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -175,23 +175,89 @@
     checkGlError("glDrawArrays");
 }
 
-#if 0
+void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
 
-void PrintEGLConfig(EGLDisplay dpy, EGLConfig config) {
-	int attrib[] = {EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, EGL_ALPHA_SIZE,
-			EGL_DEPTH_SIZE, EGL_SURFACE_TYPE, EGL_RENDERABLE_TYPE
-	};
-	for(size_t i = 0; i < sizeof(attrib)/sizeof(attrib[0]); i++) {
-        int value = 0;
-        int a = attrib[i];
-        if (eglGetConfigAttrib(dpy, config, a, &value)) {
-            printf(" 0x%04x: %d", a, value);
+#define X(VAL) {VAL, #VAL}
+    struct {EGLint attribute; const char* name;} names[] = {
+    X(EGL_BUFFER_SIZE),
+    X(EGL_ALPHA_SIZE),
+    X(EGL_BLUE_SIZE),
+    X(EGL_GREEN_SIZE),
+    X(EGL_RED_SIZE),
+    X(EGL_DEPTH_SIZE),
+    X(EGL_STENCIL_SIZE),
+    X(EGL_CONFIG_CAVEAT),
+    X(EGL_CONFIG_ID),
+    X(EGL_LEVEL),
+    X(EGL_MAX_PBUFFER_HEIGHT),
+    X(EGL_MAX_PBUFFER_PIXELS),
+    X(EGL_MAX_PBUFFER_WIDTH),
+    X(EGL_NATIVE_RENDERABLE),
+    X(EGL_NATIVE_VISUAL_ID),
+    X(EGL_NATIVE_VISUAL_TYPE),
+    X(EGL_PRESERVED_RESOURCES),
+    X(EGL_SAMPLES),
+    X(EGL_SAMPLE_BUFFERS),
+    X(EGL_SURFACE_TYPE),
+    X(EGL_TRANSPARENT_TYPE),
+    X(EGL_TRANSPARENT_RED_VALUE),
+    X(EGL_TRANSPARENT_GREEN_VALUE),
+    X(EGL_TRANSPARENT_BLUE_VALUE),
+    X(EGL_BIND_TO_TEXTURE_RGB),
+    X(EGL_BIND_TO_TEXTURE_RGBA),
+    X(EGL_MIN_SWAP_INTERVAL),
+    X(EGL_MAX_SWAP_INTERVAL),
+    X(EGL_LUMINANCE_SIZE),
+    X(EGL_ALPHA_MASK_SIZE),
+    X(EGL_COLOR_BUFFER_TYPE),
+    X(EGL_RENDERABLE_TYPE),
+    X(EGL_CONFORMANT),
+   };
+#undef X
+
+    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+        EGLint value = -1;
+        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
+        EGLint error = eglGetError();
+        if (returnVal && error == EGL_SUCCESS) {
+            printf(" %s: ", names[j].name);
+            printf("%d (0x%x)", value, value);
         }
-	}
-	printf("\n");
+    }
+    printf("\n");
 }
 
-#endif
+int printEGLConfigurations(EGLDisplay dpy) {
+    EGLint numConfig = 0;
+    EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
+    checkEglError("eglGetConfigs", returnVal);
+    if (!returnVal) {
+        return false;
+    }
+
+    printf("Number of EGL configuration: %d\n", numConfig);
+
+    EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig);
+    if (! configs) {
+        printf("Could not allocate configs.\n");
+        return false;
+    }
+
+    returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig);
+    checkEglError("eglGetConfigs", returnVal);
+    if (!returnVal) {
+        free(configs);
+        return false;
+    }
+
+    for(int i = 0; i < numConfig; i++) {
+        printf("Configuration %d\n", i);
+        printEGLConfiguration(dpy, configs[i]);
+    }
+
+    free(configs);
+    return true;
+}
 
 int main(int argc, char** argv) {
     EGLBoolean returnValue;
@@ -199,7 +265,7 @@
 
     EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
     EGLint s_configAttribs[] = {
-            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT|EGL_WINDOW_BIT,
+            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
             EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
             EGL_NONE };
     EGLint majorVersion;
@@ -226,13 +292,25 @@
         return 0;
     }
 
+    if (!printEGLConfigurations(dpy)) {
+        printf("printEGLConfigurations failed\n");
+        return 0;
+    }
+
+    checkEglError("printEGLConfigurations");
+
     EGLNativeWindowType window = android_createDisplaySurface();

     returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig);
     if (returnValue) {
-    	printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue);
-    	return 0;
+        printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue);
+        return 0;
     }
 
+    checkEglError("EGLUtils::selectConfigForNativeWindow");
+
+    printf("Chose this configuration:\n");
+    printEGLConfiguration(dpy, myConfig);
+
     surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
     checkEglError("eglCreateWindowSurface");
     if (surface == EGL_NO_SURFACE) {
diff --git a/opengl/tests/tritex/tritex.cpp b/opengl/tests/tritex/tritex.cpp
index 629b53c..3365ab4 100644
--- a/opengl/tests/tritex/tritex.cpp
+++ b/opengl/tests/tritex/tritex.cpp
@@ -123,7 +123,7 @@
     EGLConfig myConfig = {0};

     EGLint attrib[] =

     {

-            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT|EGL_WINDOW_BIT,
+            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
             EGL_DEPTH_SIZE,     16,

             EGL_NONE

     };

diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index a70134d..aa9c243 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.app.Activity;
+import android.app.KeyguardManager;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -27,6 +28,8 @@
 import android.os.UEventObserver;
 import android.util.Log;
 
+import com.android.internal.widget.LockPatternUtils;
+
 import java.io.FileReader;
 import java.io.FileNotFoundException;
 
@@ -46,7 +49,11 @@
     private final Context mContext;
 
     private PowerManagerService mPowerManager;
-    
+
+    private KeyguardManager.KeyguardLock mKeyguardLock;
+    private boolean mKeyguardDisabled;
+    private LockPatternUtils mLockPatternUtils;
+
     // The broadcast receiver which receives the result of the ordered broadcast sent when
     // the dock state changes. The original ordered broadcast is sent with an initial result
     // code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g.,
@@ -88,6 +95,7 @@
     public DockObserver(Context context, PowerManagerService pm) {
         mContext = context;
         mPowerManager = pm;
+        mLockPatternUtils = new LockPatternUtils(context.getContentResolver());
         init();  // set initial status
         startObserving(DOCK_UEVENT_MATCH);
     }
@@ -130,6 +138,10 @@
 
     void systemReady() {
         synchronized (this) {
+            KeyguardManager keyguardManager =
+                    (KeyguardManager)mContext.getSystemService(Context.KEYGUARD_SERVICE);
+            mKeyguardLock = keyguardManager.newKeyguardLock(TAG);
+
             // don't bother broadcasting undocked here
             if (mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
                 update();
@@ -142,10 +154,25 @@
         mHandler.sendEmptyMessage(0);
     }
 
+    private final void updateKeyguardLocked() {
+        if (!mLockPatternUtils.isLockPatternEnabled()) {
+            if (!mKeyguardDisabled && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+                Log.d(TAG, "calling mKeyguardLock.disableKeyguard");
+                mKeyguardLock.disableKeyguard();
+                mKeyguardDisabled = true;
+            } else if (mKeyguardDisabled && mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+                Log.d(TAG, "calling mKeyguardLock.reenableKeyguard");
+                mKeyguardLock.reenableKeyguard();
+                mKeyguardDisabled = false;
+            }
+        }
+    }
+
     private final Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
             synchronized (this) {
+                updateKeyguardLocked();
                 Log.d(TAG, "Broadcasting dock state " + mDockState);
                 // Pack up the values and broadcast them to everyone
                 mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
index d9f4c9c..d7b8f57 100644
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -337,6 +337,54 @@
         }
     }
     
+    public int getScancodeState(int code) {
+        synchronized (mFirst) {
+            VirtualKey vk = mPressedVirtualKey;
+            if (vk != null) {
+                if (vk.scancode == code) {
+                    return 2;
+                }
+            }
+            return nativeGetScancodeState(code);
+        }
+    }
+    
+    public int getScancodeState(int deviceId, int code) {
+        synchronized (mFirst) {
+            VirtualKey vk = mPressedVirtualKey;
+            if (vk != null) {
+                if (vk.scancode == code) {
+                    return 2;
+                }
+            }
+            return nativeGetScancodeState(deviceId, code);
+        }
+    }
+    
+    public int getKeycodeState(int code) {
+        synchronized (mFirst) {
+            VirtualKey vk = mPressedVirtualKey;
+            if (vk != null) {
+                if (vk.lastKeycode == code) {
+                    return 2;
+                }
+            }
+            return nativeGetKeycodeState(code);
+        }
+    }
+    
+    public int getKeycodeState(int deviceId, int code) {
+        synchronized (mFirst) {
+            VirtualKey vk = mPressedVirtualKey;
+            if (vk != null) {
+                if (vk.lastKeycode == code) {
+                    return 2;
+                }
+            }
+            return nativeGetKeycodeState(deviceId, code);
+        }
+    }
+    
     public static native String getDeviceName(int deviceId);
     public static native int getDeviceClasses(int deviceId);
     public static native void addExcludedDevice(String deviceName);
@@ -344,10 +392,10 @@
             InputDevice.AbsoluteInfo outInfo);
     public static native int getSwitchState(int sw);
     public static native int getSwitchState(int deviceId, int sw);
-    public static native int getScancodeState(int sw);
-    public static native int getScancodeState(int deviceId, int sw);
-    public static native int getKeycodeState(int sw);
-    public static native int getKeycodeState(int deviceId, int sw);
+    public static native int nativeGetScancodeState(int code);
+    public static native int nativeGetScancodeState(int deviceId, int code);
+    public static native int nativeGetKeycodeState(int code);
+    public static native int nativeGetKeycodeState(int deviceId, int code);
     public static native int scancodeToKeycode(int deviceId, int scancode);
     public static native boolean hasKeys(int[] keycodes, boolean[] keyExists);
     
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b3b50e5..65b3e3f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -365,8 +365,17 @@
         mContentResolver.registerContentObserver(Settings.Secure.getUriFor(Settings.Secure.ADB_ENABLED),
                 false, new AdbSettingsObserver());
 
-        // It is now time to start up the app processes...
+        // Before things start rolling, be sure we have decided whether
+        // we are in safe mode.
         final boolean safeMode = wm.detectSafeMode();
+        if (safeMode) {
+            try {
+                ActivityManagerNative.getDefault().enterSafeMode();
+            } catch (RemoteException e) {
+            }
+        }
+        
+        // It is now time to start up the app processes...
 
         if (notification != null) {
             notification.systemReady();
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 228d25e..84ed3ed 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1396,12 +1396,15 @@
                 }
             }
             
-        } else {
+        } else if (mLowerWallpaperTarget != null) {
             // Is it time to stop animating?
-            if (mLowerWallpaperTarget == null
-                    || mLowerWallpaperTarget.mAppToken.animation == null
-                    || mUpperWallpaperTarget == null
-                    || mUpperWallpaperTarget.mAppToken.animation == null) {
+            boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
+                    || (mLowerWallpaperTarget.mAppToken != null
+                            && mLowerWallpaperTarget.mAppToken.animation != null);
+            boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
+                    || (mUpperWallpaperTarget.mAppToken != null
+                            && mUpperWallpaperTarget.mAppToken.animation != null);
+            if (!lowerAnimating || !upperAnimating) {
                 if (DEBUG_WALLPAPER) {
                     Log.v(TAG, "No longer animating wallpaper targets!");
                 }
@@ -3965,7 +3968,7 @@
     // -------------------------------------------------------------
 
     public void disableKeyguard(IBinder token, String tag) {
-        if (mContext.checkCallingPermission(android.Manifest.permission.DISABLE_KEYGUARD)
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
             != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
         }
@@ -3973,7 +3976,7 @@
     }
 
     public void reenableKeyguard(IBinder token) {
-        if (mContext.checkCallingPermission(android.Manifest.permission.DISABLE_KEYGUARD)
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
             != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
         }
@@ -3999,7 +4002,7 @@
      * @see android.app.KeyguardManager#exitKeyguardSecurely
      */
     public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
-        if (mContext.checkCallingPermission(android.Manifest.permission.DISABLE_KEYGUARD)
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
             != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
         }
@@ -4108,7 +4111,7 @@
                 "getScancodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return KeyInputQueue.getScancodeState(sw);
+        return mQueue.getScancodeState(sw);
     }
 
     public int getScancodeStateForDevice(int devid, int sw) {
@@ -4116,7 +4119,7 @@
                 "getScancodeStateForDevice()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return KeyInputQueue.getScancodeState(devid, sw);
+        return mQueue.getScancodeState(devid, sw);
     }
 
     public int getKeycodeState(int sw) {
@@ -4124,7 +4127,7 @@
                 "getKeycodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return KeyInputQueue.getKeycodeState(sw);
+        return mQueue.getKeycodeState(sw);
     }
 
     public int getKeycodeStateForDevice(int devid, int sw) {
@@ -4132,7 +4135,7 @@
                 "getKeycodeStateForDevice()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return KeyInputQueue.getKeycodeState(devid, sw);
+        return mQueue.getKeycodeState(devid, sw);
     }
 
     public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
diff --git a/services/jni/com_android_server_KeyInputQueue.cpp b/services/jni/com_android_server_KeyInputQueue.cpp
index f27596c..c92f8df 100644
--- a/services/jni/com_android_server_KeyInputQueue.cpp
+++ b/services/jni/com_android_server_KeyInputQueue.cpp
@@ -280,13 +280,13 @@
         (void*) android_server_KeyInputQueue_getSwitchState },
     { "getSwitchState", "(II)I",
         (void*) android_server_KeyInputQueue_getSwitchStateDevice },
-    { "getScancodeState", "(I)I",
+    { "nativeGetScancodeState", "(I)I",
         (void*) android_server_KeyInputQueue_getScancodeState },
-    { "getScancodeState", "(II)I",
+    { "nativeGetScancodeState", "(II)I",
         (void*) android_server_KeyInputQueue_getScancodeStateDevice },
-    { "getKeycodeState", "(I)I",
+    { "nativeGetKeycodeState", "(I)I",
         (void*) android_server_KeyInputQueue_getKeycodeState },
-    { "getKeycodeState", "(II)I",
+    { "nativeGetKeycodeState", "(II)I",
         (void*) android_server_KeyInputQueue_getKeycodeStateDevice },
     { "hasKeys", "([I[Z)Z",
         (void*) android_server_KeyInputQueue_hasKeys },
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
index daba8cfd..957f737 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
@@ -673,7 +673,8 @@
 
         // looks like we were unable to resolve the drawable
         mContext.getLogger().warning(String.format(
-                "Unable to resolve drawable \"%1$s\" in attribute \"%2$s\"", value, mNames[index]));
+                "Unable to resolve drawable \"%1$s\" in attribute \"%2$s\"", stringValue,
+                mNames[index]));
 
         return null;
     }