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
This commit is contained in:
committed by
Andre Eisenbach
parent
6bc33b07f4
commit
a0b91d77d6
@ -897,28 +897,10 @@ public final class BluetoothAdapter {
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
|
||||
public boolean enable() {
|
||||
int state = BluetoothAdapter.STATE_OFF;
|
||||
if (isEnabled() == true) {
|
||||
if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
|
||||
return true;
|
||||
}
|
||||
// Use service interface to get the exact state
|
||||
try {
|
||||
mServiceLock.readLock().lock();
|
||||
if (mService != null) {
|
||||
state = mService.getState();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "", e);
|
||||
} finally {
|
||||
mServiceLock.readLock().unlock();
|
||||
}
|
||||
|
||||
if (state == BluetoothAdapter.STATE_BLE_ON) {
|
||||
Log.e(TAG, "BT is in BLE_ON State");
|
||||
notifyUserAction(true);
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return mManagerService.enable();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user