Merge change I129483f8 into eclair-mr2

* changes:
  Optional use of UTF-8 strings in resource bundles
diff --git a/api/current.xml b/api/current.xml
index 41714ef..a5d1967 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -23672,6 +23672,17 @@
 </implements>
 <implements name="android.content.DialogInterface.OnDismissListener">
 </implements>
+<method name="getSearchablesInGlobalSearch"
+ return="java.util.List&lt;android.app.SearchableInfo&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="onCancel"
  return="void"
  abstract="false"
@@ -24131,6 +24142,444 @@
 >
 </method>
 </interface>
+<class name="SearchableInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="autoUrlDetect"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="findActionKey"
+ return="android.app.SearchableInfo.ActionKeyInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="keyCode" type="int">
+</parameter>
+</method>
+<method name="getHintId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getIconId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getImeOptions"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getInputType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getLabelId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSearchActivity"
+ return="android.content.ComponentName"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSearchButtonText"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSettingsDescription"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestAuthority"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestIntentAction"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestIntentData"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestPackage"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestPath"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestSelection"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestThreshold"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceLanguageId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceLanguageModeId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceMaxResults"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoicePromptTextId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceSearchEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceSearchLaunchRecognizer"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceSearchLaunchWebSearch"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="queryAfterZeroResults"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="shouldIncludeInGlobalSearch"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="shouldRewriteQueryFromData"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="shouldRewriteQueryFromText"
+ return="boolean"
+ 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>
+<class name="SearchableInfo.ActionKeyInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getKeyCode"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getQueryActionMsg"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestActionMsg"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestActionMsgColumn"
+ return="java.lang.String"
+ 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>
+</class>
 <class name="Service"
  extends="android.content.ContextWrapper"
  abstract="true"
@@ -83994,6 +84443,148 @@
 >
 </method>
 </class>
+<class name="TrafficStats"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="TrafficStats"
+ type="android.net.TrafficStats"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="getMobileRxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMobileRxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMobileTxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMobileTxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalRxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalRxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalTxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalTxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getUidRxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uid" type="int">
+</parameter>
+</method>
+<method name="getUidTxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uid" type="int">
+</parameter>
+</method>
+<field name="UNSUPPORTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
 <class name="Uri"
  extends="java.lang.Object"
  abstract="true"
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index ab5e102..1f17476 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -2038,10 +2038,8 @@
      * Returns a list of the searchable activities that can be included in global search.
      * 
      * @return a list containing searchable information for all searchable activities
