diff options
author | Roshan Pius <rpius@google.com> | 2018-05-04 16:38:29 -0700 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2018-05-18 10:38:13 -0700 |
commit | d5265a61c41f23503e755d37bd5611ebef3f12b0 (patch) | |
tree | 3c11188fa12f5ce7d630807a929167814a6ade6a | |
parent | e93744bec9cb63b00b4597d49a20378749634358 (diff) |
WifiConfigManager: Temporarily disable network with no internet access
Changes in the CL:
a) Add a new network disable reason to temporarily blacklist an
auto-connected network.
b) When the device auto-connects to a network and then it detects a no
internet report, we temporarily disable the network for 10 minutes. This
should force network selection to pick another candidate if available.
Note:
a) If there are no other candidates available to auto-connect, the device
will remain connected to the existing network (even though it is
temporarily disabled).
b) If the user explicitly clicked on the network, we'll not temporarily
disable the network.
Bug: 72635747
Test: Unit tests
Test: Manually verified that device switched away from an
auto-connected network when it detects no internet.
Change-Id: I644693fa5d4477bdce1d39f391fc2fb24a773eeb
4 files changed, 151 insertions, 6 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 982c48a48..09b0b3483 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -119,10 +119,11 @@ public class WifiConfigManager { 5, // threshold for DISABLED_AUTHENTICATION_FAILURE 5, // threshold for DISABLED_DHCP_FAILURE 5, // threshold for DISABLED_DNS_FAILURE + 1, // threshold for DISABLED_NO_INTERNET_TEMPORARY 1, // threshold for DISABLED_WPS_START 6, // threshold for DISABLED_TLS_VERSION_MISMATCH 1, // threshold for DISABLED_AUTHENTICATION_NO_CREDENTIALS - 1, // threshold for DISABLED_NO_INTERNET + 1, // threshold for DISABLED_NO_INTERNET_PERMANENT 1, // threshold for DISABLED_BY_WIFI_MANAGER 1, // threshold for DISABLED_BY_USER_SWITCH 1 // threshold for DISABLED_BY_WRONG_PASSWORD @@ -141,10 +142,11 @@ public class WifiConfigManager { 5 * 60 * 1000, // threshold for DISABLED_AUTHENTICATION_FAILURE 5 * 60 * 1000, // threshold for DISABLED_DHCP_FAILURE 5 * 60 * 1000, // threshold for DISABLED_DNS_FAILURE + 10 * 60 * 1000, // threshold for DISABLED_NO_INTERNET_TEMPORARY 0 * 60 * 1000, // threshold for DISABLED_WPS_START Integer.MAX_VALUE, // threshold for DISABLED_TLS_VERSION Integer.MAX_VALUE, // threshold for DISABLED_AUTHENTICATION_NO_CREDENTIALS - Integer.MAX_VALUE, // threshold for DISABLED_NO_INTERNET + Integer.MAX_VALUE, // threshold for DISABLED_NO_INTERNET_PERMANENT Integer.MAX_VALUE, // threshold for DISABLED_BY_WIFI_MANAGER Integer.MAX_VALUE, // threshold for DISABLED_BY_USER_SWITCH Integer.MAX_VALUE // threshold for DISABLED_BY_WRONG_PASSWORD diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 74a4dc7f0..fa22749bb 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -5292,10 +5292,20 @@ public class WifiStateMachine extends StateMachine { config.networkId, false); mWifiConfigManager.updateNetworkSelectionStatus(config.networkId, WifiConfiguration.NetworkSelectionStatus - .DISABLED_NO_INTERNET); + .DISABLED_NO_INTERNET_PERMANENT); + } else { + mWifiConfigManager.incrementNetworkNoInternetAccessReports( + config.networkId); + // If this was not the last selected network, update network + // selection status to temporarily disable the network. + if (mWifiConfigManager.getLastSelectedNetwork() != config.networkId + && !config.noInternetAccessExpected) { + mWifiConfigManager.updateNetworkSelectionStatus( + config.networkId, + WifiConfiguration.NetworkSelectionStatus + .DISABLED_NO_INTERNET_TEMPORARY); + } } - mWifiConfigManager.incrementNetworkNoInternetAccessReports( - config.networkId); } } return HANDLED; diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java index 844a358d0..5b4917c7f 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java @@ -643,6 +643,33 @@ public class WifiConfigManagerTest { /** * Verifies the update of network status using + * {@link WifiConfigManager#updateNetworkSelectionStatus(int, int)}. + */ + @Test + public void testNetworkSelectionStatusTemporarilyDisabledDueToNoInternet() { + WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork(); + + NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork); + + int networkId = result.getNetworkId(); + // First set it to enabled. + verifyUpdateNetworkSelectionStatus( + networkId, NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0); + + // Now set it to temporarily disabled. The threshold for no internet is 1, so + // disable it once to actually mark it temporarily disabled. + verifyUpdateNetworkSelectionStatus( + result.getNetworkId(), NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY, 1); + verify(mWcmListener).onSavedNetworkTemporarilyDisabled(networkId); + + // Now set it back to enabled. + verifyUpdateNetworkSelectionStatus( + result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0); + verify(mWcmListener, times(2)).onSavedNetworkEnabled(networkId); + } + + /** + * Verifies the update of network status using * {@link WifiConfigManager#updateNetworkSelectionStatus(int, int)} and ensures that * enabling a network clears out all the temporary disable counters. */ diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index b067d9dfa..8da8339b3 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -16,6 +16,8 @@ package com.android.server.wifi; +import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; @@ -37,6 +39,7 @@ import android.net.ConnectivityManager; import android.net.DhcpResults; import android.net.LinkProperties; import android.net.MacAddress; +import android.net.NetworkAgent; import android.net.NetworkCapabilities; import android.net.NetworkFactory; import android.net.NetworkInfo; @@ -2123,7 +2126,7 @@ public class WifiStateMachineTest { Bundle thresholds = new Bundle(); thresholds.putIntegerArrayList("thresholds", thresholdsArray); Message message = new Message(); - message.what = android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS; + message.what = NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS; message.obj = thresholds; messengerCaptor.getValue().send(message); mLooper.dispatchAll(); @@ -2433,4 +2436,107 @@ public class WifiStateMachineTest { mLooper.dispatchAll(); assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWsm.getWifiInfo().getMacAddress()); } + + /** + * Verify that we temporarily disable the network when auto-connected to a network + * with no internet access. + */ + @Test + public void verifyAutoConnectedNetworkWithInternetValidationFailure() throws Exception { + // Simulate the first connection. + connect(); + ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); + verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), + any(NetworkInfo.class), any(LinkProperties.class), any(NetworkCapabilities.class), + anyInt(), any(NetworkMisc.class)); + + WifiConfiguration currentNetwork = new WifiConfiguration(); + currentNetwork.networkId = FRAMEWORK_NETWORK_ID; + currentNetwork.noInternetAccessExpected = false; + currentNetwork.numNoInternetAccessReports = 1; + when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) + .thenReturn(currentNetwork); + when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); + + Message message = new Message(); + message.what = NetworkAgent.CMD_REPORT_NETWORK_STATUS; + message.arg1 = NetworkAgent.INVALID_NETWORK; + message.obj = new Bundle(); + messengerCaptor.getValue().send(message); + mLooper.dispatchAll(); + + verify(mWifiConfigManager) + .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); + verify(mWifiConfigManager).updateNetworkSelectionStatus( + FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); + } + + /** + * Verify that we don't temporarily disable the network when user selected to connect to a + * network with no internet access. + */ + @Test + public void verifyLastSelectedNetworkWithInternetValidationFailure() throws Exception { + // Simulate the first connection. + connect(); + ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); + verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), + any(NetworkInfo.class), any(LinkProperties.class), any(NetworkCapabilities.class), + anyInt(), any(NetworkMisc.class)); + + WifiConfiguration currentNetwork = new WifiConfiguration(); + currentNetwork.networkId = FRAMEWORK_NETWORK_ID; + currentNetwork.noInternetAccessExpected = false; + currentNetwork.numNoInternetAccessReports = 1; + when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) + .thenReturn(currentNetwork); + when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID); + + Message message = new Message(); + message.what = NetworkAgent.CMD_REPORT_NETWORK_STATUS; + message.arg1 = NetworkAgent.INVALID_NETWORK; + message.obj = new Bundle(); + messengerCaptor.getValue().send(message); + mLooper.dispatchAll(); + + verify(mWifiConfigManager) + .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); + verify(mWifiConfigManager, never()).updateNetworkSelectionStatus( + FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); + } + + /** + * Verify that we temporarily disable the network when auto-connected to a network + * with no internet access. + */ + @Test + public void verifyAutoConnectedNoInternetExpectedNetworkWithInternetValidationFailure() + throws Exception { + // Simulate the first connection. + connect(); + ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); + verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), + any(NetworkInfo.class), any(LinkProperties.class), any(NetworkCapabilities.class), + anyInt(), any(NetworkMisc.class)); + + WifiConfiguration currentNetwork = new WifiConfiguration(); + currentNetwork.networkId = FRAMEWORK_NETWORK_ID; + currentNetwork.noInternetAccessExpected = true; + currentNetwork.numNoInternetAccessReports = 1; + when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID + 1)) + .thenReturn(currentNetwork); + when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID); + + Message message = new Message(); + message.what = NetworkAgent.CMD_REPORT_NETWORK_STATUS; + message.arg1 = NetworkAgent.INVALID_NETWORK; + message.obj = new Bundle(); + messengerCaptor.getValue().send(message); + mLooper.dispatchAll(); + + verify(mWifiConfigManager) + .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); + verify(mWifiConfigManager, never()).updateNetworkSelectionStatus( + FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); + } } |