diff options
author | Glen Kuhne <kuh@google.com> | 2017-03-23 12:54:08 -0700 |
---|---|---|
committer | Glen Kuhne <kuh@google.com> | 2017-03-28 15:52:06 -0700 |
commit | 47b8bdb173893084115ead905ea7ffe847840ca2 (patch) | |
tree | 2caacc5bb5a2d4dc9125a99b26386b52e21b9060 | |
parent | f139f833426aec5258c80fa582ca7007c079c0a2 (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.java | 9 | ||||
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java | 66 |
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()); + } } |