-     *         that have the <code>exported</code> attribute set in their searchable
-     *         meta-data.
-     * 
-     * @hide because SearchableInfo is not part of the API.
+     *         that have the <code>android:includeInGlobalSearch</code> attribute set
+     *         in their searchable meta-data.
      */
     public List<SearchableInfo> getSearchablesInGlobalSearch() {
         try {
diff --git a/core/java/android/app/SearchableInfo.java b/core/java/android/app/SearchableInfo.java
index cbf7b3d..9897742 100644
--- a/core/java/android/app/SearchableInfo.java
+++ b/core/java/android/app/SearchableInfo.java
@@ -38,8 +38,9 @@
 import java.util.HashMap;
 
 /**
- * 
- * @hide Pending API council approval
+ * Searchability meta-data for an activity.
+ * See <a href="SearchManager.html#SearchabilityMetadata">Searchability meta-data</a>
+ * for more information.
  */
 public final class SearchableInfo implements Parcelable {
 
@@ -87,9 +88,9 @@
     private final String mSuggestProviderPackage;
     
     // Flag values for Searchable_voiceSearchMode
-    private static int VOICE_SEARCH_SHOW_BUTTON = 1;
-    private static int VOICE_SEARCH_LAUNCH_WEB_SEARCH = 2;
-    private static int VOICE_SEARCH_LAUNCH_RECOGNIZER = 4;
+    private static final int VOICE_SEARCH_SHOW_BUTTON = 1;
+    private static final int VOICE_SEARCH_LAUNCH_WEB_SEARCH = 2;
+    private static final int VOICE_SEARCH_LAUNCH_RECOGNIZER = 4;
     private final int mVoiceSearchMode;
     private final int mVoiceLanguageModeId;       // voiceLanguageModel
     private final int mVoicePromptTextId;         // voicePromptText
@@ -123,6 +124,8 @@
 
     /**
      * Checks whether the badge should be a text label.
+     *
+     * @hide This feature is deprecated, no need to add it to the API.
      */
     public boolean useBadgeLabel() {
         return 0 != (mSearchMode & SEARCH_MODE_BADGE_LABEL);
@@ -130,6 +133,8 @@
 
     /**
      * Checks whether the badge should be an icon.
+     *
+     * @hide This feature is deprecated, no need to add it to the API.
      */
     public boolean useBadgeIcon() {
         return (0 != (mSearchMode & SEARCH_MODE_BADGE_ICON)) && (mIconId != 0);
@@ -220,6 +225,7 @@
      * 
      * @param context You need to supply a context to start with
      * @return Returns a context related to the searchable activity
+     * @hide
      */
     public Context getActivityContext(Context context) {
         return createActivityContext(context, mSearchActivity);
@@ -251,6 +257,7 @@
      * @param activityContext If we can determine that the provider and the activity are the
      * same, we'll just return this one.
      * @return Returns a context related to the context provider
+     * @hide
      */
     public Context getProviderContext(Context context, Context activityContext) {
         Context theirContext = null;
@@ -351,7 +358,11 @@
     }
     
     /**
-     * Private class used to hold the "action key" configuration
+     * Information about an action key in searchability meta-data.
+     * See <a href="SearchManager.html#SearchabilityMetadata">Searchability meta-data</a>
+     * for more information.
+     *
+     * @see SearchableInfo#findActionKey(int)
      */
     public static class ActionKeyInfo implements Parcelable {
         
@@ -368,7 +379,7 @@
          * construct the object.
          * @throws IllegalArgumentException if the action key configuration is invalid
          */
-        public ActionKeyInfo(Context activityContext, AttributeSet attr) {
+        ActionKeyInfo(Context activityContext, AttributeSet attr) {
             TypedArray a = activityContext.obtainStyledAttributes(attr,
                     com.android.internal.R.styleable.SearchableActionKey);
 
@@ -399,7 +410,7 @@
          * @param in The Parcel containing the previously written ActionKeyInfo,
          * positioned at the location in the buffer where it was written.
          */
-        public ActionKeyInfo(Parcel in) {
+        private ActionKeyInfo(Parcel in) {
             mKeyCode = in.readInt();
             mQueryActionMsg = in.readString();
             mSuggestActionMsg = in.readString();
@@ -461,6 +472,8 @@
      * @param activityInfo Activity to get search information from.
      * @return Search information about the given activity, or {@code null} if
      *         the activity has no or invalid searchability meta-data.
+     *
+     * @hide For use by SearchManagerService.
      */
     public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo) {
         // for each component, try to find metadata
@@ -720,7 +733,7 @@
      * @param in The Parcel containing the previously written SearchableInfo,
      * positioned at the location in the buffer where it was written.
      */
-    public SearchableInfo(Parcel in) {
+    SearchableInfo(Parcel in) {
         mLabelId = in.readInt();
         mSearchActivity = ComponentName.readFromParcel(in);
         mHintId = in.readInt();
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 30e1712..c4e1877 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -287,6 +287,14 @@
      * {@link #onStart} and returns either {@link #START_STICKY}
      * or {@link #START_STICKY_COMPATIBILITY}.
      * 
+     * <p>If you need your application to run on platform versions prior to API
+     * level 5, you can use the following model to handle the older {@link #onStart}
+     * callback in that case.  The <code>handleCommand</code> method is implemented by
+     * you as appropriate:
+     * 
+     * <pre>{@include development/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+     *   start_compatibility}</pre>
+     * 
      * @param intent The Intent supplied to {@link android.content.Context#startService}, 
      * as given.  This may be null if the service is being restarted after
      * its process has gone away, and it had previously returned anything
@@ -462,6 +470,13 @@
      * if your service is performing background music playback, so the user
      * would notice if their music stopped playing.
      * 
+     * <p>If you need your application to run on platform versions prior to API
+     * level 5, you can use the following model to call the the older {@link #setForeground}
+     * or this modern method as appropriate:
+     * 
+     * <pre>{@include development/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+     *   foreground_compatibility}</pre>
+     * 
      * @param id The identifier for this notification as per
      * {@link NotificationManager#notify(int, Notification)
      * NotificationManager.notify(int, Notification)}.
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 7df3637..fda9b81 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -199,6 +199,22 @@
         }
     }
 
+    /** Check if any A2DP sink is in Non Disconnected state
+     * i.e playing, connected, connecting, disconnecting.
+     * @return a unmodifiable set of connected A2DP sinks, or null on error.
+     * @hide
+     */
+    public Set<BluetoothDevice> getNonDisconnectedSinks() {
+        if (DBG) log("getNonDisconnectedSinks()");
+        try {
+            return Collections.unmodifiableSet(
+                    new HashSet<BluetoothDevice>(Arrays.asList(mService.getNonDisconnectedSinks())));
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+            return null;
+        }
+    }
+
     /** Get the state of an A2DP sink
      *  @param device Remote BT device.
      *  @return State code, one of STATE_
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index 002cf4e..168fe3b 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -29,6 +29,7 @@
     boolean suspendSink(in BluetoothDevice device);
     boolean resumeSink(in BluetoothDevice device);
     BluetoothDevice[] getConnectedSinks();  // change to Set<> once AIDL supports
+    BluetoothDevice[] getNonDisconnectedSinks();  // change to Set<> once AIDL supports
     int getSinkState(in BluetoothDevice device);
     boolean setSinkPriority(in BluetoothDevice device, int priority);
     int getSinkPriority(in BluetoothDevice device);
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 0db6155..091d44e 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -17,10 +17,10 @@
 package android.content;
 
 import android.accounts.Account;
+import android.net.TrafficStats;
 import android.os.Bundle;
-import android.os.Process;
-import android.os.NetStat;
 import android.os.IBinder;
+import android.os.Process;
 import android.os.RemoteException;
 import android.util.EventLog;
 
@@ -157,8 +157,8 @@
 
             SyncResult syncResult = new SyncResult();
             int uid = Process.myUid();
-            mInitialTxBytes = NetStat.getUidTxBytes(uid);
-            mInitialRxBytes = NetStat.getUidRxBytes(uid);
+            mInitialTxBytes = TrafficStats.getUidTxBytes(uid);
+            mInitialRxBytes = TrafficStats.getUidRxBytes(uid);
             ContentProviderClient provider = null;
             try {
                 provider = mContext.getContentResolver().acquireContentProviderClient(mAuthority);
@@ -175,8 +175,8 @@
                 if (!isCanceled()) {
                     mSyncContext.onFinished(syncResult);
                 }
-                onLogSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
-                        NetStat.getUidRxBytes(uid) - mInitialRxBytes, syncResult);
+                onLogSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
+                        TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, syncResult);
                 // synchronize so that the assignment will be seen by other threads
                 // that also synchronize accesses to mSyncThread
                 synchronized (mSyncThreadLock) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index d77a6ca..3344158 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1142,7 +1142,6 @@
      * Use with {@link #getSystemService} to retrieve a
      * {@link android.accounts.AccountManager} for receiving intents at a
      * time of your choosing.
-     * TODO STOPSHIP perform a final review of the the account apis before shipping
      *
      * @see #getSystemService
      * @see android.accounts.AccountManager
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 8d69814..a96e896 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -540,10 +540,33 @@
  * {@link #putExtra}.
  *
  * <ul>
- *     <li> {@link #EXTRA_TEMPLATE}
+ *     <li> {@link #EXTRA_ALARM_COUNT}
+ *     <li> {@link #EXTRA_BCC}
+ *     <li> {@link #EXTRA_CC}
+ *     <li> {@link #EXTRA_CHANGED_COMPONENT_NAME}
+ *     <li> {@link #EXTRA_DATA_REMOVED}
+ *     <li> {@link #EXTRA_DOCK_STATE}
+ *     <li> {@link #EXTRA_DOCK_STATE_CAR}
+ *     <li> {@link #EXTRA_DOCK_STATE_DESK}
+ *     <li> {@link #EXTRA_DOCK_STATE_UNDOCKED}
+ *     <li> {@link #EXTRA_DONT_KILL_APP}
+ *     <li> {@link #EXTRA_EMAIL}
+ *     <li> {@link #EXTRA_INITIAL_INTENTS}
  *     <li> {@link #EXTRA_INTENT}
+ *     <li> {@link #EXTRA_KEY_EVENT}
+ *     <li> {@link #EXTRA_PHONE_NUMBER}
+ *     <li> {@link #EXTRA_REMOTE_INTENT_TOKEN}
+ *     <li> {@link #EXTRA_REPLACING}
+ *     <li> {@link #EXTRA_SHORTCUT_ICON}
+ *     <li> {@link #EXTRA_SHORTCUT_ICON_RESOURCE}
+ *     <li> {@link #EXTRA_SHORTCUT_INTENT}
  *     <li> {@link #EXTRA_STREAM}
+ *     <li> {@link #EXTRA_SHORTCUT_NAME}
+ *     <li> {@link #EXTRA_SUBJECT}
+ *     <li> {@link #EXTRA_TEMPLATE}
  *     <li> {@link #EXTRA_TEXT}
+ *     <li> {@link #EXTRA_TITLE}
+ *     <li> {@link #EXTRA_UID}
  * </ul>
  *
  * <h3>Flags</h3>
diff --git a/core/java/android/content/TempProviderSyncAdapter.java b/core/java/android/content/TempProviderSyncAdapter.java
index b46c545..5ccaa26 100644
--- a/core/java/android/content/TempProviderSyncAdapter.java
+++ b/core/java/android/content/TempProviderSyncAdapter.java
@@ -1,9 +1,12 @@
 package android.content;
 
+import android.accounts.Account;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
 import android.database.SQLException;
+import android.net.TrafficStats;
 import android.os.Bundle;
 import android.os.Debug;
-import android.os.NetStat;
 import android.os.Parcelable;
 import android.os.Process;
 import android.os.SystemProperties;
@@ -12,9 +15,6 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.TimingLogger;
-import android.accounts.Account;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
 
 import java.io.IOException;
 
@@ -203,8 +203,8 @@
             if (mProviderSyncStarted) mProvider.onSyncCanceled();
             // We may lose the last few sync events when canceling.  Oh well.
             int uid = Process.myUid();
-            logSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
-                    NetStat.getUidRxBytes(uid) - mInitialRxBytes, mResult);
+            logSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
+                    TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, mResult);
         }
         
         @Override
@@ -212,8 +212,8 @@
             Process.setThreadPriority(Process.myTid(),
                     Process.THREAD_PRIORITY_BACKGROUND);
             int uid = Process.myUid();
-            mInitialTxBytes = NetStat.getUidTxBytes(uid);
-            mInitialRxBytes = NetStat.getUidRxBytes(uid);
+            mInitialTxBytes = TrafficStats.getUidTxBytes(uid);
+            mInitialRxBytes = TrafficStats.getUidRxBytes(uid);
             try {
                 sync(mSyncContext, mAccount, mAuthority, mExtras);
             } catch (SQLException e) {
@@ -222,8 +222,8 @@
             } finally {
                 mSyncThread = null;
                 if (!mIsCanceled) {
-                    logSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
-                    NetStat.getUidRxBytes(uid) - mInitialRxBytes, mResult);
+                    logSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
+                    TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, mResult);
                     mSyncContext.onFinished(mResult);
                 }
             }
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index ac159f4..d90536c 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -930,8 +930,8 @@
         /**
          * Gets the supported preview sizes.
          *
-         * @return a List of Size object. null if preview size setting is not
-         *         supported.
+         * @return a List of Size object. This method will always return a list
+         *         with at least one element.
          */
         public List<Size> getSupportedPreviewSizes() {
             String str = get(KEY_PREVIEW_SIZE + SUPPORTED_VALUES_SUFFIX);
@@ -1065,8 +1065,8 @@
         /**
          * Gets the supported preview formats.
          *
-         * @return a List of Integer objects. null if preview format setting is
-         *         not supported.
+         * @return a List of Integer objects. This method will always return a
+         *         list with at least one element.
          */
         public List<Integer> getSupportedPreviewFormats() {
             String str = get(KEY_PREVIEW_FORMAT + SUPPORTED_VALUES_SUFFIX);
@@ -1104,8 +1104,8 @@
         /**
          * Gets the supported picture sizes.
          *
-         * @return a List of Size objects. null if picture size setting is not
-         *         supported.
+         * @return a List of Size objects. This method will always return a list
+         *         with at least one element.
          */
         public List<Size> getSupportedPictureSizes() {
             String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX);
@@ -1143,12 +1143,18 @@
         /**
          * Gets the supported picture formats.
          *
-         * @return a List of Integer objects (values are PixelFormat.XXX). null
-         *         if picture setting is not supported.
+         * @return a List of Integer objects (values are PixelFormat.XXX). This
+         *         method will always return a list with at least one element.
          */
         public List<Integer> getSupportedPictureFormats() {
-            String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX);
-            return splitInt(str);
+            String str = get(KEY_PICTURE_FORMAT + SUPPORTED_VALUES_SUFFIX);
+            ArrayList<Integer> formats = new ArrayList<Integer>();
+            for (String s : split(str)) {
+                int f = pixelFormatForCameraFormat(s);
+                if (f == PixelFormat.UNKNOWN) continue;
+                formats.add(f);
+            }
+            return formats;
         }
 
         private String cameraFormatForPixelFormat(int pixel_format) {
@@ -1443,8 +1449,8 @@
         /**
          * Gets the supported focus modes.
          *
-         * @return a List of FOCUS_MODE_XXX string constants. null if focus mode
-         *         setting is not supported.
+         * @return a List of FOCUS_MODE_XXX string constants. This method will
+         *         always return a list with at least one element.
          */
         public List<String> getSupportedFocusModes() {
             String str = get(KEY_FOCUS_MODE + SUPPORTED_VALUES_SUFFIX);
diff --git a/core/java/android/os/NetStat.java b/core/java/android/net/TrafficStats.java
similarity index 71%
rename from core/java/android/os/NetStat.java
rename to core/java/android/net/TrafficStats.java
index e294cdf..62e9f1f 100644
--- a/core/java/android/os/NetStat.java
+++ b/core/java/android/net/TrafficStats.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.os;
+package android.net;
 
 import android.util.Log;
 
@@ -22,11 +22,22 @@
 import java.io.RandomAccessFile;
 import java.io.IOException;
 
-/** @hide */
-public class NetStat {
+/**
+ * Class that provides network traffic statistics.  These statistics include bytes transmitted and
+ * received and network packets transmitted and received, over all interfaces, over the mobile
+ * interface, and on a per-UID basis.
+ * <p>
+ * These statistics may not be available on all platforms.  If the statistics are not supported
+ * by this device, {@link #UNSUPPORTED} will be returned.
+ */
+public class TrafficStats {
+    /**
+     * The return value to indicate that the device does not support the statistic.
+     */
+    public final static int UNSUPPORTED = -1;
 
     // Logging tag.
-    private final static String TAG = "netstat";
+    private final static String TAG = "trafficstats";
 
     // We pre-create all the File objects so we don't spend a lot of
     // CPU at runtime converting from Java Strings to byte[] for the
@@ -38,36 +49,40 @@
     private final static File SYS_CLASS_NET_DIR = new File("/sys/class/net");
 
     /**
-     * Get total number of tx packets sent through rmnet0 or ppp0
+     * Get the total number of packets transmitted through the mobile interface.
      *
-     * @return number of Tx packets through rmnet0 or ppp0
+     * @return number of packets.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getMobileTxPkts() {
         return getMobileStat(MOBILE_TX_PACKETS);
     }
 
     /**
-     *  Get total number of rx packets received through rmnet0 or ppp0
+     * Get the total number of packets received through the mobile interface.
      *
-     * @return number of Rx packets through rmnet0 or ppp0
+     * @return number of packets.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getMobileRxPkts() {
         return getMobileStat(MOBILE_RX_PACKETS);
     }
 
     /**
-     *  Get total number of tx bytes received through rmnet0 or ppp0
+     * Get the total number of bytes transmitted through the mobile interface.
      *
-     * @return number of Tx bytes through rmnet0 or ppp0
+     * @return number of bytes.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
       public static long getMobileTxBytes() {
           return getMobileStat(MOBILE_TX_BYTES);
       }
 
     /**
-     *  Get total number of rx bytes received through rmnet0 or ppp0
+     * Get the total number of bytes received through the mobile interface.
      *
-     * @return number of Rx bytes through rmnet0 or ppp0
+     * @return number of bytes.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getMobileRxBytes() {
         return getMobileStat(MOBILE_RX_BYTES);
@@ -76,7 +91,8 @@
     /**
      * Get the total number of packets sent through all network interfaces.
      *
-     * @return the number of packets sent through all network interfaces
+     * @return the number of packets.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getTotalTxPkts() {
         return getTotalStat("tx_packets");
@@ -85,7 +101,8 @@
     /**
      * Get the total number of packets received through all network interfaces.
      *
-     * @return the number of packets received through all network interfaces
+     * @return number of packets.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getTotalRxPkts() {
         return getTotalStat("rx_packets");
@@ -94,7 +111,8 @@
     /**
      * Get the total number of bytes sent through all network interfaces.
      *
-     * @return the number of bytes sent through all network interfaces
+     * @return number of bytes.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getTotalTxBytes() {
         return getTotalStat("tx_bytes");
@@ -103,35 +121,35 @@
     /**
      * Get the total number of bytes received through all network interfaces.
      *
-     * @return the number of bytes received through all network interfaces
+     * @return number of bytes.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getTotalRxBytes() {
         return getTotalStat("rx_bytes");
     }
 
     /**
-     * Gets network bytes sent for this UID.
+     * Get the number of bytes sent through the network for this UID.
      * The statistics are across all interfaces.
-     * The statistics come from /proc/uid_stat.
      *
      * {@see android.os.Process#myUid()}.
      *
-     * @param uid
-     * @return byte count
+     * @param uid The UID of the process to examine.
+     * @return number of bytes.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getUidTxBytes(int uid) {
         return getNumberFromFilePath("/proc/uid_stat/" + uid + "/tcp_snd");
     }
 
     /**
-     * Gets network bytes received for this UID.
+     * Get the number of bytes received through the network for this UID.
      * The statistics are across all interfaces.
-     * The statistics come from /proc/uid_stat.
      *
      * {@see android.os.Process#myUid()}.
      *
-     * @param uid
-     * @return byte count
+     * @param uid The UID of the process to examine.
+     * @return number of bytes
      */
     public static long getUidRxBytes(int uid) {
         return getNumberFromFilePath("/proc/uid_stat/" + uid + "/tcp_rcv");
@@ -159,7 +177,7 @@
 
         File[] nets = SYS_CLASS_NET_DIR.listFiles();
         if (nets == null) {
-            return 0;
+            return UNSUPPORTED;
         }
         long total = 0;
         StringBuffer strbuf = new StringBuffer();
@@ -187,14 +205,14 @@
                       e);
             }
         }
-        return 0L;
+        return UNSUPPORTED;
     }
 
     // File will have format <number><newline>
     private static long getNumberFromFilePath(String filename) {
         RandomAccessFile raf = getFile(filename);
         if (raf == null) {
-            return 0L;
+            return UNSUPPORTED;
         }
         return getNumberFromFile(raf, filename);
     }
@@ -209,7 +227,7 @@
             raf.close();
         } catch (IOException e) {
             Log.w(TAG, "Exception getting TCP bytes from " + filename, e);
-            return 0L;
+            return UNSUPPORTED;
         } finally {
             if (raf != null) {
                 try {
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index 46de708..f2e132b5 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -376,6 +376,16 @@
         return sinks.toArray(new BluetoothDevice[sinks.size()]);
     }
 
+    public synchronized BluetoothDevice[] getNonDisconnectedSinks() {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        Set<BluetoothDevice> sinks = lookupSinksMatchingStates(
+                new int[] {BluetoothA2dp.STATE_CONNECTED,
+                           BluetoothA2dp.STATE_PLAYING,
+                           BluetoothA2dp.STATE_CONNECTING,
+                           BluetoothA2dp.STATE_DISCONNECTING});
+        return sinks.toArray(new BluetoothDevice[sinks.size()]);
+    }
+
     public synchronized int getSinkState(BluetoothDevice device) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         Integer state = mAudioDevices.get(device);
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index e960491..0d0d245 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -546,12 +546,14 @@
 
         boolean authorized = false;
         ParcelUuid uuid = ParcelUuid.fromString(deviceUuid);
+        BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+
         // Bluez sends the UUID of the local service being accessed, _not_ the
         // remote service
         if (mBluetoothService.isEnabled() &&
                 (BluetoothUuid.isAudioSource(uuid) || BluetoothUuid.isAvrcpTarget(uuid)
-                        || BluetoothUuid.isAdvAudioDist(uuid))) {
-            BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+                        || BluetoothUuid.isAdvAudioDist(uuid)) &&
+                        (a2dp.getNonDisconnectedSinks().size() == 0)) {
             BluetoothDevice device = mAdapter.getRemoteDevice(address);
             authorized = a2dp.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF;
             if (authorized) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1fc3678..d94d0c2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5961,7 +5961,11 @@
     protected void onRestoreInstanceState(Parcelable state) {
         mPrivateFlags |= SAVE_STATE_CALLED;
         if (state != BaseSavedState.EMPTY_STATE && state != null) {
-            throw new IllegalArgumentException("Wrong state class -- expecting View State");
+            throw new IllegalArgumentException("Wrong state class, expecting View State but "
+                    + "received " + state.getClass().toString() + " instead. This usually happens "
+                    + "when two views of different type have the same id in the same hierarchy. " 
+                    + "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure " 
+                    + "other views do not use the same id.");
         }
     }
 
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 4baf612..2fd974e 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -1300,7 +1300,7 @@
         }
     }
 
-    private static Object resolveId(Context context, int id) {
+    static Object resolveId(Context context, int id) {
         Object fieldValue;
         final Resources resources = context.getResources();
         if (id >= 0) {
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index fb369d3..ee26218 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -108,6 +108,8 @@
     private static final int RECEIVED_TOUCH_ICON_URL             = 132;
     private static final int GET_VISITED_HISTORY                 = 133;
     private static final int OPEN_FILE_CHOOSER                   = 134;
+    private static final int SHOW_CUSTOM_VIEW                    = 135;
+    private static final int HIDE_CUSTOM_VIEW                    = 136;
 
     // Message triggered by the client to resume execution
     private static final int NOTIFY                              = 200;
@@ -679,6 +681,23 @@
                     mWebChromeClient.openFileChooser((UploadFile) msg.obj);
                 }
                 break;
+
+            case SHOW_CUSTOM_VIEW:
+                if (mWebChromeClient != null) {
+                    HashMap<String, Object> map =
+                            (HashMap<String, Object>) msg.obj;
+                    View view = (View) map.get("view");
+                    WebChromeClient.CustomViewCallback callback =
+                            (WebChromeClient.CustomViewCallback) map.get("callback");
+                    mWebChromeClient.onShowCustomView(view, callback);
+                }
+                break;
+
+            case HIDE_CUSTOM_VIEW:
+                if (mWebChromeClient != null) {
+                    mWebChromeClient.onHideCustomView();
+                }
+                break;
         }
     }
 
@@ -1385,4 +1404,24 @@
         }
         return uploadFile.getResult();
     }
+
+    /* package */ void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {
+        if (mWebChromeClient == null) {
+            return;
+        }
+        Message msg = obtainMessage(SHOW_CUSTOM_VIEW);
+        HashMap<String, Object> map = new HashMap();
+        map.put("view", view);
+        map.put("callback", callback);
+        msg.obj = map;
+        sendMessage(msg);
+    }
+
+    /* package */ void hideCustomView() {
+        if (mWebChromeClient == null) {
+            return;
+        }
+        Message msg = obtainMessage(HIDE_CUSTOM_VIEW);
+        sendMessage(msg);
+    }
 }
diff --git a/core/java/android/webkit/PluginActivity.java b/core/java/android/webkit/PluginActivity.java
deleted file mode 100644
index c60512b..0000000
--- a/core/java/android/webkit/PluginActivity.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.webkit;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.webkit.plugin.SurfaceDrawingModel;
-import android.webkit.plugin.WebkitPlugin;
-
-/**
- * This activity is invoked when a plugin elects to go into full screen mode.
- * @hide
- */
-public class PluginActivity extends Activity {
-
-    private static final String LOGTAG = "PluginActivity";
-    
-    /* package */ static final String INTENT_EXTRA_NPP_INSTANCE =
-            "android.webkit.plugin.NPP_INSTANCE";
-
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        final Intent intent = getIntent();
-        if (intent == null) {
-            Log.e(LOGTAG, "Unable to retrieve the intent responsible for this activity");
-            finish();
-            return;
-        }
-
-        final int npp = intent.getIntExtra(INTENT_EXTRA_NPP_INSTANCE, -1);
-
-        if (npp == -1) {
-            Log.e(LOGTAG, "The intent did not include the NPP pointer");
-            finish();
-            return;
-        }
-
-        // retrieve the plugin's existing java object instead of creating a new one
-        WebkitPlugin plugin = nativeGetWebkitPlugin(npp);
-
-        if (plugin == null) {
-            Log.e(LOGTAG, "Unable to retrieve the plugin's java interface");
-            finish();
-            return;
-        }
-        SurfaceDrawingModel fullScreenSurface = plugin.getFullScreenSurface();
-        if (fullScreenSurface == null) {
-            Log.e(LOGTAG, "The plugin returned a null value for the full-screen interface");
-            finish();
-            return;
-        }
-        View pluginView = fullScreenSurface.getSurface();
-        if (pluginView != null) {
-            setContentView(pluginView);
-        } else {
-            // No custom full-sreen view returned by the plugin, odd but
-            // just in case, finish the activity.
-            Log.e(LOGTAG, "The plugin's full-screen interface returned a null view");
-            finish();
-        }
-    }
-
-    native WebkitPlugin nativeGetWebkitPlugin(int npp);
-}
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 924398e..608c8a24 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -789,7 +789,6 @@
         // Set up a measure spec so a layout can always be recreated.
         mWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
         mHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
-        requestFocus();
     }
 
     /**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 3be6a3f..7c79fd9 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3205,6 +3205,8 @@
         // Note that sendOurVisibleRect calls viewToContent, so the coordinates
         // should be in content coordinates.
         Rect bounds = nativeFocusCandidateNodeBounds();
+        Rect vBox = contentToViewRect(bounds);
+        mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), vBox.height());
         if (!Rect.intersects(bounds, visibleRect)) {
             mWebTextView.bringIntoView();
         }
@@ -3215,25 +3217,14 @@
             // i.e. In the case of opening/closing the screen.
             // In that case, we need to set the dimensions, but not the other
             // aspects.
-            // We also need to restore the selection, which gets wrecked by
-            // calling setTextEntryRect.
-            Spannable spannable = (Spannable) mWebTextView.getText();
-            int start = Selection.getSelectionStart(spannable);
-            int end = Selection.getSelectionEnd(spannable);
             // If the text has been changed by webkit, update it.  However, if
             // there has been more UI text input, ignore it.  We will receive
             // another update when that text is recognized.
-            if (text != null && !text.equals(spannable.toString())
+            if (text != null && !text.equals(mWebTextView.getText().toString())
                     && nativeTextGeneration() == mTextGeneration) {
                 mWebTextView.setTextAndKeepSelection(text);
-            } else {
-                // FIXME: Determine whether this is necessary.
-                Selection.setSelection(spannable, start, end);
             }
         } else {
-            Rect vBox = contentToViewRect(bounds);
-            mWebTextView.setRect(vBox.left, vBox.top, vBox.width(),
-                    vBox.height());
             mWebTextView.setGravity(nativeFocusCandidateIsRtlText() ?
                     Gravity.RIGHT : Gravity.NO_GRAVITY);
             // This needs to be called before setType, which may call
@@ -3247,8 +3238,8 @@
                 text = "";
             }
             mWebTextView.setTextAndKeepSelection(text);
-            mWebTextView.requestFocus();
         }
+        mWebTextView.requestFocus();
     }
 
     /**
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 33f3713c..6079773 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -41,6 +41,7 @@
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
+import android.webkit.plugin.FullScreenDrawingModel;
 import android.webkit.plugin.SurfaceDrawingModel;
 import android.webkit.plugin.WebkitPlugin;
 
@@ -2214,16 +2215,36 @@
         return pluginManager.getPluginInstance(pkgName, npp);
     }
 
-    // called by JNI. PluginWidget function to launch an activity and overlays
-    // the activity with the View provided by the plugin class.
-    private void startFullScreenPluginActivity(int npp) {
+    // called by JNI. PluginWidget function to launch a full-screen view using a
+    // View object provided by the plugin class.
+    private void showFullScreenPlugin(WebkitPlugin webkitPlugin) {
         if (mWebView == null) {
             return;
         }
 
-        Intent intent = new Intent("android.intent.webkit.PLUGIN");
-        intent.putExtra(PluginActivity.INTENT_EXTRA_NPP_INSTANCE, npp);
-        mWebView.getContext().startActivity(intent);
+        final FullScreenDrawingModel surface = webkitPlugin.getFullScreenSurface();
+        if(surface == null) {
+            Log.e(LOGTAG, "Attempted to create an full-screen surface with a null drawing model");
+            return;
+        }
+
+        WebChromeClient.CustomViewCallback callback = new WebChromeClient.CustomViewCallback() {
+            public void onCustomViewHidden() {
+                if (surface != null) {
+                    surface.onSurfaceRemoved();
+                }
+            }
+        };
+
+        mCallbackProxy.showCustomView(surface.getSurface(), callback);
+    }
+
+    private void hideFullScreenPlugin() {
+        if (mWebView == null) {
+            return;
+        }
+
+        mCallbackProxy.hideCustomView();
     }
 
     // called by JNI.  PluginWidget functions for creating an embedded View for
diff --git a/core/java/android/webkit/plugin/FullScreenDrawingModel.java b/core/java/android/webkit/plugin/FullScreenDrawingModel.java
new file mode 100644
index 0000000..fe9d197
--- /dev/null
+++ b/core/java/android/webkit/plugin/FullScreenDrawingModel.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package android.webkit.plugin;
+
+/**
+ *
+ * @hide pending API solidification
+ */
+public interface FullScreenDrawingModel extends SurfaceDrawingModel {
+
+    public void onSurfaceRemoved();
+
+}
diff --git a/core/java/android/webkit/plugin/WebkitPlugin.java b/core/java/android/webkit/plugin/WebkitPlugin.java
index 3d13c1c..af02cdc 100644
--- a/core/java/android/webkit/plugin/WebkitPlugin.java
+++ b/core/java/android/webkit/plugin/WebkitPlugin.java
@@ -30,7 +30,7 @@
  */
 public interface WebkitPlugin {
 
-    SurfaceDrawingModel getEmbeddedSurface();
-    SurfaceDrawingModel getFullScreenSurface();
+    SurfaceDrawingModel    getEmbeddedSurface();
+    FullScreenDrawingModel getFullScreenSurface();
 
 }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5199ada..e964a8f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -17,8 +17,8 @@
 package com.android.internal.os;
 
 import android.bluetooth.BluetoothHeadset;
+import android.net.TrafficStats;
 import android.os.BatteryStats;
-import android.os.NetStat;
 import android.os.Parcel;
 import android.os.ParcelFormatException;
 import android.os.Parcelable;
@@ -1022,8 +1022,8 @@
     public void doUnplug(long batteryUptime, long batteryRealtime) {
         for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
             Uid u = mUidStats.valueAt(iu);
-            u.mStartedTcpBytesReceived = NetStat.getUidRxBytes(u.mUid);
-            u.mStartedTcpBytesSent = NetStat.getUidTxBytes(u.mUid);
+            u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid);
+            u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid);
             u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
             u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
         }
@@ -1031,10 +1031,10 @@
             mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
         }
         // Track total mobile data
-        doDataUnplug(mMobileDataRx, NetStat.getMobileRxBytes());
-        doDataUnplug(mMobileDataTx, NetStat.getMobileTxBytes());
-        doDataUnplug(mTotalDataRx, NetStat.getTotalRxBytes());
-        doDataUnplug(mTotalDataTx, NetStat.getTotalTxBytes());
+        doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes());
+        doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes());
+        doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes());
+        doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes());
         // Track radio awake time
         mRadioDataStart = getCurrentRadioDataUptime();
         mRadioDataUptime = 0;
@@ -1058,10 +1058,10 @@
         for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
             mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
         }
-        doDataPlug(mMobileDataRx, NetStat.getMobileRxBytes());
-        doDataPlug(mMobileDataTx, NetStat.getMobileTxBytes());
-        doDataPlug(mTotalDataRx, NetStat.getTotalRxBytes());
-        doDataPlug(mTotalDataTx, NetStat.getTotalTxBytes());
+        doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes());
+        doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes());
+        doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes());
+        doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes());
         // Track radio awake time
         mRadioDataUptime = getRadioDataUptime();
         mRadioDataStart = -1;
