From 25fea7a2f8bf1978283d464d3fb3a78a7552898d Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 3 Oct 2019 08:37:55 -0700 Subject: WifiNetworkFactory: Remove network from config manager Remove the network configuration from config manager once the processing of the request is complete. This will otherwise cause the next network request for the same network to reuse existing credentials. Bug: 141882562 Test: manual testing with the demo app. Test: atest com.android.server.wifi Test: Will send for regression testing. Change-Id: Id068aab8b48d87beee1edc12f074527850eadfd0 Merged-In: Id068aab8b48d87beee1edc12f074527850eadfd0 (cherry picked from commit 7836168c83b185a1d84d292df57a6e29299c0f76) --- .../android/server/wifi/WifiNetworkFactory.java | 37 ++++++++++++++++++++-- .../server/wifi/WifiNetworkFactoryTest.java | 8 +++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java index c375e9f59..48797f773 100644 --- a/service/java/com/android/server/wifi/WifiNetworkFactory.java +++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java @@ -712,6 +712,11 @@ public class WifiNetworkFactory extends NetworkFactory { WifiConfiguration existingSavedNetwork = mWifiConfigManager.getConfiguredNetwork(network.configKey()); if (existingSavedNetwork != null) { + if (WifiConfigurationUtil.hasCredentialChanged(existingSavedNetwork, network)) { + // TODO (b/142035508): What if the user has a saved network with different + // credentials? + Log.w(TAG, "Network config already present in config manager, reusing"); + } return existingSavedNetwork.networkId; } NetworkUpdateResult networkUpdateResult = @@ -724,6 +729,32 @@ public class WifiNetworkFactory extends NetworkFactory { return networkUpdateResult.netId; } + // Helper method to remove the provided network configuration from WifiConfigManager, if it was + // added by an app's specifier request. + private void disconnectAndRemoveNetworkFromWifiConfigManager( + @Nullable WifiConfiguration network) { + // Trigger a disconnect first. + mWifiInjector.getClientModeImpl().disconnectCommand(); + + if (network == null) return; + WifiConfiguration wcmNetwork = + mWifiConfigManager.getConfiguredNetwork(network.configKey()); + if (wcmNetwork == null) { + Log.e(TAG, "Network not present in config manager"); + return; + } + // Remove the network if it was added previously by an app's specifier request. + if (wcmNetwork.ephemeral && wcmNetwork.fromWifiNetworkSpecifier) { + boolean success = + mWifiConfigManager.removeNetwork(wcmNetwork.networkId, wcmNetwork.creatorUid); + if (!success) { + Log.e(TAG, "Failed to remove network from config manager"); + } else if (mVerboseLoggingEnabled) { + Log.v(TAG, "Removed network from config manager " + wcmNetwork.networkId); + } + } + } + // Helper method to trigger a connection request & schedule a timeout alarm to track the // connection request. private void connectToNetwork(@NonNull WifiConfiguration network) { @@ -762,7 +793,6 @@ public class WifiNetworkFactory extends NetworkFactory { networkToConnect.SSID = network.SSID; // Set the WifiConfiguration.BSSID field to prevent roaming. networkToConnect.BSSID = findBestBssidFromActiveMatchedScanResultsForNetwork(network); - // Mark the network ephemeral so that it's automatically removed at the end of connection. networkToConnect.ephemeral = true; networkToConnect.fromWifiNetworkSpecifier = true; @@ -770,7 +800,8 @@ public class WifiNetworkFactory extends NetworkFactory { mUserSelectedNetwork = networkToConnect; // Disconnect from the current network before issuing a new connect request. - mWifiInjector.getClientModeImpl().disconnectCommand(); + disconnectAndRemoveNetworkFromWifiConfigManager(mUserSelectedNetwork); + // Trigger connection to the network. connectToNetwork(networkToConnect); // Triggered connection to network, now wait for the connection status. @@ -974,7 +1005,7 @@ public class WifiNetworkFactory extends NetworkFactory { // Invoked at the termination of current connected request processing. private void teardownForConnectedNetwork() { Log.i(TAG, "Disconnecting from network on reset"); - mWifiInjector.getClientModeImpl().disconnectCommand(); + disconnectAndRemoveNetworkFromWifiConfigManager(mUserSelectedNetwork); mConnectedSpecificNetworkRequest = null; mConnectedSpecificNetworkRequestSpecifier = null; // ensure there is no active request in progress. diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java index 63cc8bf60..6a4dc25d8 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java @@ -1615,9 +1615,17 @@ public class WifiNetworkFactoryTest { verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue()); // Now release the network request. + WifiConfiguration wcmNetwork = new WifiConfiguration(mSelectedNetwork); + wcmNetwork.networkId = TEST_NETWORK_ID_1; + wcmNetwork.creatorUid = TEST_UID_1; + wcmNetwork.fromWifiNetworkSpecifier = true; + wcmNetwork.ephemeral = true; + when(mWifiConfigManager.getConfiguredNetwork(mSelectedNetwork.configKey())) + .thenReturn(wcmNetwork); mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest); // Verify that we triggered a disconnect. verify(mClientModeImpl, times(2)).disconnectCommand(); + verify(mWifiConfigManager).removeNetwork(TEST_NETWORK_ID_1, TEST_UID_1); // Re-enable connectivity manager . verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false); } -- cgit v1.2.3