Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6627c71 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix bluetooth can't turn off during network reset (2/3)" into qt-qpr1-dev

parents 937136e5 d61f3f9c
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -1195,9 +1195,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(): Setting persist.bluetooth.factoryreset to retry later");
            SystemProperties.set("persist.bluetooth.factoryreset", "true");
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
+1 −0
Original line number Diff line number Diff line
@@ -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 {
+80 −34
Original line number Diff line number Diff line
@@ -73,11 +73,14 @@ import com.android.server.pm.UserRestrictionsUtils;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
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;

@@ -257,6 +260,47 @@ 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(new HashSet<Integer>(Arrays.asList(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;
    }

    private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
        @Override
        public void onChange(boolean unused) {
@@ -1627,7 +1671,9 @@ 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(new HashSet<Integer>(
                        //     Arrays.asList(BluetoothAdapter.STATE_OFF)))".
                        // (b) Wait until the STATE_OFF state is updated to
                        //     all components.
                        // (c) Wait until the Bluetooth process exits, and
@@ -1637,7 +1683,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
                        // message. On slower devices, that delay needs to be
                        // on the order of (2 * SERVICE_RESTART_TIME_MS).
                        //
                        waitForOnOff(false, true);
                        waitForState(new HashSet<Integer>(Arrays.asList(
                                BluetoothAdapter.STATE_OFF)));
                        Message restartMsg =
                                mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
                        mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
@@ -1650,10 +1697,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
                    }
                    mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
                    if (mEnable && mBluetooth != null) {
                        waitForOnOff(true, false);
                        waitForState(new HashSet<Integer>(Arrays.asList(
                                BluetoothAdapter.STATE_ON)));
                        mEnable = false;
                        handleDisable();
                        waitForOnOff(false, false);
                        waitForState(new HashSet<Integer>(Arrays.asList(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();
@@ -1782,9 +1835,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
                    }

                    if (!mEnable) {
                        waitForOnOff(true, false);
                        waitForState(new HashSet<Integer>(Arrays.asList(
                                BluetoothAdapter.STATE_ON)));
                        handleDisable();
                        waitForOnOff(false, false);
                        waitForState(new HashSet<Integer>(Arrays.asList(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;
                }
@@ -1816,7 +1875,8 @@ 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(new HashSet<Integer>(Arrays.asList(
                                    BluetoothAdapter.STATE_OFF)));
                            Message restartMsg =
                                    mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
                            mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
@@ -1939,7 +1999,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
                            mState = BluetoothAdapter.STATE_TURNING_ON;
                        }

                        waitForOnOff(true, false);
                        waitForState(new HashSet<Integer>(Arrays.asList(
                                BluetoothAdapter.STATE_ON)));

                        if (mState == BluetoothAdapter.STATE_TURNING_ON) {
                            bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
@@ -1954,7 +2015,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
                        bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
                                BluetoothAdapter.STATE_TURNING_OFF);

                        boolean didDisableTimeout = !waitForOnOff(false, true);
                        boolean didDisableTimeout =
                                !waitForState(new HashSet<Integer>(Arrays.asList(
                                    BluetoothAdapter.STATE_OFF)));

                        bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
                                BluetoothAdapter.STATE_OFF);
@@ -2206,12 +2269,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 {
@@ -2219,33 +2277,19 @@ 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) {
                if (states.contains(mBluetooth.getState())) {
                    return true;
                }
                } else {
                    if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
                        return true;
                    }
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "getState()", e);
                break;
            } finally {
                mBluetoothLock.readLock().unlock();
            }
            if (on || off) {
            SystemClock.sleep(300);
            } else {
                SystemClock.sleep(50);
            }
            i++;
        }
        Slog.e(TAG, "waitForOnOff time out");
        Slog.e(TAG, "waitForState " + states + " time out");
        return false;
    }

@@ -2306,7 +2350,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
                mContext.getPackageName(), false);
        handleDisable();

        waitForOnOff(false, true);
        waitForState(new HashSet<Integer>(Arrays.asList(BluetoothAdapter.STATE_OFF)));

        sendBluetoothServiceDownCallback();

@@ -2468,6 +2512,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 + "]";
        }