summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlen Kuhne <kuh@google.com>2017-03-23 12:54:08 -0700
committerGlen Kuhne <kuh@google.com>2017-03-28 15:52:06 -0700
commit47b8bdb173893084115ead905ea7ffe847840ca2 (patch)
tree2caacc5bb5a2d4dc9125a99b26386b52e21b9060
parentf139f833426aec5258c80fa582ca7007c079c0a2 (diff)
Reset & Stop updating WifiInfo outside ConnectMode
Added a WifiInfo reset call on entering and exiting ConnectModeState, as well as setting WifiInfo SupplicantState to Disconnected. Also removed handling of SUPPLICANT_STATE_CHANGE_EVENT from ScanModeState, which results in no updates to WifiInfo. This fixes an issue where WifiConnectivityManager could become frozen due to wpa_supplicant shenanigans in ScanModeState. Test: Added a unit test Bug: 36416438 Change-Id: Id8f4bd6434937ece08978a6186f6a9b1a6ab9c37
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java9
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java66
2 files changed, 70 insertions, 5 deletions
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 17b8b2f40..791c170d8 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -4429,10 +4429,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
case CMD_START_SCAN:
handleScanRequest(message);
break;
- case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
- SupplicantState state = handleSupplicantStateChange(message);
- if (mVerboseLoggingEnabled) log("SupplicantState= " + state);
- break;
default:
return NOT_HANDLED;
}
@@ -4637,7 +4633,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
if (!mWifiNative.removeAllNetworks()) {
loge("Failed to remove networks on entering connect mode");
}
-
+ mWifiInfo.reset();
+ mWifiInfo.setSupplicantState(SupplicantState.DISCONNECTED);
// Let the system know that wifi is available in client mode.
setWifiState(WIFI_STATE_ENABLED);
@@ -4669,6 +4666,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
if (!mWifiNative.removeAllNetworks()) {
loge("Failed to remove networks on exiting connect mode");
}
+ mWifiInfo.reset();
+ mWifiInfo.setSupplicantState(SupplicantState.DISCONNECTED);
}
@Override
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
index ad441f54d..d6c0f28bc 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
@@ -86,6 +86,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -1427,4 +1428,69 @@ public class WifiStateMachineTest {
when(mWifiConfigManager.enableNetwork(eq(newNetworkId), anyBoolean(), anyInt()))
.thenReturn(true);
}
+
+ /**
+ * Verifies that WifiInfo is cleared upon exiting and entering WifiInfo, and that it is not
+ * updated by SUPPLICAN_STATE_CHANGE_EVENTs in ScanModeState.
+ * This protects WifiStateMachine from getting into a bad state where WifiInfo says wifi is
+ * already Connected or Connecting, (when it is in-fact Disconnected), so
+ * WifiConnectivityManager does not attempt any new Connections, freezing wifi.
+ */
+ @Test
+ public void testWifiInfoCleanedUpEnteringExitingConnectModeState() throws Exception {
+ InOrder inOrder = inOrder(mWifiConnectivityManager);
+ Log.i(TAG, mWsm.getCurrentState().getName());
+ String initialBSSID = "aa:bb:cc:dd:ee:ff";
+ WifiInfo wifiInfo = mWsm.getWifiInfo();
+ wifiInfo.setBSSID(initialBSSID);
+
+ // Set WSM to CONNECT_MODE and verify state, and wifi enabled in ConnectivityManager
+ mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
+ startSupplicantAndDispatchMessages();
+ mWsm.setSupplicantRunning(true);
+ mLooper.dispatchAll();
+ assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest());
+ assertEquals(WifiManager.WIFI_STATE_ENABLED, mWsm.syncGetWifiState());
+ inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(true));
+ assertNull(wifiInfo.getBSSID());
+
+ // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated
+ mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED));
+ mLooper.dispatchAll();
+ assertEquals(sBSSID, wifiInfo.getBSSID());
+ assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState());
+
+ // Set WSM to SCAN_ONLY_MODE, verify state and wifi disabled in ConnectivityManager, and
+ // WifiInfo is reset() and state set to DISCONNECTED
+ mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE);
+ mLooper.dispatchAll();
+ assertEquals(WifiStateMachine.SCAN_ONLY_MODE, mWsm.getOperationalModeForTest());
+ assertEquals("ScanModeState", getCurrentState().getName());
+ assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState());
+ inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(false));
+ assertNull(wifiInfo.getBSSID());
+ assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState());
+
+ // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is not updated
+ mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED));
+ mLooper.dispatchAll();
+ assertNull(wifiInfo.getBSSID());
+ assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState());
+
+ // Set the bssid to something, so we can verify it is cleared (just in case)
+ wifiInfo.setBSSID(initialBSSID);
+
+ // Set WSM to CONNECT_MODE and verify state, and wifi enabled in ConnectivityManager,
+ // and WifiInfo has been reset
+ mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
+ mLooper.dispatchAll();
+ assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest());
+ assertEquals(WifiManager.WIFI_STATE_ENABLED, mWsm.syncGetWifiState());
+ inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(true));
+ assertEquals("DisconnectedState", getCurrentState().getName());
+ assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState());
+ assertNull(wifiInfo.getBSSID());
+ }
}