@@ -1519,7 +1519,7 @@
         
         public long computeCurrentTcpBytesReceived() {
             return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
-                    ? (NetStat.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
+                    ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
         }
 
         @Override
@@ -1696,7 +1696,7 @@
         
         public long computeCurrentTcpBytesSent() {
             return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
-                    ? (NetStat.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
+                    ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
         }
 
         void writeToParcelLocked(Parcel out, long batteryRealtime) {
@@ -2919,22 +2919,22 @@
 
     /** Only STATS_UNPLUGGED works properly */
     public long getMobileTcpBytesSent(int which) {
-        return getTcpBytes(NetStat.getMobileTxBytes(), mMobileDataTx, which);
+        return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which);
     }
 
     /** Only STATS_UNPLUGGED works properly */
     public long getMobileTcpBytesReceived(int which) {
-        return getTcpBytes(NetStat.getMobileRxBytes(), mMobileDataRx, which);
+        return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which);
     }
 
     /** Only STATS_UNPLUGGED works properly */
     public long getTotalTcpBytesSent(int which) {
-        return getTcpBytes(NetStat.getTotalTxBytes(), mTotalDataTx, which);
+        return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which);
     }
 
     /** Only STATS_UNPLUGGED works properly */
     public long getTotalTcpBytesReceived(int which) {
-        return getTcpBytes(NetStat.getTotalRxBytes(), mTotalDataRx, which);
+        return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which);
     }
 
     @Override
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index eacf0ce..ba0bf0d 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -76,6 +76,13 @@
      */
     public static final native IBinder getContextObject();
     
