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

Commit 5d61d8dd authored by Matthew Xie's avatar Matthew Xie Committed by Android (Google) Code Review
Browse files

Merge "Apply timeout for powerdown event and reset state machine when bluez crashes"

parents 11e2e5de 694c0b83
Loading
Loading
Loading
Loading
+75 −3
Original line number Diff line number Diff line
@@ -109,6 +109,8 @@ final class BluetoothAdapterStateMachine extends StateMachine {
    private static final int DEVICES_DISCONNECT_TIMEOUT = 104;
    // Prepare Bluetooth timeout happens
    private static final int PREPARE_BLUETOOTH_TIMEOUT = 105;
    // Bluetooth Powerdown timeout happens
    private static final int POWER_DOWN_TIMEOUT = 106;

    private Context mContext;
    private BluetoothService mBluetoothService;
@@ -129,6 +131,8 @@ final class BluetoothAdapterStateMachine extends StateMachine {

    private static final int PREPARE_BLUETOOTH_TIMEOUT_TIME = 10000;

    private static final int POWER_DOWN_TIMEOUT_TIME = 5000;

    BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService,
                                 BluetoothAdapter bluetoothAdapter) {
        super(TAG);
@@ -386,6 +390,11 @@ final class BluetoothAdapterStateMachine extends StateMachine {
                    break;
                case USER_TURN_OFF: // ignore
                    break;
                case POWER_STATE_CHANGED:
                    if ((Boolean) message.obj) {
                        recoverStateMachine(TURN_HOT, null);
                    }
                    break;
                default:
                    return NOT_HANDLED;
            }
@@ -420,14 +429,27 @@ final class BluetoothAdapterStateMachine extends StateMachine {
                    }
                    break;
                case POWER_STATE_CHANGED:
                    removeMessages(POWER_DOWN_TIMEOUT);
                    if (!((Boolean) message.obj)) {
                        if (mPublicState == BluetoothAdapter.STATE_TURNING_OFF) {
                            transitionTo(mHotOff);
                            finishSwitchingOff();
                        }
                    } else {
                        if (mPublicState != BluetoothAdapter.STATE_TURNING_ON) {
                            if (mContext.getResources().getBoolean
                            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
                                recoverStateMachine(TURN_HOT, null);
                            } else {
                                recoverStateMachine(TURN_COLD, null);
                            }
                        }
                    }
                    break;
                case ALL_DEVICES_DISCONNECTED:
                    removeMessages(DEVICES_DISCONNECT_TIMEOUT);
                    mBluetoothService.switchConnectable(false);
                    sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
                    break;
                case DEVICES_DISCONNECT_TIMEOUT:
                    sendMessage(ALL_DEVICES_DISCONNECTED);
@@ -439,6 +461,17 @@ final class BluetoothAdapterStateMachine extends StateMachine {
                        deferMessage(obtainMessage(TURN_HOT));
                    }
                    break;
                case POWER_DOWN_TIMEOUT:
                    transitionTo(mHotOff);
                    finishSwitchingOff();
                    // reset the hardware for error recovery
                    Log.e(TAG, "Devices failed to power down, reseting...");
                    deferMessage(obtainMessage(TURN_COLD));
                    if (mContext.getResources().getBoolean
                        (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
                        deferMessage(obtainMessage(TURN_HOT));
                    }
                    break;
                case USER_TURN_ON:
                case AIRPLANE_MODE_OFF:
                case AIRPLANE_MODE_ON:
@@ -501,6 +534,7 @@ final class BluetoothAdapterStateMachine extends StateMachine {
                                           DEVICES_DISCONNECT_TIMEOUT_TIME);
                    } else {
                        mBluetoothService.switchConnectable(false);
                        sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
                    }

                    // we turn all the way to PowerOff with AIRPLANE_MODE_ON
@@ -520,6 +554,12 @@ final class BluetoothAdapterStateMachine extends StateMachine {
                case PER_PROCESS_TURN_OFF:
                    perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
                    break;
                case POWER_STATE_CHANGED:
                    if ((Boolean) message.obj) {
                        // reset the state machine and send it TURN_ON_CONTINUE message
                        recoverStateMachine(USER_TURN_ON, false);
                    }
                    break;
                default:
                    return NOT_HANDLED;
            }
@@ -540,7 +580,7 @@ final class BluetoothAdapterStateMachine extends StateMachine {

            if (what == PER_PROCESS_TURN_ON) {
                isTurningOn = true;
            } else if (what == PER_PROCESS_TURN_OFF) {
            } else if (what == USER_TURN_OFF) {
                isTurningOn = false;
            } else {
                Log.e(TAG, "enter PerProcessState: wrong msg: " + what);
@@ -568,12 +608,31 @@ final class BluetoothAdapterStateMachine extends StateMachine {
                    }
                    break;
                case POWER_STATE_CHANGED:
                    removeMessages(POWER_DOWN_TIMEOUT);
                    if (!((Boolean) message.obj)) {
                        transitionTo(mHotOff);
                        if (!mContext.getResources().getBoolean
                            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
                            deferMessage(obtainMessage(TURN_COLD));
                        }
                    } else {
                        if (!isTurningOn) {
                            recoverStateMachine(TURN_COLD, null);
                            for (IBluetoothStateChangeCallback c:
                                     mBluetoothService.getApplicationStateChangeCallbacks()) {
                                perProcessCallback(false, c);
                                deferMessage(obtainMessage(PER_PROCESS_TURN_ON, c));
                            }
                        }
                    }
                    break;
                case POWER_DOWN_TIMEOUT:
                    transitionTo(mHotOff);
                    Log.e(TAG, "Power-down timed out, resetting...");
                    deferMessage(obtainMessage(TURN_COLD));
                    if (mContext.getResources().getBoolean
                        (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
                        deferMessage(obtainMessage(TURN_HOT));
                    }
                    break;
                case USER_TURN_ON:
@@ -616,10 +675,12 @@ final class BluetoothAdapterStateMachine extends StateMachine {
                    perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
                    if (mBluetoothService.isApplicationStateChangeTrackerEmpty()) {
                        mBluetoothService.switchConnectable(false);
                        sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
                    }
                    break;
                case AIRPLANE_MODE_ON:
                    mBluetoothService.switchConnectable(false);
                    sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
                    allProcessesCallback(false);
                    // we turn all the way to PowerOff with AIRPLANE_MODE_ON
                    deferMessage(obtainMessage(AIRPLANE_MODE_ON));
@@ -699,6 +760,17 @@ final class BluetoothAdapterStateMachine extends StateMachine {
        mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
    }

    /**
     * bluetoothd has crashed and recovered, the adapter state machine has to
     * reset itself and try to return to previous state
     */
    private void recoverStateMachine(int what, Object obj) {
        Log.e(TAG, "Get unexpected power on event, reset with: " + what);
        transitionTo(mHotOff);
        deferMessage(obtainMessage(TURN_COLD));
        deferMessage(obtainMessage(what, obj));
    }

    private void dump(PrintWriter pw) {
        IState currentState = getCurrentState();
        if (currentState == mPowerOff) {
+2 −17
Original line number Diff line number Diff line
@@ -59,9 +59,8 @@ class BluetoothEventLoop {
    // from remote device when Android is in Suspend state.
    private PowerManager.WakeLock mWakeLock;

    private static final int EVENT_RESTART_BLUETOOTH = 1;
    private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 2;
    private static final int EVENT_AGENT_CANCEL = 3;
    private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 1;
    private static final int EVENT_AGENT_CANCEL = 2;

    private static final int CREATE_DEVICE_ALREADY_EXISTS = 1;
    private static final int CREATE_DEVICE_SUCCESS = 0;
@@ -75,9 +74,6 @@ class BluetoothEventLoop {
        public void handleMessage(Message msg) {
            String address = null;
            switch (msg.what) {
            case EVENT_RESTART_BLUETOOTH:
                mBluetoothService.restart();
                break;
            case EVENT_PAIRING_CONSENT_DELAYED_ACCEPT:
                address = (String)msg.obj;
                if (address != null) {
@@ -375,9 +371,6 @@ class BluetoothEventLoop {
        } else if (name.equals("Powered")) {
            mBluetoothState.sendMessage(BluetoothAdapterStateMachine.POWER_STATE_CHANGED,
                propValues[1].equals("true") ? new Boolean(true) : new Boolean(false));
            // bluetoothd has restarted, re-read all our properties.
            // Note: bluez only sends this property change when it restarts.
            onRestartRequired();
        } else if (name.equals("DiscoverableTimeout")) {
            adapterProperties.setProperty(name, propValues[1]);
        }
@@ -1033,14 +1026,6 @@ class BluetoothEventLoop {
        mBluetoothService.onHealthDeviceChannelChanged(devicePath, channelPath, exists);
    }

    private void onRestartRequired() {
        if (mBluetoothService.isEnabled()) {
            Log.e(TAG, "*** A serious error occurred (did bluetoothd crash?) - " +
                       "restarting Bluetooth ***");
            mHandler.sendEmptyMessage(EVENT_RESTART_BLUETOOTH);
        }
    }

    private static void log(String msg) {
        Log.d(TAG, msg);
    }
+0 −21
Original line number Diff line number Diff line
@@ -95,7 +95,6 @@ public class BluetoothService extends IBluetooth.Stub {
    private boolean mIsAirplaneSensitive;
    private boolean mIsAirplaneToggleable;
    private BluetoothAdapterStateMachine mBluetoothState;
    private boolean mRestart = false;  // need to call enable() after disable()
    private int[] mAdapterSdpHandles;
    private ParcelUuid[] mAdapterUuids;

@@ -429,11 +428,6 @@ public class BluetoothService extends IBluetooth.Stub {
        } finally {
            Binder.restoreCallingIdentity(ident);
        }

        if (mRestart) {
            mRestart = false;
            enable();
        }
    }

    /**
@@ -456,10 +450,6 @@ public class BluetoothService extends IBluetooth.Stub {
        // the adapter property could be changed before event loop is stoped, clear it again
        mAdapterProperties.clear();
        disableNative();
        if (mRestart) {
            mRestart = false;
            enable();
        }
    }

    /** Bring up BT and persist BT on in settings */
@@ -500,17 +490,6 @@ public class BluetoothService extends IBluetooth.Stub {
        return true;
    }

    /** Forcibly restart Bluetooth if it is on */
    /* package */ synchronized void restart() {
        if (getBluetoothStateInternal() != BluetoothAdapter.STATE_ON) {
            return;
        }
        mRestart = true;
        if (!disable(false)) {
            mRestart = false;
        }
    }

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {