Fix bluetooth can't turn off during network reset (2/3)

Remove disable Bluetooth action from AdapterService and move to
BluetoothManagerService.
Add factory reset reason into Bluetooth enable/disable reason list.

Bug: 110181479
Test: manual
Change-Id: I4bff3c3bb75fbb0d1e13c459c0d9d3fd3b8b3195
This commit is contained in:
weichinweng
2020-03-05 10:37:44 +08:00
committed by Weichin Weng
parent 32d8641104
commit e547073e75
3 changed files with 75 additions and 37 deletions

View File

@@ -1229,10 +1229,11 @@ public final class BluetoothAdapter {
public boolean factoryReset() {
try {
mServiceLock.readLock().lock();
if (mService != null) {
return mService.factoryReset();
if (mService != null && mService.factoryReset()
&& mManagerService != null && mManagerService.onFactoryReset()) {
return true;
}
Log.e(TAG, "factoryReset(): IBluetooth Service is null");
Log.e(TAG, "factoryReset(): Setting persist.bluetooth.factoryreset to retry later");
SystemProperties.set("persist.bluetooth.factoryreset", "true");
} catch (RemoteException e) {
Log.e(TAG, "", e);

View File

@@ -40,6 +40,7 @@ enum EnableDisableReasonEnum {
ENABLE_DISABLE_REASON_CRASH = 7;
ENABLE_DISABLE_REASON_USER_SWITCH = 8;
ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9;
ENABLE_DISABLE_REASON_FACTORY_RESET = 10;
}
enum DirectionEnum {

View File

@@ -85,6 +85,7 @@ import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -272,6 +273,46 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
};
public boolean onFactoryReset() {
// Wait for stable state if bluetooth is temporary state.
int state = getState();
if (state == BluetoothAdapter.STATE_BLE_TURNING_ON
|| state == BluetoothAdapter.STATE_TURNING_ON
|| state == BluetoothAdapter.STATE_TURNING_OFF) {
if (!waitForState(Set.of(BluetoothAdapter.STATE_BLE_ON, BluetoothAdapter.STATE_ON))) {
return false;
}
}
// Clear registered LE apps to force shut-off Bluetooth
clearBleApps();
state = getState();
try {
mBluetoothLock.readLock().lock();
if (mBluetooth == null) {
return false;
}
if (state == BluetoothAdapter.STATE_BLE_ON) {
addActiveLog(
BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET,
mContext.getPackageName(), false);
mBluetooth.onBrEdrDown();
return true;
} else if (state == BluetoothAdapter.STATE_ON) {
addActiveLog(
BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET,
mContext.getPackageName(), false);
mBluetooth.disable();
return true;
}
} catch (RemoteException e) {
Slog.e(TAG, "Unable to shutdown Bluetooth", e);
} finally {
mBluetoothLock.readLock().unlock();
}
return false;
}
public void onAirplaneModeChanged() {
synchronized (this) {
if (isBluetoothPersistedStateOn()) {
@@ -1670,7 +1711,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
// 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)".
// is accomplished by
// "waitForState(Set.of(BluetoothAdapter.STATE_OFF))".
// (b) Wait until the STATE_OFF state is updated to
// all components.
// (c) Wait until the Bluetooth process exits, and
@@ -1680,7 +1722,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
// message. The delay time is backed off if Bluetooth
// continuously failed to turn on itself.
//
waitForOnOff(false, true);
waitForState(Set.of(BluetoothAdapter.STATE_OFF));
Message restartMsg =
mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
@@ -1693,10 +1735,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
if (mEnable && mBluetooth != null) {
waitForOnOff(true, false);
waitForState(Set.of(BluetoothAdapter.STATE_ON));
mEnable = false;
handleDisable();
waitForOnOff(false, false);
waitForState(Set.of(BluetoothAdapter.STATE_OFF,
BluetoothAdapter.STATE_TURNING_ON,
BluetoothAdapter.STATE_TURNING_OFF,
BluetoothAdapter.STATE_BLE_TURNING_ON,
BluetoothAdapter.STATE_BLE_ON,
BluetoothAdapter.STATE_BLE_TURNING_OFF));
} else {
mEnable = false;
handleDisable();
@@ -1819,9 +1866,14 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
if (!mEnable) {
waitForOnOff(true, false);
waitForState(Set.of(BluetoothAdapter.STATE_ON));
handleDisable();
waitForOnOff(false, false);
waitForState(Set.of(BluetoothAdapter.STATE_OFF,
BluetoothAdapter.STATE_TURNING_ON,
BluetoothAdapter.STATE_TURNING_OFF,
BluetoothAdapter.STATE_BLE_TURNING_ON,
BluetoothAdapter.STATE_BLE_ON,
BluetoothAdapter.STATE_BLE_TURNING_OFF));
}
break;
}
@@ -1853,7 +1905,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
== BluetoothAdapter.STATE_OFF)) {
if (mEnable) {
Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
waitForOnOff(false, true);
waitForState(Set.of(BluetoothAdapter.STATE_OFF));
Message restartMsg =
mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
@@ -1982,7 +2034,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mState = BluetoothAdapter.STATE_TURNING_ON;
}
waitForOnOff(true, false);
waitForState(Set.of(BluetoothAdapter.STATE_ON));
if (mState == BluetoothAdapter.STATE_TURNING_ON) {
bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
@@ -1997,7 +2049,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
BluetoothAdapter.STATE_TURNING_OFF);
boolean didDisableTimeout = !waitForOnOff(false, true);
boolean didDisableTimeout =
!waitForState(Set.of(BluetoothAdapter.STATE_OFF));
bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
BluetoothAdapter.STATE_OFF);
@@ -2243,12 +2296,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
}
/**
* if on is true, wait for state become ON
* if off is true, wait for state become OFF
* if both on and off are false, wait for state not ON
*/
private boolean waitForOnOff(boolean on, boolean off) {
private boolean waitForState(Set<Integer> states) {
int i = 0;
while (i < 10) {
try {
@@ -2256,18 +2304,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (mBluetooth == null) {
break;
}
if (on) {
if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) {
return true;
}
} else if (off) {
if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) {
return true;
}
} else {
if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
return true;
}
if (states.contains(mBluetooth.getState())) {
return true;
}
} catch (RemoteException e) {
Slog.e(TAG, "getState()", e);
@@ -2275,14 +2313,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} finally {
mBluetoothLock.readLock().unlock();
}
if (on || off) {
SystemClock.sleep(300);
} else {
SystemClock.sleep(50);
}
SystemClock.sleep(300);
i++;
}
Slog.e(TAG, "waitForOnOff time out");
Slog.e(TAG, "waitForState " + states + " time out");
return false;
}
@@ -2343,7 +2377,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mContext.getPackageName(), false);
handleDisable();
waitForOnOff(false, true);
waitForState(Set.of(BluetoothAdapter.STATE_OFF));
sendBluetoothServiceDownCallback();
@@ -2533,6 +2567,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
return "USER_SWITCH";
case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
return "RESTORE_USER_SETTING";
case BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET:
return "FACTORY_RESET";
case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
default: return "UNKNOWN[" + reason + "]";
}