+    /**
+     * Special for system process to not allow incoming calls to run at
+     * background scheduling priority.
+     * @hide
+     */
+    public static final native void disableBackgroundScheduling(boolean disable);
+    
     static native final void handleGc();
     
     public static void forceGc(String reason) {
diff --git a/core/java/com/google/android/net/GoogleHttpClient.java b/core/java/com/google/android/net/GoogleHttpClient.java
index 8a1298f..7bdc7f8 100644
--- a/core/java/com/google/android/net/GoogleHttpClient.java
+++ b/core/java/com/google/android/net/GoogleHttpClient.java
@@ -19,13 +19,14 @@
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
+import android.net.TrafficStats;
 import android.net.http.AndroidHttpClient;
 import android.os.Build;
-import android.os.NetStat;
 import android.os.SystemClock;
 import android.provider.Checkin;
 import android.util.Config;
 import android.util.Log;
+import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpHost;
@@ -45,7 +46,6 @@
 import org.apache.http.impl.client.RequestWrapper;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
-import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
 
 import java.io.IOException;
 import java.net.InetAddress;
@@ -205,8 +205,8 @@
                 // to follow redirects, count each redirect as an additional round trip.
 
                 int uid = android.os.Process.myUid();
-                long startTx = NetStat.getUidTxBytes(uid);
-                long startRx = NetStat.getUidRxBytes(uid);
+                long startTx = TrafficStats.getUidTxBytes(uid);
+                long startRx = TrafficStats.getUidRxBytes(uid);
 
                 response = mClient.execute(request, context);
                 HttpEntity origEntity = response == null ? null : response.getEntity();
diff --git a/core/java/com/google/android/net/NetworkStatsEntity.java b/core/java/com/google/android/net/NetworkStatsEntity.java
index f5d2349..a22fa1e 100644
--- a/core/java/com/google/android/net/NetworkStatsEntity.java
+++ b/core/java/com/google/android/net/NetworkStatsEntity.java
@@ -16,11 +16,10 @@
 
 package com.google.android.net;
 
-import android.os.NetStat;
+import android.net.TrafficStats;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.util.EventLog;
-
 import org.apache.http.HttpEntity;
 import org.apache.http.entity.HttpEntityWrapper;
 
@@ -45,8 +44,8 @@
                 super.close();
             } finally {
                 long processingTime = SystemClock.elapsedRealtime() - mProcessingStartTime;
-                long tx = NetStat.getUidTxBytes(mUid);
-                long rx = NetStat.getUidRxBytes(mUid);
+                long tx = TrafficStats.getUidTxBytes(mUid);
+                long rx = TrafficStats.getUidRxBytes(mUid);
 
                 EventLog.writeEvent(HTTP_STATS_EVENT, mUa, mResponseLatency, processingTime,
                         tx - mStartTx, rx - mStartRx);
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index f0885fd..627fcbf 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -670,6 +670,12 @@
     android::IPCThreadState::self()->joinThreadPool();
 }
 
