summaryrefslogtreecommitdiff
path: root/service/java/com/android/server/bluetooth/BluetoothManagerService.java
diff options
context:
space:
mode:
authorPavlin Radoslavov <pavlin@google.com>2016-06-01 22:25:18 -0700
committerPavlin Radoslavov <pavlin@google.com>2016-06-02 14:56:31 -0700
commita4201975ca287ca4d3640a3800e6d379a8f4f80a (patch)
tree5868fa74fc773fe9154ea4d9019428b5c9110678 /service/java/com/android/server/bluetooth/BluetoothManagerService.java
parent630c0a3a0748855515a6544da3380c12f83a619e (diff)
Delay handleEnable() until Bluetooth state is OFF
During shutdown of the Bluetooth stack, if a request to enable Bluetooth is received, the request is processed immediately. As a result, we don't let the Bluetooth service to shutdown cleanly, and the Bluetooth process with the native backend doesn't go away. This creates various issues in the native backend stack. Now, after an enable request is received, if necessary we delay acting on it, until the Bluetooth state is OFF. Bug: 17723234 Change-Id: I55db4bbd4f45227aa49eae996dcc328f76557a9b
Diffstat (limited to 'service/java/com/android/server/bluetooth/BluetoothManagerService.java')
-rw-r--r--service/java/com/android/server/bluetooth/BluetoothManagerService.java72
1 files changed, 31 insertions, 41 deletions
diff --git a/service/java/com/android/server/bluetooth/BluetoothManagerService.java b/service/java/com/android/server/bluetooth/BluetoothManagerService.java
index 1f88be55ec..3eadb5ca73 100644
--- a/service/java/com/android/server/bluetooth/BluetoothManagerService.java
+++ b/service/java/com/android/server/bluetooth/BluetoothManagerService.java
@@ -639,19 +639,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
Slog.d(TAG,"enable(): mBluetooth =" + mBluetooth +
" mBinding = " + mBinding + " mState = " + mState);
}
- // We do not honor ON requests when the adapter is already turned ON or in the process of
- // turning ON.
- // As a protective mechanism to make sure that the native stack gets cleaned up properly
- // before turning it back ON we ignore requests while the bluetooth is turning OFF.
- // Bug: b/28318203
- if (mState == BluetoothAdapter.STATE_BLE_TURNING_OFF ||
- mState == BluetoothAdapter.STATE_TURNING_OFF ||
- mState == BluetoothAdapter.STATE_ON ||
- mState == BluetoothAdapter.STATE_BLE_ON ||
- mState == BluetoothAdapter.STATE_TURNING_ON ||
- mState == BluetoothAdapter.STATE_BLE_TURNING_ON) {
- return false;
- }
synchronized(mReceiver) {
mQuietEnableExternal = false;
@@ -701,6 +688,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mBluetoothLock.writeLock().lock();
if (mUnbinding) return;
mUnbinding = true;
+ mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
if (mBluetooth != null) {
//Unregister callback object
try {
@@ -1165,7 +1153,31 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mEnable = true;
- handleEnable(msg.arg1 == 1);
+ if (mBluetooth == null) {
+ handleEnable(msg.arg1 == 1);
+ } else {
+ //
+ // We need to wait until transitioned to STATE_OFF and
+ // the previous Bluetooth process has exited. The
+ // waiting period has three components:
+ // (a) Wait until the local state is STATE_OFF. This
+ // is accomplished by "waitForOnOff(false, true)".
+ // (b) Wait until the STATE_OFF state is updated to
+ // all components.
+ // (c) Wait until the Bluetooth process exits, and
+ // ActivityManager detects it.
+ // The waiting for (b) and (c) is accomplished by
+ // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
+ // message. On slower devices, that delay needs to be
+ // on the order of (2 * SERVICE_RESTART_TIME_MS).
+ //
+ waitForOnOff(false, true);
+ mQuietEnable = (msg.arg1 == 1);
+ Message restartMsg = mHandler.obtainMessage(
+ MESSAGE_RESTART_BLUETOOTH_SERVICE);
+ mHandler.sendMessageDelayed(restartMsg,
+ 2 * SERVICE_RESTART_TIME_MS);
+ }
break;
case MESSAGE_DISABLE:
@@ -1617,14 +1629,11 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (newState == BluetoothAdapter.STATE_OFF) {
// If Bluetooth is off, send service down event to proxy objects, and unbind
if (DBG) Slog.d(TAG, "Bluetooth is complete turn off");
- if (canUnbindBluetoothService()) {
- if (DBG) Slog.d(TAG, "Good to unbind!");
- sendBluetoothServiceDownCallback();
- unbindAndFinish();
- sendBleStateChanged(prevState, newState);
- // Don't broadcast as it has already been broadcast before
- isStandardBroadcast = false;
- }
+ sendBluetoothServiceDownCallback();
+ unbindAndFinish();
+ sendBleStateChanged(prevState, newState);
+ // Don't broadcast as it has already been broadcast before
+ isStandardBroadcast = false;
} else if (!intermediate_off) {
// connect to GattService
@@ -1726,25 +1735,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
quietMode ? 1 : 0, 0));
}
- private boolean canUnbindBluetoothService() {
- try {
- //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
- mBluetoothLock.readLock().lock();
- if (mEnable || (mBluetooth == null)) return false;
- if (mHandler.hasMessages(MESSAGE_BLUETOOTH_STATE_CHANGE)) return false;
- return (mBluetooth.getState() == BluetoothAdapter.STATE_OFF);
- } catch (RemoteException e) {
- Slog.e(TAG, "getState()", e);
- } finally {
- mBluetoothLock.readLock().unlock();
- }
- return false;
- }
-
private void recoverBluetoothServiceFromError() {
Slog.e(TAG,"recoverBluetoothServiceFromError");
try {