Merge "Make sure live streamed http live content does not start playing from the very beginning."
diff --git a/api/current.xml b/api/current.xml
index d2bd8e5..357daae 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -21911,47 +21911,6 @@
 <parameter name="exitAnim" type="int">
 </parameter>
 </method>
-<method name="popBackStack"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-</method>
-<method name="popBackStack"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-<parameter name="name" type="java.lang.String">
-</parameter>
-<parameter name="flags" type="int">
-</parameter>
-</method>
-<method name="popBackStack"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-<parameter name="id" type="int">
-</parameter>
-<parameter name="flags" type="int">
-</parameter>
-</method>
 <method name="registerForContextMenu"
  return="void"
  abstract="false"
@@ -22637,17 +22596,6 @@
  visibility="protected"
 >
 </field>
-<field name="POP_BACK_STACK_INCLUSIVE"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="RESULT_CANCELED"
  type="int"
  transient="false"
@@ -28360,6 +28308,17 @@
 <parameter name="args" type="java.lang.String[]">
 </parameter>
 </method>
+<method name="executePendingTransactions"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="findFragmentById"
  return="android.app.Fragment"
  abstract="true"
@@ -28426,7 +28385,7 @@
 >
 </method>
 <method name="popBackStack"
- return="boolean"
+ return="void"
  abstract="true"
  native="false"
  synchronized="false"
@@ -28437,7 +28396,7 @@
 >
 </method>
 <method name="popBackStack"
- return="boolean"
+ return="void"
  abstract="true"
  native="false"
  synchronized="false"