+static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
+        jobject clazz, jboolean disable)
+{
+    IPCThreadState::disableBackgroundScheduling(disable ? true : false);
+}
+
 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
 {
     LOGV("Gc has executed, clearing binder ops");
@@ -682,6 +688,7 @@
      /* name, signature, funcPtr */
     { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
     { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
+    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
     { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
 };
 
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 094b02d..e84f2e5 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -120,11 +120,7 @@
 
 jint android_os_Process_myTid(JNIEnv* env, jobject clazz)
 {
-#ifdef HAVE_GETTID
-    return gettid();
-#else
-    return getpid();
-#endif
+    return androidGetTid();
 }
 
 jint android_os_Process_getUidForName(JNIEnv* env, jobject clazz, jstring name)
@@ -191,15 +187,11 @@
 
 void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
 {
-    if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
-        signalExceptionForGroupError(env, clazz, EINVAL);
+    int res = androidSetThreadSchedulingGroup(pid, grp);
+    if (res != NO_ERROR) {
+        signalExceptionForGroupError(env, clazz, res == BAD_VALUE ? EINVAL : errno);
         return;
     }
-
-    if (set_sched_policy(pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
-                                      SP_BACKGROUND : SP_FOREGROUND)) {
-        signalExceptionForGroupError(env, clazz, errno);
-    }
 }
 
 void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp) 
@@ -275,22 +267,15 @@
 void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
                                               jint pid, jint pri)
 {
-    int rc = 0;
-
-    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(pid, SP_BACKGROUND);
-    } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(pid, SP_FOREGROUND);
+    int rc = androidSetThreadPriority(pid, pri);
+    if (rc != 0) {
+        if (rc == INVALID_OPERATION) {
+            signalExceptionForPriorityError(env, clazz, errno);
+        } else {
+            signalExceptionForGroupError(env, clazz, errno);
+        }
     }
-
-    if (rc) {
-        signalExceptionForGroupError(env, clazz, errno);
-        return;
-    }
-
-    if (setpriority(PRIO_PROCESS, pid, pri) < 0) {
-        signalExceptionForPriorityError(env, clazz, errno);
-    }
+    
     //LOGI("Setting priority of %d: %d, getpriority returns %d\n",
     //     pid, pri, getpriority(PRIO_PROCESS, pid));
 }
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock.xml b/core/res/res/layout/keyguard_screen_tab_unlock.xml
index a45faad..7e365fc 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock.xml
@@ -40,6 +40,20 @@
         android:textAppearance="?android:attr/textAppearanceMedium"
         />
 
+    <!-- emergency call button shown when sim is missing or PUKd -->
+    <Button
+        android:id="@+id/emergencyCallButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentRight="true"
+        android:layout_marginTop="10dip"
+        android:layout_marginRight="8dip"
+        android:drawableLeft="@drawable/ic_emergency"
+        style="@style/Widget.Button.Transparent"
+        android:drawablePadding="8dip"
+       />
+
     <!-- time and date -->
     <com.android.internal.widget.DigitalClock android:id="@+id/time"
         android:layout_width="wrap_content"
@@ -121,6 +135,7 @@
         android:layout_marginLeft="24dip"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:layout_marginTop="12dip"
+        android:drawablePadding="4dip"
         />
 
     <com.android.internal.widget.SlidingTab
@@ -132,18 +147,5 @@
         android:layout_marginBottom="80dip" 
         />
 
-    <!-- emergency call button shown when sim is missing or PUKd -->
-    <Button
-        android:id="@+id/emergencyCallButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/screenLocked"
-        android:layout_marginTop="8dip"
-        android:layout_marginLeft="24dip"
-        android:drawableLeft="@drawable/ic_emergency"
-        style="@style/Widget.Button.Transparent"
-        android:drawablePadding="8dip"
-       />
-
 </RelativeLayout>
 
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
index 1001697..33afe93 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
@@ -45,6 +45,18 @@
             android:textAppearance="?android:attr/textAppearanceMedium"
             />
 
+        <!-- emergency call button shown when sim is missing or PUKd -->
+        <Button
+            android:id="@+id/emergencyCallButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:layout_marginTop="20dip"
+            android:drawableLeft="@drawable/ic_emergency"
+            style="@style/Widget.Button.Transparent"
+            android:drawablePadding="8dip"
+           />
+
         <com.android.internal.widget.DigitalClock android:id="@+id/time"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -122,19 +134,9 @@
             android:textAppearance="?android:attr/textAppearanceMedium"
             android:gravity="center"
             android:layout_marginTop="12dip"
+            android:drawablePadding="4dip"
             />
 
-        <!-- emergency call button shown when sim is missing or PUKd -->
-        <Button
-            android:id="@+id/emergencyCallButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/screenLocked"
-            android:layout_marginTop="8dip"
-            android:drawableLeft="@drawable/ic_emergency"
-            style="@style/Widget.Button.Transparent"
-            android:drawablePadding="8dip"
-           />
     </RelativeLayout>
 
     <!-- right side -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index f17d1ff..b6af6b2 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -90,5 +90,12 @@
     <color name="sliding_tab_text_color_active">@android:color/black</color>
     <color name="sliding_tab_text_color_shadow">@android:color/black</color>
 
+    <!-- keyguard tab -->
+    <color name="keyguard_text_color_normal">#ffffff</color>
+    <color name="keyguard_text_color_unlock">#a7d84c</color>
+    <color name="keyguard_text_color_soundoff">#ffffff</color>
+    <color name="keyguard_text_color_soundon">#e69310</color>
+    <color name="keyguard_text_color_decline">#fe0a5a</color>
+
 </resources>
 
