From e9d6e6722d8e4724b42f4c1dffa02bed05ee8b0a Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 30 Jun 2017 13:23:16 -0700 Subject: WifiConfigManager: Method to remove all transient networks Add a new method to remove all transient (ephemeral or passpoint) configured networks after every disconect. This is a lazy handling of the removal of any lingering ephemeral networks in the database. For example, if we encounter an assoc-reject while trying to connect to an ephemeral network, this config will now be removed in the next disconnect. The alternative is to check and remove the ephemeral network whenever the connection attempt fails, or if it's ignored after addition because of the connection rate limiter in WifiConnectivityManager, etc. We chose the passive removal implementation to balance the tradeoff of fixing the issue and CL size. Bug: 62841520 Test: Unit tests Test: Manual tests with WFA. Test: Regression tests (b/63663462). Change-Id: I708955bf6ff59a757b2d4ef7dfbb02b383d8e4d8 --- .../com/android/server/wifi/WifiConfigManager.java | 27 +++++++++++++++++ .../com/android/server/wifi/WifiStateMachine.java | 12 ++------ .../android/server/wifi/WifiConfigManagerTest.java | 34 ++++++++++++++++++++++ .../server/wifi/WifiConfigurationTestUtil.java | 6 ++++ .../android/server/wifi/WifiStateMachineTest.java | 11 +++++++ 5 files changed, 80 insertions(+), 10 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 67583a397..ceba0b776 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -1206,6 +1206,33 @@ public class WifiConfigManager { return removedNetworks; } + /** + * Iterates through the internal list of configured networks and removes any ephemeral or + * passpoint network configurations which are transient in nature. + * + * @return true if a network was removed, false otherwise. + */ + public boolean removeAllEphemeralOrPasspointConfiguredNetworks() { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "Removing all passpoint or ephemeral configured networks"); + } + boolean didRemove = false; + WifiConfiguration[] copiedConfigs = + mConfiguredNetworks.valuesForAllUsers().toArray(new WifiConfiguration[0]); + for (WifiConfiguration config : copiedConfigs) { + if (config.isPasspoint()) { + Log.d(TAG, "Removing passpoint network config " + config.configKey()); + removeNetwork(config.networkId, mSystemUiUid); + didRemove = true; + } else if (config.ephemeral) { + Log.d(TAG, "Removing ephemeral network config " + config.configKey()); + removeNetwork(config.networkId, mSystemUiUid); + didRemove = true; + } + } + return didRemove; + } + /** * Helper method to mark a network enabled for network selection. */ diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 183f32ff0..b347ea322 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -4810,16 +4810,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss void registerDisconnected() { if (mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) { mWifiConfigManager.updateNetworkAfterDisconnect(mLastNetworkId); - // We are switching away from this configuration, - // hence record the time we were connected last - WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(mLastNetworkId); - if (config != null) { - // Remove WifiConfiguration for ephemeral or Passpoint networks, since they're - // temporary networks. - if (config.ephemeral || config.isPasspoint()) { - mWifiConfigManager.removeNetwork(mLastNetworkId, Process.WIFI_UID); - } - } + // Let's remove any ephemeral or passpoint networks on every disconnect. + mWifiConfigManager.removeAllEphemeralOrPasspointConfiguredNetworks(); } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java index 6996a5825..b1ff4f24c 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java @@ -2714,6 +2714,40 @@ public class WifiConfigManagerTest { mContextConfigStoreMockOrder.verify(mWifiConfigStore, times(2)).write(eq(false)); } + /** + * Verifies that all the ephemeral and passpoint networks are removed when + * {@link WifiConfigManager#removeAllEphemeralOrPasspointConfiguredNetworks()} is invoked. + */ + @Test + public void testRemoveAllEphemeralOrPasspointConfiguredNetworks() throws Exception { + WifiConfiguration savedOpenNetwork = WifiConfigurationTestUtil.createOpenNetwork(); + WifiConfiguration ephemeralNetwork = WifiConfigurationTestUtil.createEphemeralNetwork(); + WifiConfiguration passpointNetwork = WifiConfigurationTestUtil.createPasspointNetwork(); + + verifyAddNetworkToWifiConfigManager(savedOpenNetwork); + verifyAddEphemeralNetworkToWifiConfigManager(ephemeralNetwork); + verifyAddPasspointNetworkToWifiConfigManager(passpointNetwork); + + List expectedConfigsBeforeRemove = new ArrayList() {{ + add(savedOpenNetwork); + add(ephemeralNetwork); + add(passpointNetwork); + }}; + WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate( + expectedConfigsBeforeRemove, mWifiConfigManager.getConfiguredNetworks()); + + assertTrue(mWifiConfigManager.removeAllEphemeralOrPasspointConfiguredNetworks()); + + List expectedConfigsAfterRemove = new ArrayList() {{ + add(savedOpenNetwork); + }}; + WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate( + expectedConfigsAfterRemove, mWifiConfigManager.getConfiguredNetworks()); + + // No more ephemeral or passpoint networks to remove now. + assertFalse(mWifiConfigManager.removeAllEphemeralOrPasspointConfiguredNetworks()); + } + /** * Verifies that the modification of a single network using * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} and ensures that any diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java index b9afce47f..62a68d47b 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java @@ -229,6 +229,12 @@ public class WifiConfigurationTestUtil { null, SECURITY_NONE); } + public static WifiConfiguration createEphemeralNetwork() { + WifiConfiguration configuration = createOpenNetwork(); + configuration.ephemeral = true; + return configuration; + } + public static WifiConfiguration createOpenHiddenNetwork() { WifiConfiguration configuration = createOpenNetwork(); configuration.hiddenSSID = true; diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index 52b4d3687..c91f937fe 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -2020,4 +2020,15 @@ public class WifiStateMachineTest { mLooper.dispatchAll(); verify(mWifiNative, never()).resetTxPowerLimit(); } + + /* + * Verifies that a network disconnection event will result in WifiStateMachine invoking + * {@link WifiConfigManager#removeAllEphemeralOrPasspointConfiguredNetworks()} to remove + * any ephemeral or passpoint networks from it's internal database. + */ + @Test + public void testDisconnectionRemovesEphemeralAndPasspointNetworks() throws Exception { + disconnect(); + verify(mWifiConfigManager).removeAllEphemeralOrPasspointConfiguredNetworks(); + } } -- cgit v1.2.3