@@ -28452,6 +28411,47 @@
 </parameter>
 </method>
 <method name="popBackStack"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="id" type="int">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="popBackStackImmediate"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="popBackStackImmediate"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="popBackStackImmediate"
  return="boolean"
  abstract="true"
  native="false"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 07d21fb..5174f19 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2086,63 +2086,12 @@
     }
     
     /**
-     * Flag for {@link #popBackStack(String, int)}
-     * and {@link #popBackStack(int, int)}: If set, and the name or ID of
-     * a back stack entry has been supplied, then all matching entries will
-     * be consumed until one that doesn't match is found or the bottom of
-     * the stack is reached.  Otherwise, all entries up to but not including that entry
-     * will be removed.
-     */
-    public static final int POP_BACK_STACK_INCLUSIVE = 1<<0;
-
-    /**
-     * Pop the top state off the back stack.  Returns true if there was one
-     * to pop, else false.
-     * @deprecated use {@link #getFragmentManager}.
-     */
-    @Deprecated
-    public boolean popBackStack() {
-        return mFragments.popBackStack();
-    }
-
-    /**
-     * Pop the last fragment transition from the local activity's fragment
-     * back stack.  If there is nothing to pop, false is returned.
-     * @param name If non-null, this is the name of a previous back state
-     * to look for; if found, all states up to that state will be popped.  The
-     * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
-     * the named state itself is popped. If null, only the top state is popped.
-     * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
-     * @deprecated use {@link #getFragmentManager}.
-     */
-    @Deprecated
-    public boolean popBackStack(String name, int flags) {
-        return mFragments.popBackStack(name, flags);
-    }
-
-    /**
-     * Pop all back stack states up to the one with the given identifier.
-     * @param id Identifier of the stated to be popped. If no identifier exists,
-     * false is returned.
-     * The identifier is the number returned by
-     * {@link FragmentTransaction#commit() FragmentTransaction.commit()}.  The
-     * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
-     * the named state itself is popped.
-     * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
-     * @deprecated use {@link #getFragmentManager}.
-     */
-    @Deprecated
-    public boolean popBackStack(int id, int flags) {
-        return mFragments.popBackStack(id, flags);
-    }
-    
-    /**
      * Called when the activity has detected the user's press of the back
      * key.  The default implementation simply finishes the current activity,
      * but you can override this to do whatever you want.
      */
     public void onBackPressed() {
-        if (!mFragments.popBackStack()) {
+        if (!mFragments.popBackStackImmediate()) {
             finish();
         }
     }
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 9970418..d3a4f33 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -22,6 +22,7 @@
 import android.content.res.TypedArray;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
@@ -99,6 +100,20 @@
     public abstract FragmentTransaction openTransaction();
 
     /**
+     * After a {@link FragmentTransaction} is committed with
+     * {@link FragmentTransaction#commit FragmentTransaction.commit()}, it
+     * is scheduled to be executed asynchronously on the process's main thread.
+     * If you want to immediately executing any such pending operations, you
+     * can call this function (only from the main thread) to do so.  Note that
+     * all callbacks and other related behavior will be done from within this
+     * call, so be careful about where this is called from.
+     *
+     * @return Returns true if there were any pending transactions to be
+     * executed.
+     */
+    public abstract boolean executePendingTransactions();
+
+    /**
      * Finds a fragment that was identified by the given id either when inflated
      * from XML or as the container ID when added in a transaction.  This first
      * searches through fragments that are currently added to the manager's
@@ -132,7 +147,15 @@
      * Pop the top state off the back stack.  Returns true if there was one
      * to pop, else false.
      */
-    public abstract boolean popBackStack();
+    public abstract void popBackStack();
+
+    /**
+     * Like {@link #popBackStack()}, but performs the operation immediately
+     * inside of the call.  This is like calling {@link #executePendingTransactions()}
+     * afterwards.
+     * @return Returns true if there was something popped, else false.
+     */
+    public abstract boolean popBackStackImmediate();
 
     /**
      * Pop the last fragment transition from the manager's fragment
@@ -143,7 +166,15 @@
      * the named state itself is popped. If null, only the top state is popped.
      * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
      */
-    public abstract boolean popBackStack(String name, int flags);
+    public abstract void popBackStack(String name, int flags);
+
+    /**
+     * Like {@link #popBackStack(String, int)}, but performs the operation immediately
+     * inside of the call.  This is like calling {@link #executePendingTransactions()}
+     * afterwards.
+     * @return Returns true if there was something popped, else false.
+     */
+    public abstract boolean popBackStackImmediate(String name, int flags);
 
     /**
      * Pop all back stack states up to the one with the given identifier.
@@ -155,7 +186,15 @@
      * the named state itself is popped.
      * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
      */
-    public abstract boolean popBackStack(int id, int flags);
+    public abstract void popBackStack(int id, int flags);
+
+    /**
+     * Like {@link #popBackStack(int, int)}, but performs the operation immediately
+     * inside of the call.  This is like calling {@link #executePendingTransactions()}
+     * afterwards.
+     * @return Returns true if there was something popped, else false.
+     */
+    public abstract boolean popBackStackImmediate(int id, int flags);
 
     /**
      * Return the number of entries currently in the back stack.
@@ -300,17 +339,58 @@
     }
 
     @Override
-    public boolean popBackStack() {
+    public boolean executePendingTransactions() {
+        return execPendingActions();
+    }
+
+    @Override
+    public void popBackStack() {
+        enqueueAction(new Runnable() {
+            @Override public void run() {
+                popBackStackState(mActivity.mHandler, null, -1, 0);
+            }
+        }, false);
+    }
+
+    @Override
+    public boolean popBackStackImmediate() {
+        checkStateLoss();
+        executePendingTransactions();
         return popBackStackState(mActivity.mHandler, null, -1, 0);
     }
 
     @Override
-    public boolean popBackStack(String name, int flags) {
+    public void popBackStack(final String name, final int flags) {
+        enqueueAction(new Runnable() {
+            @Override public void run() {
+                popBackStackState(mActivity.mHandler, name, -1, flags);
+            }
+        }, false);
+    }
+
+    @Override
+    public boolean popBackStackImmediate(String name, int flags) {
+        checkStateLoss();
+        executePendingTransactions();
         return popBackStackState(mActivity.mHandler, name, -1, flags);
     }
 
     @Override
-    public boolean popBackStack(int id, int flags) {
+    public void popBackStack(final int id, final int flags) {
+        if (id < 0) {
+            throw new IllegalArgumentException("Bad id: " + id);
+        }
+        enqueueAction(new Runnable() {
+            @Override public void run() {
+                popBackStackState(mActivity.mHandler, null, id, flags);
+            }
+        }, false);
+    }
+
+    @Override
+    public boolean popBackStackImmediate(int id, int flags) {
+        checkStateLoss();
+        executePendingTransactions();
         if (id < 0) {
             throw new IllegalArgumentException("Bad id: " + id);
         }
@@ -849,16 +929,20 @@
         return null;
     }
     
+    private void checkStateLoss() {
+        if (mStateSaved) {
+            throw new IllegalStateException(
+                    "Can not perform this action after onSaveInstanceState");
+        }
+        if (mNoTransactionsBecause != null) {
+            throw new IllegalStateException(
+                    "Can not perform this action inside of " + mNoTransactionsBecause);
+        }
+    }
+
     public void enqueueAction(Runnable action, boolean allowStateLoss) {
         if (!allowStateLoss) {
-            if (mStateSaved) {
-                throw new IllegalStateException(
-                        "Can not perform this action after onSaveInstanceState");
-            }
-            if (mNoTransactionsBecause != null) {
-                throw new IllegalStateException(
-                        "Can not perform this action inside of " + mNoTransactionsBecause);
-            }
+            checkStateLoss();
         }
         synchronized (this) {
             if (mActivity == null) {
@@ -934,17 +1018,23 @@
     /**
      * Only call from main thread!
      */
-    public void execPendingActions() {
+    public boolean execPendingActions() {
         if (mExecutingActions) {
-            throw new IllegalStateException("Recursive entry to execPendingActions");
+            throw new IllegalStateException("Recursive entry to executePendingTransactions");
         }
         
+        if (Looper.myLooper() != Looper.getMainLooper()) {
+            throw new IllegalStateException("Must be called from main thread of process");
+        }
+
+        boolean didSomething = false;
+
         while (true) {
             int numActions;
             
             synchronized (this) {
                 if (mPendingActions == null || mPendingActions.size() == 0) {
-                    return;
+                    return didSomething;
                 }
                 
                 numActions = mPendingActions.size();
@@ -961,6 +1051,7 @@
                 mTmpActions[i].run();
             }
             mExecutingActions = false;
+            didSomething = true;
         }
     }
     
@@ -984,19 +1075,14 @@
         if (mBackStack == null) {
             return false;
         }
-        if (name == null && id < 0 && (flags&Activity.POP_BACK_STACK_INCLUSIVE) == 0) {
+        if (name == null && id < 0 && (flags&POP_BACK_STACK_INCLUSIVE) == 0) {
             int last = mBackStack.size()-1;
             if (last < 0) {
                 return false;
             }
             final BackStackRecord bss = mBackStack.remove(last);
-            enqueueAction(new Runnable() {
-                public void run() {
-                    if (DEBUG) Log.v(TAG, "Popping back stack state: " + bss);
-                    bss.popFromBackStack(true);
-                    reportBackStackChanged();
-                }
-            }, false);
+            bss.popFromBackStack(true);
+            reportBackStackChanged();
         } else {
             int index = -1;
             if (name != null || id >= 0) {
@@ -1016,7 +1102,7 @@
                 if (index < 0) {
                     return false;
                 }
-                if ((flags&Activity.POP_BACK_STACK_INCLUSIVE) != 0) {
+                if ((flags&POP_BACK_STACK_INCLUSIVE) != 0) {
                     index--;
                     // Consume all following entries that match.
                     while (index >= 0) {
@@ -1038,16 +1124,12 @@
             for (int i=mBackStack.size()-1; i>index; i--) {
                 states.add(mBackStack.remove(i));
             }
-            enqueueAction(new Runnable() {
-                public void run() {
-                    final int LAST = states.size()-1;
-                    for (int i=0; i<=LAST; i++) {
-                        if (DEBUG) Log.v(TAG, "Popping back stack state: " + states.get(i));
-                        states.get(i).popFromBackStack(i == LAST);
-                    }
-                    reportBackStackChanged();
-                }
-            }, false);
+            final int LAST = states.size()-1;
+            for (int i=0; i<=LAST; i++) {
+                if (DEBUG) Log.v(TAG, "Popping back stack state: " + states.get(i));
+                states.get(i).popFromBackStack(i == LAST);
+            }
+            reportBackStackChanged();
         }
         return true;
     }
@@ -1084,6 +1166,10 @@
     }
     
     Parcelable saveAllState() {
+        // Make sure all pending operations have now been executed to get
+        // our state update-to-date.
+        execPendingActions();
+
         mStateSaved = true;
 
         if (mActive == null || mActive.size() <= 0) {
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 0ce69ad..39f3cee 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -23,6 +23,7 @@
 
 import android.app.Fragment;
 import android.app.FragmentBreadCrumbs;
+import android.app.FragmentManager;
 import android.app.FragmentTransaction;
 import android.app.ListActivity;
 import android.content.Context;
@@ -902,7 +903,8 @@
     }
 
     private void switchToHeaderInner(String fragmentName, Bundle args, int direction) {
-        getFragmentManager().popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE);
+        getFragmentManager().popBackStack(BACK_STACK_PREFS,
+                FragmentManager.POP_BACK_STACK_INCLUSIVE);
         Fragment f = Fragment.instantiate(this, fragmentName, args);
         FragmentTransaction transaction = getFragmentManager().openTransaction();
         transaction.setTransition(direction == 0 ? FragmentTransaction.TRANSIT_NONE
@@ -934,7 +936,8 @@
         if (mCurHeader == header) {
             // This is the header we are currently displaying.  Just make sure
             // to pop the stack up to its root state.
-            getFragmentManager().popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE);
+            getFragmentManager().popBackStack(BACK_STACK_PREFS,
+                    FragmentManager.POP_BACK_STACK_INCLUSIVE);
         } else {
             int direction = mHeaders.indexOf(header) - mHeaders.indexOf(mCurHeader);
             switchToHeaderInner(header.fragment, header.fragmentArguments, direction);
@@ -1061,14 +1064,14 @@
             setResult(resultCode, resultData);
             finish();
         } else {
+            // XXX be smarter about popping the stack.
+            onBackPressed();
             if (caller != null) {
                 if (caller.getTargetFragment() != null) {
                     caller.getTargetFragment().onActivityResult(caller.getTargetRequestCode(),
                             resultCode, resultData);
                 }
             }
-            // XXX be smarter about popping the stack.
-            onBackPressed();
         }
     }
     
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 1d103ed..1406e4e 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -110,8 +110,10 @@
         if (isShowing()) {
             mPopup.dismiss();
         }
-        mTreeObserver.removeGlobalOnLayoutListener(this);
-        mTreeObserver = null;
+        if (mTreeObserver != null) {
+            mTreeObserver.removeGlobalOnLayoutListener(this);
+            mTreeObserver = null;
+        }
     }
 
     public boolean isShowing() {
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
index f019599..43cf06a 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
@@ -110,6 +110,21 @@
         mTestUtils.disable(adapter);
     }
 
+    public void testAcceptPair() {
+        int iterations = BluetoothTestRunner.sPairIterations;
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sPairAddress);
+        mTestUtils.enable(adapter);
+
+        for (int i = 0; i < iterations; i++) {
+            mTestUtils.writeOutput("acceptPair iteration " + (i + 1) + " of " + iterations);
+            mTestUtils.acceptPair(adapter, device, BluetoothTestRunner.sPairPasskey,
+                    BluetoothTestRunner.sPairPin);
+            mTestUtils.unpair(adapter, device);
+        }
+        mTestUtils.disable(adapter);
+    }
+
     public void testConnectA2dp() {
         int iterations = BluetoothTestRunner.sConnectA2dpIterations;
         if (iterations == 0) {
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
index 328891c..29dee34 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
@@ -137,7 +137,6 @@
 
         @Override
         public void onReceive(Context context, Intent intent) {
-            Log.i("BT", intent.toString());
             if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction())) {
                 setFiredFlag(DISCOVERY_STARTED_FLAG);
             } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) {
@@ -203,7 +202,7 @@
             if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(intent.getAction())) {
                 int varient = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, -1);
                 assertNotSame(-1, varient);
-                switch(varient) {
+                switch (varient) {
                     case BluetoothDevice.PAIRING_VARIANT_PIN:
                         mDevice.setPin(mPin);
                         break;
@@ -252,7 +251,7 @@
             mDevice = device;
             mProfile = profile;
 
-            switch(mProfile) {
+            switch (mProfile) {
                 case BluetoothProfile.A2DP:
                     mConnectionAction = BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED;
                     break;
@@ -384,11 +383,14 @@
                 mask = 0; // Don't check for received intents since we might have missed them.
                 break;
             case BluetoothAdapter.STATE_OFF:
-            case BluetoothAdapter.STATE_TURNING_OFF:
                 assertFalse(adapter.isEnabled());
                 start = System.currentTimeMillis();
                 assertTrue(adapter.enable());
                 break;
+            case BluetoothAdapter.STATE_TURNING_OFF:
+                start = System.currentTimeMillis();
+                assertTrue(adapter.enable());
+                break;
             default:
                 removeReceiver(receiver);
                 fail(String.format("enable() invalid state: state=%d", state));
@@ -410,7 +412,6 @@
                     return;
                 }
             } else {
-                assertFalse(adapter.isEnabled());
                 assertEquals(BluetoothAdapter.STATE_TURNING_ON, state);
             }
             sleep(POLL_TIME);
@@ -437,7 +438,6 @@
             case BluetoothAdapter.STATE_TURNING_ON:
                 assertFalse(adapter.isEnabled());
                 start = System.currentTimeMillis();
-                assertTrue(adapter.disable());
                 break;
             case BluetoothAdapter.STATE_ON:
                 assertTrue(adapter.isEnabled());
@@ -470,7 +470,6 @@
                     return;
                 }
             } else {
-                assertFalse(adapter.isEnabled());
                 assertEquals(BluetoothAdapter.STATE_TURNING_OFF, state);
             }
             sleep(POLL_TIME);
@@ -629,11 +628,22 @@
     }
 
     public void pair(BluetoothAdapter adapter, BluetoothDevice device, int passkey, byte[] pin) {
+        pairOrAcceptPair(adapter, device, passkey, pin, true);
+    }
+
+    public void acceptPair(BluetoothAdapter adapter, BluetoothDevice device, int passkey,
+            byte[] pin) {
+        pairOrAcceptPair(adapter, device, passkey, pin, false);
+    }
+
+    private void pairOrAcceptPair(BluetoothAdapter adapter, BluetoothDevice device, int passkey,
+            byte[] pin, boolean pair) {
         int mask = PairReceiver.STATE_BONDING_FLAG | PairReceiver.STATE_BONDED_FLAG;
         long start = -1;
+        String methodName = pair ? "pair()" : "acceptPair()";
 
         if (!adapter.isEnabled()) {
-            fail("pair() bluetooth not enabled");
+            fail(methodName + " bluetooth not enabled");
         }
 
         PairReceiver receiver = getPairReceiver(device, passkey, pin, mask);
@@ -643,7 +653,9 @@
             case BluetoothDevice.BOND_NONE:
                 assertFalse(adapter.getBondedDevices().contains(device));
                 start = System.currentTimeMillis();
-                assertTrue(device.createBond());
+                if (pair) {
+                    assertTrue(device.createBond());
+                }
                 break;
             case BluetoothDevice.BOND_BONDING:
                 mask = 0; // Don't check for received intents since we might have missed them.
@@ -653,7 +665,8 @@
                 return;
             default:
                 removeReceiver(receiver);
-                fail(String.format("pair() invalid state: device=%s, state=%d", device, state));
+                fail(String.format("%s invalid state: device=%s, state=%d", methodName, device,
+                        state));
         }
 
         long s = System.currentTimeMillis();
@@ -664,10 +677,10 @@
                 if ((receiver.getFiredFlags() & mask) == mask) {
                     long finish = receiver.getCompletedTime();
                     if (start != -1 && finish != -1) {
-                        writeOutput(String.format("pair() completed in %d ms: device=%s",
+                        writeOutput(String.format("%s completed in %d ms: device=%s", methodName,
                                 (finish - start), device));
                     } else {
-                        writeOutput(String.format("pair() completed: device=%s", device));
+                        writeOutput(String.format("%s completed: device=%s", methodName, device));
                     }
                     removeReceiver(receiver);
                     return;
@@ -678,9 +691,9 @@
 
         int firedFlags = receiver.getFiredFlags();
         removeReceiver(receiver);
-        fail(String.format("pair() timeout: device=%s, state=%d (expected %d), "
-                + "flags=0x%x (expected 0x%x)", device, state, BluetoothDevice.BOND_BONDED,
-                firedFlags, mask));
+        fail(String.format("%s timeout: device=%s, state=%d (expected %d), "
+                + "flags=0x%x (expected 0x%x)", methodName, device, state,
+                BluetoothDevice.BOND_BONDED, firedFlags, mask));
     }
 
     public void unpair(BluetoothAdapter adapter, BluetoothDevice device) {
@@ -788,7 +801,7 @@
                     long finish = receiver.getCompletedTime();
                     if (start != -1 && finish != -1) {
                         writeOutput(String.format("connectProfile() completed in %d ms: "
-                                +"device=%s, profile=%d", (finish - start), device, profile));
+                                + "device=%s, profile=%d", (finish - start), device, profile));
                     } else {
                         writeOutput(String.format("connectProfile() completed: device=%s, "
                                 + "profile=%d", device, profile));
@@ -857,7 +870,7 @@
                     long finish = receiver.getCompletedTime();
                     if (start != -1 && finish != -1) {
                         writeOutput(String.format("disconnectProfile() completed in %d ms: "
-                                +"device=%s, profile=%d", (finish - start), device, profile));
+                                + "device=%s, profile=%d", (finish - start), device, profile));
                     } else {
                         writeOutput(String.format("disconnectProfile() completed: device=%s, "
                                 + "profile=%d", device, profile));
@@ -934,14 +947,12 @@
         long s = System.currentTimeMillis();
         switch (profile) {
             case BluetoothProfile.A2DP:
-                while (mA2dp != null
-                        && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+                while (mA2dp != null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
                     sleep(POLL_TIME);
                 }
                 return mA2dp;
             case BluetoothProfile.HEADSET:
-                while (mHeadset != null
-                        && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+                while (mHeadset != null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
                     sleep(POLL_TIME);
                 }
                 return mHeadset;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index bb39c8f..18815f5 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1832,7 +1832,12 @@
             }
 
             final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
-            ActionMode mode = getCallback().onWindowStartingActionMode(wrappedCallback);
+            ActionMode mode = null;
+            try {
+                mode = getCallback().onWindowStartingActionMode(wrappedCallback);
+            } catch (AbstractMethodError ame) {
+                // Older apps might not implement this callback method.
+            }
             if (mode != null) {
                 mActionMode = mode;
             } else {
@@ -1877,7 +1882,11 @@
                 }
             }
             if (mActionMode != null) {
-                getCallback().onActionModeStarted(mActionMode);
+                try {
+                    getCallback().onActionModeStarted(mActionMode);
+                } catch (AbstractMethodError ame) {
+                    // Older apps might not implement this callback method.
+                }
             }
             return mActionMode;
         }
@@ -2094,7 +2103,11 @@
                 if (mActionModeView != null) {
                     mActionModeView.removeAllViews();
                 }
-                getCallback().onActionModeFinished(mActionMode);
+                try {
+                    getCallback().onActionModeFinished(mActionMode);
+                } catch (AbstractMethodError ame) {
+                    // Older apps might not implement this callback method.
+                }
                 mActionMode = null;
             }
         }