diff --git a/docs/html/guide/developing/tools/aidl.jd b/docs/html/guide/developing/tools/aidl.jd
index abfa8b1..19d9ea1 100644
--- a/docs/html/guide/developing/tools/aidl.jd
+++ b/docs/html/guide/developing/tools/aidl.jd
@@ -297,9 +297,9 @@
         as method arguments. </li>
 </ul>
 <p>Here is some sample code demonstrating calling an AIDL-created service, taken
-    from the Remote Activity sample in the ApiDemos project.</p>
-<p>{@sample development/samples/ApiDemos/src/com/example/android/apis/app/RemoteServiceBinding.java
-    exposing_a_service}</p>
+    from the Remote Service sample in the ApiDemos project.</p>
+<p>{@sample development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
+    calling_a_service}</p>
 
 
 
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 884b5c1..749a977 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -52,7 +52,7 @@
         DUMP_TRANSACTION        = B_PACK_CHARS('_','D','M','P'),
         INTERFACE_TRANSACTION   = B_PACK_CHARS('_', 'N', 'T', 'F'),
 
-        // Corresponds to tfOneWay -- an asynchronous call.
+        // Corresponds to TF_ONE_WAY -- an asynchronous call.
         FLAG_ONEWAY             = 0x00000001
     };
 
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 78306b2b..3ab985d 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -68,6 +68,13 @@
 
     static  void                shutdown();
     
+    // Call this to disable switching threads to background scheduling when
+    // receiving incoming IPC calls.  This is specifically here for the
+    // Android system process, since it expects to have background apps calling
+    // in to it but doesn't want to acquire locks in its services while in
+    // the background.
+    static  void                disableBackgroundScheduling(bool disable);
+    
 private:
                                 IPCThreadState();
                                 ~IPCThreadState();
@@ -93,9 +100,10 @@
                                            void* cookie);
     
     const   sp<ProcessState>    mProcess;
+    const   pid_t               mMyThreadId;
             Vector<BBinder*>    mPendingStrongDerefs;
             Vector<RefBase::weakref_type*> mPendingWeakDerefs;
-                                
+            
             Parcel              mIn;
             Parcel              mOut;
             status_t            mLastError;
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 0fc533f..130d83c 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -124,6 +124,24 @@
 
 extern void androidSetCreateThreadFunc(android_create_thread_fn func);
 
+// ------------------------------------------------------------------
+// Extra functions working with raw pids.
+
+// Get pid for the current thread.
+extern pid_t androidGetTid();
+
+// Change the scheduling group of a particular thread.  The group
+// should be one of the ANDROID_TGROUP constants.  Returns BAD_VALUE if
+// grp is out of range, else another non-zero value with errno set if
+// the operation failed.
+extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
+
+// Change the priority AND scheduling group of a particular thread.  The priority
+// should be one of the ANDROID_PRIORITY constants.  Returns INVALID_OPERATION
+// if the priority set failed, else another value if just the group set failed;
+// in either case errno is set.
+extern int androidSetThreadPriority(pid_t tid, int prio);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index b2a7db8..473f580 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -292,6 +292,7 @@
 static bool gHaveTLS = false;
 static pthread_key_t gTLS = 0;
 static bool gShutdown = false;
+static bool gDisableBackgroundScheduling = false;
 
 IPCThreadState* IPCThreadState::self()
 {
@@ -332,6 +333,11 @@
     }
 }
 
+void IPCThreadState::disableBackgroundScheduling(bool disable)
+{
+    gDisableBackgroundScheduling = disable;
+}
+
 sp<ProcessState> IPCThreadState::process()
 {
     return mProcess;
@@ -386,6 +392,11 @@
 
     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
     
+    // This thread may have been spawned by a thread that was in the background
+    // scheduling group, so first we will make sure it is in the default/foreground
+    // one to avoid performing an initial transaction in the background.
+    androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
+        
     status_t result;
     do {
         int32_t cmd;
@@ -427,19 +438,13 @@
         }
         
         // After executing the command, ensure that the thread is returned to the
-        // default cgroup and priority before rejoining the pool.  This is a failsafe
-        // in case the command implementation failed to properly restore the thread's
-        // scheduling parameters upon completion.
-        int my_id;
-#ifdef HAVE_GETTID
-        my_id = gettid();
-#else
-        my_id = getpid();
-#endif
-        if (!set_sched_policy(my_id, SP_FOREGROUND)) {
-            // success; reset the priority as well
-            setpriority(PRIO_PROCESS, my_id, ANDROID_PRIORITY_NORMAL);
-        }
+        // default cgroup before rejoining the pool.  The driver takes care of
+        // restoring the priority, but doesn't do anything with cgroups so we
+        // need to take care of that here in userspace.  Note that we do make
+        // sure to go in the foreground after executing a transaction, but
+        // there are other callbacks into user code that could have changed
+        // our group so we want to make absolutely sure it is put back.
+        androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
 
         // Let this thread exit the thread pool if it is no longer
         // needed and it is not the main process thread.
@@ -583,10 +588,10 @@
 }
 
 IPCThreadState::IPCThreadState()
-    : mProcess(ProcessState::self())
+    : mProcess(ProcessState::self()), mMyThreadId(androidGetTid())
 {
     pthread_setspecific(gTLS, this);
-        clearCaller();
+    clearCaller();
     mIn.setDataCapacity(256);
     mOut.setDataCapacity(256);
 }
@@ -930,6 +935,17 @@
             mCallingPid = tr.sender_pid;
             mCallingUid = tr.sender_euid;
             
+            bool doBackground = !gDisableBackgroundScheduling &&
+                    getpriority(PRIO_PROCESS, mMyThreadId)
+                            >= ANDROID_PRIORITY_BACKGROUND;
+            if (doBackground) {
+                // We have inherited a background priority from the caller.
+                // Ensure this thread is in the background scheduling class,
+                // since the driver won't modify scheduling classes for us.
+                androidSetThreadSchedulingGroup(mMyThreadId,
+                        ANDROID_TGROUP_BG_NONINTERACT);
+            }
+            
             //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
             
             Parcel reply;
@@ -967,6 +983,13 @@
             mCallingPid = origPid;
             mCallingUid = origUid;
             
+            if (doBackground) {
+                // We moved to the background scheduling group to execute
+                // this transaction, so now that we are done go back in the
+                // foreground.
+                androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
+            }
+            
             IF_LOG_TRANSACTIONS() {
                 TextOutput::Bundle _b(alog);
                 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index ec3db09..6ca2603 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -20,6 +20,8 @@
 #include <utils/threads.h>
 #include <utils/Log.h>
 
+#include <cutils/sched_policy.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <memory.h>
@@ -269,6 +271,53 @@
     gCreateThreadFn = func;
 }
 
