Loading core/java/android/bluetooth/BluetoothAdapter.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -1229,10 +1229,11 @@ public final class BluetoothAdapter { public boolean factoryReset() { public boolean factoryReset() { try { try { mServiceLock.readLock().lock(); mServiceLock.readLock().lock(); if (mService != null) { if (mService != null && mService.factoryReset() return 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"); SystemProperties.set("persist.bluetooth.factoryreset", "true"); } catch (RemoteException e) { } catch (RemoteException e) { Log.e(TAG, "", e); Log.e(TAG, "", e); Loading core/proto/android/bluetooth/enums.proto +1 −0 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,7 @@ enum EnableDisableReasonEnum { ENABLE_DISABLE_REASON_CRASH = 7; ENABLE_DISABLE_REASON_CRASH = 7; ENABLE_DISABLE_REASON_USER_SWITCH = 8; ENABLE_DISABLE_REASON_USER_SWITCH = 8; ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9; ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9; ENABLE_DISABLE_REASON_FACTORY_RESET = 10; } } enum DirectionEnum { enum DirectionEnum { Loading services/core/java/com/android/server/BluetoothManagerService.java +70 −34 Original line number Original line Diff line number Diff line Loading @@ -85,6 +85,7 @@ import java.util.LinkedList; import java.util.Locale; import java.util.Locale; import java.util.Map; import java.util.Map; import java.util.NoSuchElementException; import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; Loading Loading @@ -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() { public void onAirplaneModeChanged() { synchronized (this) { synchronized (this) { if (isBluetoothPersistedStateOn()) { if (isBluetoothPersistedStateOn()) { Loading Loading @@ -1670,7 +1711,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // the previous Bluetooth process has exited. The // the previous Bluetooth process has exited. The // waiting period has three components: // waiting period has three components: // (a) Wait until the local state is STATE_OFF. This // (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 // (b) Wait until the STATE_OFF state is updated to // all components. // all components. // (c) Wait until the Bluetooth process exits, and // (c) Wait until the Bluetooth process exits, and Loading @@ -1680,7 +1722,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // message. The delay time is backed off if Bluetooth // message. The delay time is backed off if Bluetooth // continuously failed to turn on itself. // continuously failed to turn on itself. // // waitForOnOff(false, true); waitForState(Set.of(BluetoothAdapter.STATE_OFF)); Message restartMsg = Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); Loading @@ -1693,10 +1735,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); if (mEnable && mBluetooth != null) { if (mEnable && mBluetooth != null) { waitForOnOff(true, false); waitForState(Set.of(BluetoothAdapter.STATE_ON)); mEnable = false; mEnable = false; handleDisable(); 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 { } else { mEnable = false; mEnable = false; handleDisable(); handleDisable(); Loading Loading @@ -1819,9 +1866,14 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } } if (!mEnable) { if (!mEnable) { waitForOnOff(true, false); waitForState(Set.of(BluetoothAdapter.STATE_ON)); handleDisable(); 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; break; } } Loading Loading @@ -1853,7 +1905,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { == BluetoothAdapter.STATE_OFF)) { == BluetoothAdapter.STATE_OFF)) { if (mEnable) { if (mEnable) { Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting."); Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting."); waitForOnOff(false, true); waitForState(Set.of(BluetoothAdapter.STATE_OFF)); Message restartMsg = Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); Loading Loading @@ -1982,7 +2034,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mState = BluetoothAdapter.STATE_TURNING_ON; mState = BluetoothAdapter.STATE_TURNING_ON; } } waitForOnOff(true, false); waitForState(Set.of(BluetoothAdapter.STATE_ON)); if (mState == BluetoothAdapter.STATE_TURNING_ON) { if (mState == BluetoothAdapter.STATE_TURNING_ON) { bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON); bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON); Loading @@ -1997,7 +2049,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, BluetoothAdapter.STATE_TURNING_OFF); BluetoothAdapter.STATE_TURNING_OFF); boolean didDisableTimeout = !waitForOnOff(false, true); boolean didDisableTimeout = !waitForState(Set.of(BluetoothAdapter.STATE_OFF)); bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, BluetoothAdapter.STATE_OFF); BluetoothAdapter.STATE_OFF); Loading Loading @@ -2243,12 +2296,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } } } } /** private boolean waitForState(Set<Integer> states) { * 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) { int i = 0; int i = 0; while (i < 10) { while (i < 10) { try { try { Loading @@ -2256,33 +2304,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (mBluetooth == null) { if (mBluetooth == null) { break; break; } } if (on) { if (states.contains(mBluetooth.getState())) { if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) { return true; } } else if (off) { if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) { return true; return true; } } } else { if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) { return true; } } } catch (RemoteException e) { } catch (RemoteException e) { Slog.e(TAG, "getState()", e); Slog.e(TAG, "getState()", e); break; break; } finally { } finally { mBluetoothLock.readLock().unlock(); mBluetoothLock.readLock().unlock(); } } if (on || off) { SystemClock.sleep(300); SystemClock.sleep(300); } else { SystemClock.sleep(50); } i++; i++; } } Slog.e(TAG, "waitForOnOff time out"); Slog.e(TAG, "waitForState " + states + " time out"); return false; return false; } } Loading Loading @@ -2343,7 +2377,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mContext.getPackageName(), false); mContext.getPackageName(), false); handleDisable(); handleDisable(); waitForOnOff(false, true); waitForState(Set.of(BluetoothAdapter.STATE_OFF)); sendBluetoothServiceDownCallback(); sendBluetoothServiceDownCallback(); Loading Loading @@ -2533,6 +2567,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return "USER_SWITCH"; return "USER_SWITCH"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING: case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING: return "RESTORE_USER_SETTING"; return "RESTORE_USER_SETTING"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET: return "FACTORY_RESET"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED: case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED: default: return "UNKNOWN[" + reason + "]"; default: return "UNKNOWN[" + reason + "]"; } } Loading Loading
core/java/android/bluetooth/BluetoothAdapter.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -1229,10 +1229,11 @@ public final class BluetoothAdapter { public boolean factoryReset() { public boolean factoryReset() { try { try { mServiceLock.readLock().lock(); mServiceLock.readLock().lock(); if (mService != null) { if (mService != null && mService.factoryReset() return 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"); SystemProperties.set("persist.bluetooth.factoryreset", "true"); } catch (RemoteException e) { } catch (RemoteException e) { Log.e(TAG, "", e); Log.e(TAG, "", e); Loading
core/proto/android/bluetooth/enums.proto +1 −0 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,7 @@ enum EnableDisableReasonEnum { ENABLE_DISABLE_REASON_CRASH = 7; ENABLE_DISABLE_REASON_CRASH = 7; ENABLE_DISABLE_REASON_USER_SWITCH = 8; ENABLE_DISABLE_REASON_USER_SWITCH = 8; ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9; ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9; ENABLE_DISABLE_REASON_FACTORY_RESET = 10; } } enum DirectionEnum { enum DirectionEnum { Loading
services/core/java/com/android/server/BluetoothManagerService.java +70 −34 Original line number Original line Diff line number Diff line Loading @@ -85,6 +85,7 @@ import java.util.LinkedList; import java.util.Locale; import java.util.Locale; import java.util.Map; import java.util.Map; import java.util.NoSuchElementException; import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; Loading Loading @@ -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() { public void onAirplaneModeChanged() { synchronized (this) { synchronized (this) { if (isBluetoothPersistedStateOn()) { if (isBluetoothPersistedStateOn()) { Loading Loading @@ -1670,7 +1711,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // the previous Bluetooth process has exited. The // the previous Bluetooth process has exited. The // waiting period has three components: // waiting period has three components: // (a) Wait until the local state is STATE_OFF. This // (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 // (b) Wait until the STATE_OFF state is updated to // all components. // all components. // (c) Wait until the Bluetooth process exits, and // (c) Wait until the Bluetooth process exits, and Loading @@ -1680,7 +1722,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // message. The delay time is backed off if Bluetooth // message. The delay time is backed off if Bluetooth // continuously failed to turn on itself. // continuously failed to turn on itself. // // waitForOnOff(false, true); waitForState(Set.of(BluetoothAdapter.STATE_OFF)); Message restartMsg = Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); Loading @@ -1693,10 +1735,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); if (mEnable && mBluetooth != null) { if (mEnable && mBluetooth != null) { waitForOnOff(true, false); waitForState(Set.of(BluetoothAdapter.STATE_ON)); mEnable = false; mEnable = false; handleDisable(); 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 { } else { mEnable = false; mEnable = false; handleDisable(); handleDisable(); Loading Loading @@ -1819,9 +1866,14 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } } if (!mEnable) { if (!mEnable) { waitForOnOff(true, false); waitForState(Set.of(BluetoothAdapter.STATE_ON)); handleDisable(); 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; break; } } Loading Loading @@ -1853,7 +1905,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { == BluetoothAdapter.STATE_OFF)) { == BluetoothAdapter.STATE_OFF)) { if (mEnable) { if (mEnable) { Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting."); Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting."); waitForOnOff(false, true); waitForState(Set.of(BluetoothAdapter.STATE_OFF)); Message restartMsg = Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); Loading Loading @@ -1982,7 +2034,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mState = BluetoothAdapter.STATE_TURNING_ON; mState = BluetoothAdapter.STATE_TURNING_ON; } } waitForOnOff(true, false); waitForState(Set.of(BluetoothAdapter.STATE_ON)); if (mState == BluetoothAdapter.STATE_TURNING_ON) { if (mState == BluetoothAdapter.STATE_TURNING_ON) { bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON); bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON); Loading @@ -1997,7 +2049,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, BluetoothAdapter.STATE_TURNING_OFF); BluetoothAdapter.STATE_TURNING_OFF); boolean didDisableTimeout = !waitForOnOff(false, true); boolean didDisableTimeout = !waitForState(Set.of(BluetoothAdapter.STATE_OFF)); bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, BluetoothAdapter.STATE_OFF); BluetoothAdapter.STATE_OFF); Loading Loading @@ -2243,12 +2296,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } } } } /** private boolean waitForState(Set<Integer> states) { * 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) { int i = 0; int i = 0; while (i < 10) { while (i < 10) { try { try { Loading @@ -2256,33 +2304,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (mBluetooth == null) { if (mBluetooth == null) { break; break; } } if (on) { if (states.contains(mBluetooth.getState())) { if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) { return true; } } else if (off) { if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) { return true; return true; } } } else { if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) { return true; } } } catch (RemoteException e) { } catch (RemoteException e) { Slog.e(TAG, "getState()", e); Slog.e(TAG, "getState()", e); break; break; } finally { } finally { mBluetoothLock.readLock().unlock(); mBluetoothLock.readLock().unlock(); } } if (on || off) { SystemClock.sleep(300); SystemClock.sleep(300); } else { SystemClock.sleep(50); } i++; i++; } } Slog.e(TAG, "waitForOnOff time out"); Slog.e(TAG, "waitForState " + states + " time out"); return false; return false; } } Loading Loading @@ -2343,7 +2377,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mContext.getPackageName(), false); mContext.getPackageName(), false); handleDisable(); handleDisable(); waitForOnOff(false, true); waitForState(Set.of(BluetoothAdapter.STATE_OFF)); sendBluetoothServiceDownCallback(); sendBluetoothServiceDownCallback(); Loading Loading @@ -2533,6 +2567,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return "USER_SWITCH"; return "USER_SWITCH"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING: case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING: return "RESTORE_USER_SETTING"; return "RESTORE_USER_SETTING"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET: return "FACTORY_RESET"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED: case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED: default: return "UNKNOWN[" + reason + "]"; default: return "UNKNOWN[" + reason + "]"; } } Loading