diff options
author | Calvin On <con@google.com> | 2016-06-15 17:58:23 -0700 |
---|---|---|
committer | Andre Eisenbach <eisenbach@google.com> | 2016-06-17 21:18:21 +0000 |
commit | 20f11b34f738d5586e0ad6b1cd50bbe4239de58d (patch) | |
tree | 042c4b5755d93b423389f029c426b0b1344d3537 /service/java/com/android/server/bluetooth/BluetoothManagerService.java | |
parent | c5ad1f87b25822ff086c75f5c165d131db0251da (diff) |
Fix race with BT disable in BLE_ON_STATE
This will restart the BT stack when it detects a transition
into OFF state while the user enable flag (mEnable) is set.
Bug: 29363429
Change-Id: I9839119b34c4694ad92e96240c6989008b2f8d52
Diffstat (limited to 'service/java/com/android/server/bluetooth/BluetoothManagerService.java')
-rw-r--r-- | service/java/com/android/server/bluetooth/BluetoothManagerService.java | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/service/java/com/android/server/bluetooth/BluetoothManagerService.java b/service/java/com/android/server/bluetooth/BluetoothManagerService.java index 9154b8eced..59e4f28496 100644 --- a/service/java/com/android/server/bluetooth/BluetoothManagerService.java +++ b/service/java/com/android/server/bluetooth/BluetoothManagerService.java @@ -1153,8 +1153,27 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); mEnable = true; + + // Use service interface to get the exact state + try { + mBluetoothLock.readLock().lock(); + if (mBluetooth != null) { + int state = mBluetooth.getState(); + if (state == BluetoothAdapter.STATE_BLE_ON) { + Slog.w(TAG, "BT is in BLE_ON State"); + mBluetooth.onLeServiceUp(); + break; + } + } + } catch (RemoteException e) { + Slog.e(TAG, "", e); + } finally { + mBluetoothLock.readLock().unlock(); + } + + mQuietEnable = (msg.arg1 == 1); if (mBluetooth == null) { - handleEnable(msg.arg1 == 1); + handleEnable(mQuietEnable); } else { // // We need to wait until transitioned to STATE_OFF and @@ -1172,7 +1191,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // 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, @@ -1335,17 +1353,30 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // handle error state transition case from TURNING_ON to OFF // unbind and rebind bluetooth service and enable bluetooth if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && - (newState == BluetoothAdapter.STATE_OFF) && - (mBluetooth != null) && mEnable) { + (newState == BluetoothAdapter.STATE_OFF) && + (mBluetooth != null) && mEnable) { recoverBluetoothServiceFromError(); } if ((prevState == BluetoothAdapter.STATE_TURNING_ON) && - (newState == BluetoothAdapter.STATE_BLE_ON) && - (mBluetooth != null) && mEnable) { + (newState == BluetoothAdapter.STATE_BLE_ON) && + (mBluetooth != null) && mEnable) { recoverBluetoothServiceFromError(); } + // If we tried to enable BT while BT was in the process of shutting down, + // wait for the BT process to fully tear down and then force a restart + // here. This is a bit of a hack (b/29363429). + if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && + (newState == BluetoothAdapter.STATE_OFF)) { + if (mEnable) { + Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting."); + waitForOnOff(false, true); + Message restartMsg = mHandler.obtainMessage( + MESSAGE_RESTART_BLUETOOTH_SERVICE); + mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS); + } + } if (newState == BluetoothAdapter.STATE_ON || - newState == BluetoothAdapter.STATE_BLE_ON) { + newState == BluetoothAdapter.STATE_BLE_ON) { // bluetooth is working, reset the counter if (mErrorRecoveryRetryCounter != 0) { Slog.w(TAG, "bluetooth is recovered from error"); @@ -1388,7 +1419,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // Send BT state broadcast to update // the BT icon correctly if ((mState == BluetoothAdapter.STATE_TURNING_ON) || - (mState == BluetoothAdapter.STATE_ON)) { + (mState == BluetoothAdapter.STATE_ON)) { bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, BluetoothAdapter.STATE_TURNING_OFF); mState = BluetoothAdapter.STATE_TURNING_OFF; @@ -1621,8 +1652,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { boolean isStandardBroadcast = true; if (prevState != newState) { //Notify all proxy objects first of adapter state change - if (newState == BluetoothAdapter.STATE_BLE_ON - || newState == BluetoothAdapter.STATE_OFF) { + if (newState == BluetoothAdapter.STATE_BLE_ON || + newState == BluetoothAdapter.STATE_OFF) { boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF && newState == BluetoothAdapter.STATE_BLE_ON); @@ -1667,13 +1698,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub { sendBluetoothStateCallback(isUp); sendBleStateChanged(prevState, newState); - } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON - || newState == BluetoothAdapter.STATE_BLE_TURNING_OFF ) { + } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON || + newState == BluetoothAdapter.STATE_BLE_TURNING_OFF ) { sendBleStateChanged(prevState, newState); isStandardBroadcast = false; - } else if (newState == BluetoothAdapter.STATE_TURNING_ON - || newState == BluetoothAdapter.STATE_TURNING_OFF) { + } else if (newState == BluetoothAdapter.STATE_TURNING_ON || + newState == BluetoothAdapter.STATE_TURNING_OFF) { sendBleStateChanged(prevState, newState); } |