+pid_t androidGetTid()
+{
+#ifdef HAVE_GETTID
+    return gettid();
+#else
+    return getpid();
+#endif
+}
+
+int androidSetThreadSchedulingGroup(pid_t tid, int grp)
+{
+    if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
+        return BAD_VALUE;
+    }
+
+    if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+                                      SP_BACKGROUND : SP_FOREGROUND)) {
+        return PERMISSION_DENIED;
+    }
+    
+    return NO_ERROR;
+}
+
+int androidSetThreadPriority(pid_t tid, int pri)
+{
+    int rc = 0;
+    int lasterr = 0;
+
+    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
+        rc = set_sched_policy(tid, SP_BACKGROUND);
+    } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
+        rc = set_sched_policy(tid, SP_FOREGROUND);
+    }
+
+    if (rc) {
+        lasterr = errno;
+    }
+
+    if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
+        rc = INVALID_OPERATION;
+    } else {
+        errno = lasterr;
+    }
+    
+    return rc;
+}
+
 namespace android {
 
 /*
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index cd62ed1..7763549 100755
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -875,53 +875,51 @@
         synchronized(mListeners) {
             boolean wasNavigating = mNavigating;
             mNavigating = (status == GPS_STATUS_SESSION_BEGIN);
-    
-            if (wasNavigating == mNavigating) {
-                return;
-            }
-            
-            if (mNavigating) {
+
+            if (mNavigating && !mWakeLock.isHeld()) {
                 if (DEBUG) Log.d(TAG, "Acquiring wakelock");
                  mWakeLock.acquire();
             }
-        
-            int size = mListeners.size();
-            for (int i = 0; i < size; i++) {
-                Listener listener = mListeners.get(i);
+
+            if (wasNavigating != mNavigating) {
+                int size = mListeners.size();
+                for (int i = 0; i < size; i++) {
+                    Listener listener = mListeners.get(i);
+                    try {
+                        if (mNavigating) {
+                            listener.mListener.onGpsStarted();
+                        } else {
+                            listener.mListener.onGpsStopped();
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "RemoteException in reportStatus");
+                        mListeners.remove(listener);
+                        // adjust for size of list changing
+                        size--;
+                    }
+                }
+
                 try {
-                    if (mNavigating) {
-                        listener.mListener.onGpsStarted(); 
-                    } else {
-                        listener.mListener.onGpsStopped(); 
+                    // update battery stats
+                    for (int i=mClientUids.size() - 1; i >= 0; i--) {
+                        int uid = mClientUids.keyAt(i);
+                        if (mNavigating) {
+                            mBatteryStats.noteStartGps(uid);
+                        } else {
+                            mBatteryStats.noteStopGps(uid);
+                        }
                     }
                 } catch (RemoteException e) {
                     Log.w(TAG, "RemoteException in reportStatus");
-                    mListeners.remove(listener);
-                    // adjust for size of list changing
-                    size--;
                 }
+
+                // send an intent to notify that the GPS has been enabled or disabled.
+                Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION);
+                intent.putExtra(EXTRA_ENABLED, mNavigating);
+                mContext.sendBroadcast(intent);
             }
 
-            try {
-                // update battery stats
-                for (int i=mClientUids.size() - 1; i >= 0; i--) {
-                    int uid = mClientUids.keyAt(i);
-                    if (mNavigating) {
-                        mBatteryStats.noteStartGps(uid);
-                    } else {
-                        mBatteryStats.noteStopGps(uid);
-                    }
-                }
-            } catch (RemoteException e) {
-                Log.w(TAG, "RemoteException in reportStatus");
-            }
-
-            // send an intent to notify that the GPS has been enabled or disabled.
-            Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION);
-            intent.putExtra(EXTRA_ENABLED, mNavigating);
-            mContext.sendBroadcast(intent);
-
-            if (!mNavigating) {
+            if (status == GPS_STATUS_ENGINE_OFF && mWakeLock.isHeld()) {
                 if (DEBUG) Log.d(TAG, "Releasing wakelock");
                 mWakeLock.release();
             }
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index 130239e..37c2450 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -70,7 +70,7 @@
         return OK;
     }
 
-    fseek(mFile, SEEK_END, 0);
+    fseek(mFile, 0, SEEK_END);
     *size = ftello(mFile);
 
     return OK;
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 8dd8ea9..9dbefe4 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -33,6 +33,10 @@
 
 namespace android {
 
+// Everything must match except for
+// protection, bitrate, padding, private bits and mode extension.
+static const uint32_t kMask = 0xfffe0ccf;
+
 static bool get_mp3_frame_size(
         uint32_t header, size_t *frame_size,
         int *out_sampling_rate = NULL, int *out_channels = NULL,
@@ -60,7 +64,7 @@
     if (version == 0x01) {
         return false;
     }
-    
+
     unsigned layer = (header >> 17) & 3;
 
     if (layer == 0x00) {
@@ -199,13 +203,9 @@
         }
     }
 
-    // Everything must match except for
-    // protection, bitrate, padding, private bits and mode extension.
-    const uint32_t kMask = 0xfffe0ccf;
-
     const size_t kMaxFrameSize = 4096;
     uint8_t *buffer = new uint8_t[kMaxFrameSize];
-    
+
     off_t pos = *inout_pos - kMaxFrameSize;
     size_t buffer_offset = kMaxFrameSize;
     size_t buffer_length = kMaxFrameSize;
@@ -269,7 +269,7 @@
                 valid = false;
                 break;
             }
-            
+
             uint32_t test_header = U32_AT(tmp);
 
             LOGV("subsequent header is %08x", test_header);
@@ -489,8 +489,9 @@
         }
 
         uint32_t header = U32_AT((const uint8_t *)buffer->data());
-        
-        if (get_mp3_frame_size(header, &frame_size)) {
+
+        if ((header & kMask) == (mFixedHeader & kMask)
+            && get_mp3_frame_size(header, &frame_size)) {
             break;
         }
 
diff --git a/media/libstagefright/codecs/aacdec/AACDecoder.cpp b/media/libstagefright/codecs/aacdec/AACDecoder.cpp
index 03ac88d..5c77a3a 100644
--- a/media/libstagefright/codecs/aacdec/AACDecoder.cpp
+++ b/media/libstagefright/codecs/aacdec/AACDecoder.cpp
@@ -17,7 +17,7 @@
       mBufferGroup(NULL),
       mConfig(new tPVMP4AudioDecoderExternal),
       mDecoderBuf(NULL),
-      mLastSeekTimeUs(0),
+      mAnchorTimeUs(0),
       mNumSamplesOutput(0),
       mInputBuffer(NULL) {
 }
@@ -79,7 +79,7 @@
 
     mSource->start();
 
-    mLastSeekTimeUs = 0;
+    mAnchorTimeUs = 0;
     mNumSamplesOutput = 0;
     mStarted = true;
 
@@ -112,13 +112,16 @@
 
     int32_t numChannels;
     int32_t sampleRate;
+    int64_t durationUs;
     CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
     CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
+    CHECK(srcFormat->findInt64(kKeyDuration, &durationUs));
 
     sp<MetaData> meta = new MetaData;
     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
     meta->setInt32(kKeyChannelCount, numChannels);
     meta->setInt32(kKeySampleRate, sampleRate);
+    meta->setInt64(kKeyDuration, durationUs);
 
     return meta;
 }
@@ -150,11 +153,13 @@
             return err;
         }
 
-        if (seekTimeUs >= 0) {
-            CHECK(mInputBuffer->meta_data()->findInt64(
-                        kKeyTime, &mLastSeekTimeUs));
-
+        int64_t timeUs;
+        if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
+            mAnchorTimeUs = timeUs;
             mNumSamplesOutput = 0;
+        } else {
+            // We must have a new timestamp after seeking.
+            CHECK(seekTimeUs < 0);
         }
     }
 
@@ -189,7 +194,7 @@
 
     buffer->meta_data()->setInt64(
             kKeyTime,
-            mLastSeekTimeUs
+            mAnchorTimeUs
                 + (mNumSamplesOutput * 1000000) / mConfig->samplingRate);
 
     mNumSamplesOutput += mConfig->frameLength;
diff --git a/media/libstagefright/codecs/mp3dec/Android.mk b/media/libstagefright/codecs/mp3dec/Android.mk
index d618b83..cb2788c 100644
--- a/media/libstagefright/codecs/mp3dec/Android.mk
+++ b/media/libstagefright/codecs/mp3dec/Android.mk
@@ -28,10 +28,6 @@
  	src/pvmp3_seek_synch.cpp \
  	src/pvmp3_stereo_proc.cpp \
  	src/pvmp3_reorder.cpp \
- 	src/pvmp3_polyphase_filter_window.cpp \
- 	src/pvmp3_mdct_18.cpp \
- 	src/pvmp3_dct_9.cpp \
- 	src/pvmp3_dct_16.cpp
 
 ifeq ($(TARGET_ARCH),arm)
 LOCAL_SRC_FILES += \
@@ -39,6 +35,12 @@
  	src/asm/pvmp3_mdct_18_gcc.s \
  	src/asm/pvmp3_dct_9_gcc.s \
 	src/asm/pvmp3_dct_16_gcc.s
+else
+LOCAL_SRC_FILES += \
+ 	src/pvmp3_polyphase_filter_window.cpp \
+ 	src/pvmp3_mdct_18.cpp \
+ 	src/pvmp3_dct_9.cpp \
+ 	src/pvmp3_dct_16.cpp
 endif
 
 LOCAL_C_INCLUDES := \
diff --git a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
index 45e20dc..f9193c0 100644
--- a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
+++ b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
@@ -78,13 +78,16 @@
 
     int32_t numChannels;
     int32_t sampleRate;
+    int64_t durationUs;
     CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
     CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
+    CHECK(srcFormat->findInt64(kKeyDuration, &durationUs));
 
     sp<MetaData> meta = new MetaData;
     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
     meta->setInt32(kKeyChannelCount, numChannels);
     meta->setInt32(kKeySampleRate, sampleRate);
+    meta->setInt64(kKeyDuration, durationUs);
 
     return meta;
 }
@@ -120,6 +123,9 @@
         if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
             mAnchorTimeUs = timeUs;
             mNumSamplesOutput = 0;
+        } else {
+            // We must have a new timestamp after seeking.
+            CHECK(seekTimeUs < 0);
         }
     }
 
diff --git a/media/libstagefright/include/AACDecoder.h b/media/libstagefright/include/AACDecoder.h
index 303d854..f09addd 100644
--- a/media/libstagefright/include/AACDecoder.h
+++ b/media/libstagefright/include/AACDecoder.h
@@ -48,7 +48,7 @@
 
     tPVMP4AudioDecoderExternal *mConfig;
     void *mDecoderBuf;
-    int64_t mLastSeekTimeUs;
+    int64_t mAnchorTimeUs;
     int64_t mNumSamplesOutput;
 
     MediaBuffer *mInputBuffer;
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 676e5f6..27b631e 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -100,7 +100,7 @@
     private boolean mSystemReady;
     private ArrayList<Intent> mDeferredBroadcasts;
 
-    private class NetworkAttributes {
+    private static class NetworkAttributes {
         /**
          * Class for holding settings read from resources.
          */
@@ -108,6 +108,7 @@
         public int mType;
         public int mRadio;
         public int mPriority;
+        public NetworkInfo.State mLastState;
         public NetworkAttributes(String init) {
             String fragments[] = init.split(",");
             mName = fragments[0].toLowerCase();
@@ -128,6 +129,7 @@
                 mType = ConnectivityManager.TYPE_MOBILE_HIPRI;
             }
             mPriority = Integer.parseInt(fragments[2]);
+            mLastState = NetworkInfo.State.UNKNOWN;
         }
         public boolean isDefault() {
             return (mType == mRadio);
@@ -135,7 +137,7 @@
     }
     NetworkAttributes[] mNetAttributes;
 
