am a6433475: am 5c0f3e50: Merge "Cannot enable Bluetooth after using airplane and Bluetooth tethering sequentially" into jb-mr1.1-dev

* commit 'a64334756858b9fd3bad2c263feea00233699218':
  Cannot enable Bluetooth after using airplane and Bluetooth tethering sequentially
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index 69ccbc7..851c03c 100755
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -982,14 +982,9 @@
                 sendBluetoothStateCallback(isUp);
 
                 //If Bluetooth is off, send service down event to proxy objects, and unbind
-                if (!isUp) {
-                    //Only unbind with mEnable flag not set
-                    //For race condition: disable and enable back-to-back
-                    //Avoid unbind right after enable due to callback from disable
-                    if ((!mEnable) && (mBluetooth != null)) {
-                        sendBluetoothServiceDownCallback();
-                        unbindAndFinish();
-                    }
+                if (!isUp && canUnbindBluetoothService()) {
+                    sendBluetoothServiceDownCallback();
+                    unbindAndFinish();
                 }
             }
 
@@ -1037,4 +1032,22 @@
         Log.e(TAG,"waitForOnOff time out");
         return false;
     }
+
+    private boolean canUnbindBluetoothService() {
+        synchronized(mConnection) {
+            //Only unbind with mEnable flag not set
+            //For race condition: disable and enable back-to-back
+            //Avoid unbind right after enable due to callback from disable
+            //Only unbind with Bluetooth at OFF state
+            //Only unbind without any MESSAGE_BLUETOOTH_STATE_CHANGE message
+            try {
+                if (mEnable || (mBluetooth == null)) return false;
+                if (mHandler.hasMessages(MESSAGE_BLUETOOTH_STATE_CHANGE)) return false;
+                return (mBluetooth.getState() == BluetoothAdapter.STATE_OFF);
+            } catch (RemoteException e) {
+                Log.e(TAG, "getState()", e);
+            }
+        }
+        return false;
+    }
 }