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

Commit 6029611e authored by Vinit Deshapnde's avatar Vinit Deshapnde
Browse files

Fix an incorrectly created race accessing Wifi Supplicant

ScanModeState is trying to undo whatever it did in its enter(), in its
exit() function. But doing that is incorrect because it is possible to
transition to multiple states that require different conditions.

In this bug, the state machine transitioned from ScanModeState to
WaitForP2pDisabled state; in response to Stop Supplicant command. Well,
when we are trying to stop supplicant, there is clearly no need to
enable P2P or load all networks. But since this code exists in exit(),
it is executed nonetheless, causing race conditions accessing the
wpa_supplicant (WifiStateMachine is trying to shut it down, but
P2pStateMachine is trying to bring up the p2p interfaces).

We solve that problem by moving this code to the place where we transition
to DisconnectedState - since that's the state that needs this as a
precondition.

Bug: 10761752
Change-Id: Iaf0ffd8056de8533b5d2bfdf8c440fbb7e406dac
parent e14d0c21
Loading
Loading
Loading
Loading
+35 −19
Original line number Diff line number Diff line
@@ -427,8 +427,12 @@ public class WifiStateMachine extends StateMachine {
    /* An IP address was removed from our interface */
    static final int CMD_IP_ADDRESS_REMOVED               = BASE + 141;

    /* Wifi state machine modes of operation */
    /* CONNECT_MODE - connect to any 'known' AP when it becomes available */
    public static final int CONNECT_MODE                   = 1;
    /* SCAN_ONLY_MODE - don't connect to any APs; scan, but only while apps hold lock */
    public static final int SCAN_ONLY_MODE                 = 2;
    /* SCAN_ONLY_WITH_WIFI_OFF - scan, but don't connect to any APs */
    public static final int SCAN_ONLY_WITH_WIFI_OFF_MODE   = 3;

    private static final int SUCCESS = 1;
@@ -2942,6 +2946,8 @@ public class WifiStateMachine extends StateMachine {

            if (mOperationalMode != CONNECT_MODE) {
                mWifiNative.disconnect();
                mWifiConfigStore.disableAllNetworks();
                setWifiState(WIFI_STATE_DISABLED);
                transitionTo(mScanModeState);
            } else {
                /* Driver stop may have disabled networks, enable right after start */
@@ -2969,7 +2975,15 @@ public class WifiStateMachine extends StateMachine {
            }
            mWifiNative.setPowerSave(true);

            if (mP2pSupported) mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_ENABLE_P2P);
            if (mP2pSupported) {
                if (mOperationalMode == CONNECT_MODE) {
                    mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_ENABLE_P2P);
                } else {
                    // P2P statemachine starts in disabled state, and is not enabled until
                    // CMD_ENABLE_P2P is sent from here; so, nothing needs to be done to
                    // keep it disabled.
                }
            }

            final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -3240,15 +3254,14 @@ public class WifiStateMachine extends StateMachine {
        private int mLastOperationMode;
        @Override
        public void enter() {
            mWifiConfigStore.disableAllNetworks();
            mLastOperationMode = mOperationalMode;
            if (mLastOperationMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
                mWifiP2pChannel.sendMessage(CMD_DISABLE_P2P_REQ);
                setWifiState(WIFI_STATE_DISABLED);
            }
        }
        @Override
        public void exit() {
        public boolean processMessage(Message message) {
            switch(message.what) {
                case CMD_SET_OPERATIONAL_MODE:
                    if (message.arg1 == CONNECT_MODE) {

                        if (mLastOperationMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
                            setWifiState(WIFI_STATE_ENABLED);
                            // Load and re-enable networks when going back to enabled state
@@ -3258,13 +3271,9 @@ public class WifiStateMachine extends StateMachine {
                        } else {
                            mWifiConfigStore.enableAllNetworks();
                        }

                        mWifiNative.reconnect();
        }
        @Override
        public boolean processMessage(Message message) {
            switch(message.what) {
                case CMD_SET_OPERATIONAL_MODE:
                    if (message.arg1 == CONNECT_MODE) {

                        mOperationalMode = CONNECT_MODE;
                        transitionTo(mDisconnectedState);
                    } else {
@@ -3890,6 +3899,13 @@ public class WifiStateMachine extends StateMachine {
                case CMD_SET_OPERATIONAL_MODE:
                    if (message.arg1 != CONNECT_MODE) {
                        mOperationalMode = message.arg1;

                        mWifiConfigStore.disableAllNetworks();
                        if (mOperationalMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
                            mWifiP2pChannel.sendMessage(CMD_DISABLE_P2P_REQ);
                            setWifiState(WIFI_STATE_DISABLED);
                        }

                        transitionTo(mScanModeState);
                    }
                    break;