-    private class RadioAttributes {
+    private static class RadioAttributes {
         public String mName;
         public int mPriority;
         public int mSimultaneity;
@@ -1213,9 +1215,22 @@
             switch (msg.what) {
                 case NetworkStateTracker.EVENT_STATE_CHANGED:
                     info = (NetworkInfo) msg.obj;
+                    int type = info.getType();
+                    NetworkInfo.State state = info.getState();
+                    if(mNetAttributes[type].mLastState == state) {
+                        if (DBG) {
+                            // TODO - remove this after we validate the dropping doesn't break anything
+                            Log.d(TAG, "Dropping ConnectivityChange for " +
+                                    info.getTypeName() +": " +
+                                    state + "/" + info.getDetailedState());
+                        }
+                        return;
+                    }
+                    mNetAttributes[type].mLastState = state;
+
                     if (DBG) Log.d(TAG, "ConnectivityChange for " +
                             info.getTypeName() + ": " +
-                            info.getState() + "/" + info.getDetailedState());
+                            state + "/" + info.getDetailedState());
 
                     // Connectivity state changed:
                     // [31-13] Reserved for future use
@@ -1233,10 +1248,9 @@
                     if (info.getDetailedState() ==
                             NetworkInfo.DetailedState.FAILED) {
                         handleConnectionFailure(info);
-                    } else if (info.getState() ==
-                            NetworkInfo.State.DISCONNECTED) {
+                    } else if (state == NetworkInfo.State.DISCONNECTED) {
                         handleDisconnect(info);
-                    } else if (info.getState() == NetworkInfo.State.SUSPENDED) {
+                    } else if (state == NetworkInfo.State.SUSPENDED) {
                         // TODO: need to think this over.
                         // the logic here is, handle SUSPENDED the same as
                         // DISCONNECTED. The only difference being we are
@@ -1245,7 +1259,7 @@
                         // opportunity to handle DISCONNECTED and SUSPENDED
                         // differently, or not.
                         handleDisconnect(info);
-                    } else if (info.getState() == NetworkInfo.State.CONNECTED) {
+                    } else if (state == NetworkInfo.State.CONNECTED) {
                         handleConnect(info);
                     }
                     break;
diff --git a/services/java/com/android/server/NetStatService.java b/services/java/com/android/server/NetStatService.java
index 1ea0bac..0834405 100644
--- a/services/java/com/android/server/NetStatService.java
+++ b/services/java/com/android/server/NetStatService.java
@@ -17,8 +17,8 @@
 package com.android.server;
 
 import android.content.Context;
+import android.net.TrafficStats;
 import android.os.INetStatService;
-import android.os.NetStat;
 
 public class NetStatService extends INetStatService.Stub {
 
@@ -27,34 +27,34 @@
     }
 
     public long getMobileTxPackets() {
-        return NetStat.getMobileTxPkts();
+        return TrafficStats.getMobileTxPkts();
     }
 
     public long getMobileRxPackets() {
-        return NetStat.getMobileRxPkts();
+        return TrafficStats.getMobileRxPkts();
     }
 
     public long getMobileTxBytes() {
-        return NetStat.getMobileTxBytes();
+        return TrafficStats.getMobileTxBytes();
     }
 
     public long getMobileRxBytes() {
-        return NetStat.getMobileRxBytes();
+        return TrafficStats.getMobileRxBytes();
     }
 
     public long getTotalTxPackets() {
-        return NetStat.getTotalTxPkts();
+        return TrafficStats.getTotalTxPkts();
     }
 
     public long getTotalRxPackets() {
-        return NetStat.getTotalRxPkts();
+        return TrafficStats.getTotalRxPkts();
     }
 
     public long getTotalTxBytes() {
-        return NetStat.getTotalTxBytes();
+        return TrafficStats.getTotalTxBytes();
     }
 
     public long getTotalRxBytes() {
-        return NetStat.getTotalRxBytes();
+        return TrafficStats.getTotalRxBytes();
     }
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 73f930d..214ecc1 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -18,6 +18,7 @@
 
 import com.android.server.am.ActivityManagerService;
 import com.android.server.status.StatusBarService;
+import com.android.internal.os.BinderInternal;
 import com.android.internal.os.SamplingProfilerIntegration;
 
 import dalvik.system.VMRuntime;
@@ -80,6 +81,8 @@
         android.os.Process.setThreadPriority(
                 android.os.Process.THREAD_PRIORITY_FOREGROUND);
 
+        BinderInternal.disableBackgroundScheduling(true);
+        
         String factoryTestStr = SystemProperties.get("ro.factorytest");
         int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
                 : Integer.parseInt(factoryTestStr);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 0ea832b..987a24e 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -25,6 +25,7 @@
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothDevice;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -62,6 +63,7 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.regex.Pattern;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -109,7 +111,7 @@
     private int mMulticastDisabled;
 
     private final IBatteryStats mBatteryStats;
-    
+
     /**
      * See {@link Settings.Gservices#WIFI_IDLE_MS}. This is the default value if a
      * Settings.Gservices value is not present. This timeout value is chosen as
@@ -162,7 +164,7 @@
      * Last UID that asked to enable WIFI.
      */
     private int mLastEnableUid = Process.myUid();
-    
+
     /**
      * Number of allowed radio frequency channels in various regulatory domains.
      * This list is sufficient for 802.11b/g networks (2.4GHz range).
@@ -177,7 +179,7 @@
         mWifiStateTracker = tracker;
         mWifiStateTracker.enableRssiPolling(true);
         mBatteryStats = BatteryStatsService.getService();
-        
+
         mScanResultCache = new LinkedHashMap<String, ScanResult>(
             SCAN_RESULT_CACHE_SIZE, 0.75f, true) {
                 /*
@@ -396,7 +398,7 @@
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
-        
+
         // Update state
         mWifiState = wifiState;
 
@@ -1380,11 +1382,16 @@
                 }
                 mPluggedType = pluggedType;
             } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
-                boolean isBluetoothPlaying =
-                        intent.getIntExtra(
-                                BluetoothA2dp.EXTRA_SINK_STATE,
-                                BluetoothA2dp.STATE_DISCONNECTED) == BluetoothA2dp.STATE_PLAYING;
+                BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+                Set<BluetoothDevice> sinks = a2dp.getConnectedSinks();
+                boolean isBluetoothPlaying = false;
+                for (BluetoothDevice sink : sinks) {
+                    if (a2dp.getSinkState(sink) == BluetoothA2dp.STATE_PLAYING) {
+                        isBluetoothPlaying = true;
+                    }
+                }
                 mWifiStateTracker.setBluetoothScanMode(isBluetoothPlaying);
+
             } else {
                 return;
             }
@@ -1396,7 +1403,7 @@
          * Determines whether the Wi-Fi chipset should stay awake or be put to
          * sleep. Looks at the setting for the sleep policy and the current
          * conditions.
-         * 
+         *
          * @see #shouldDeviceStayAwake(int, int)
          */
         private boolean shouldWifiStayAwake(int stayAwakeConditions, int pluggedType) {
@@ -1415,7 +1422,7 @@
                 return shouldDeviceStayAwake(stayAwakeConditions, pluggedType);
             }
         }
-        
+
         /**
          * Determine whether the bit value corresponding to {@code pluggedType} is set in
          * the bit string {@code stayAwakeConditions}. Because a {@code pluggedType} value
@@ -1509,7 +1516,7 @@
         intentFilter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
         mContext.registerReceiver(mReceiver, intentFilter);
     }
-    
+
     private boolean isAirplaneSensitive() {
         String airplaneModeRadios = Settings.System.getString(mContext.getContentResolver(),
                 Settings.System.AIRPLANE_MODE_RADIOS);
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index 2b9d18f..bee0930 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -283,7 +283,7 @@
     private IBinder mBluetoothIcon;
     private IconData mBluetoothData;
     private int mBluetoothHeadsetState;
-    private int mBluetoothA2dpState;
+    private boolean mBluetoothA2dpConnected;
     private int mBluetoothPbapState;
     private boolean mBluetoothEnabled;
 
@@ -455,7 +455,7 @@
         } else {
             mBluetoothEnabled = false;
         }
-        mBluetoothA2dpState = BluetoothA2dp.STATE_DISCONNECTED;
+        mBluetoothA2dpConnected = false;
         mBluetoothHeadsetState = BluetoothHeadset.STATE_DISCONNECTED;
         mBluetoothPbapState = BluetoothPbap.STATE_DISCONNECTED;
         mService.setIconVisibility(mBluetoothIcon, mBluetoothEnabled);
@@ -636,12 +636,12 @@
         int flags =  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                 | WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-        
+
         if (!mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_sf_slowBlur)) {
             flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
         }
-        
+
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.WRAP_CONTENT,
                 ViewGroup.LayoutParams.WRAP_CONTENT,
@@ -1083,7 +1083,6 @@
 
     private final void updateBluetooth(Intent intent) {
         int iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth;
-
         String action = intent.getAction();
         if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
             int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
@@ -1092,8 +1091,12 @@
             mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
                     BluetoothHeadset.STATE_ERROR);
         } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
-            mBluetoothA2dpState = intent.getIntExtra(BluetoothA2dp.EXTRA_SINK_STATE,
-                    BluetoothA2dp.STATE_DISCONNECTED);
+            BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+            if (a2dp.getConnectedSinks().size() != 0) {
+                mBluetoothA2dpConnected = true;
+            } else {
+                mBluetoothA2dpConnected = false;
+            }
         } else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
             mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE,
                     BluetoothPbap.STATE_DISCONNECTED);
@@ -1101,9 +1104,7 @@
             return;
         }
 
-        if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED ||
-                mBluetoothA2dpState == BluetoothA2dp.STATE_CONNECTED ||
-                mBluetoothA2dpState == BluetoothA2dp.STATE_PLAYING ||
+        if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED || mBluetoothA2dpConnected ||
                 mBluetoothPbapState == BluetoothPbap.STATE_CONNECTED) {
             iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth_connected;
         }