OEM configurable thresholds to disable network
Allow configuration via overlay for some failure reasons that
temporarily disable network selection.
Bug: 152173075
Test: atest com.android.server.wifi
Change-Id: Ibebf2f0c810d835b8c613e22505f4c5f12985854
Merged-In: Ibebf2f0c810d835b8c613e22505f4c5f12985854
(cherry picked from commit e0776523342197696563e1e1e821c89027282a3b)
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 83cabf7..8782ccd 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -50,6 +50,7 @@
import android.util.LocalLog;
import android.util.Log;
import android.util.Pair;
+import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.hotspot2.PasspointManager;
@@ -329,6 +330,7 @@
private final NetworkListSharedStoreData mNetworkListSharedStoreData;
private final NetworkListUserStoreData mNetworkListUserStoreData;
private final RandomizedMacStoreData mRandomizedMacStoreData;
+ private final SparseArray<DisableReasonInfo> mDisableReasonInfo;
/**
* Create new instance of WifiConfigManager.
@@ -375,6 +377,8 @@
mFrameworkFacade = frameworkFacade;
mDeviceConfigFacade = deviceConfigFacade;
+ mDisableReasonInfo = DISABLE_REASON_INFOS.clone();
+ loadCustomConfigsForDisableReasonInfos();
mLocalLog = new LocalLog(
context.getSystemService(ActivityManager.class).isLowRamDevice() ? 128 : 256);
@@ -383,6 +387,35 @@
}
/**
+ * Modify the internal copy of DisableReasonInfo with custom configurations defined in
+ * an overlay.
+ */
+ private void loadCustomConfigsForDisableReasonInfos() {
+ mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION,
+ new DisableReasonInfo(
+ // Note that there is a space at the end of this string. Cannot fix
+ // since this string is persisted.
+ "NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ",
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonAssociationRejectionThreshold),
+ 5 * 60 * 1000));
+
+ mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE,
+ new DisableReasonInfo(
+ "NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE",
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonAuthenticationFailureThreshold),
+ 5 * 60 * 1000));
+
+ mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_DHCP_FAILURE,
+ new DisableReasonInfo(
+ "config_wifiDisableReasonDhcpFailureThreshold",
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonDhcpFailureThreshold),
+ 5 * 60 * 1000));
+ }
+
+ /**
* Network Selection disable reason thresholds. These numbers are used to debounce network
* failures before we disable them.
*
@@ -390,9 +423,8 @@
* @return the disable threshold, or -1 if not found.
*/
@VisibleForTesting
- public static int getNetworkSelectionDisableThreshold(
- @NetworkSelectionDisableReason int reason) {
- DisableReasonInfo info = DISABLE_REASON_INFOS.get(reason);
+ public int getNetworkSelectionDisableThreshold(@NetworkSelectionDisableReason int reason) {
+ DisableReasonInfo info = mDisableReasonInfo.get(reason);
if (info == null) {
Log.e(TAG, "Unrecognized network disable reason code for disable threshold: " + reason);
return -1;
@@ -406,9 +438,8 @@
* enable the network again.
*/
@VisibleForTesting
- public static int getNetworkSelectionDisableTimeoutMillis(
- @NetworkSelectionDisableReason int reason) {
- DisableReasonInfo info = DISABLE_REASON_INFOS.get(reason);
+ public int getNetworkSelectionDisableTimeoutMillis(@NetworkSelectionDisableReason int reason) {
+ DisableReasonInfo info = mDisableReasonInfo.get(reason);
if (info == null) {
Log.e(TAG, "Unrecognized network disable reason code for disable timeout: " + reason);
return -1;
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index 0264c3e..420d470 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -337,6 +337,12 @@
<integer-array translatable="false" name="config_wifiSingleSavedNetworkConnectedScanIntervalScheduleSec">
</integer-array>
+ <!-- List of constants to indicate how many failures are needed to temporarily disable a network
+ from auto-connect -->
+ <integer translatable="false" name="config_wifiDisableReasonAssociationRejectionThreshold"> 5 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonAuthenticationFailureThreshold"> 5 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonDhcpFailureThreshold"> 5 </integer>
+
<!-- List of constants that indicate the number of consecutive failures per type needed to block a BSSID.
A blocked BSSID will not be considered in network selection and firmware roaming.-->
<integer translatable="false" name="config_wifiBssidBlocklistMonitorApUnableToHandleNewStaThreshold"> 1 </integer>
diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml
index 60764ba..9b0dc6a 100644
--- a/service/res/values/overlayable.xml
+++ b/service/res/values/overlayable.xml
@@ -104,6 +104,9 @@
<item type="array" name="config_wifiConnectedScanIntervalScheduleSec" />
<item type="array" name="config_wifiSingleSavedNetworkConnectedScanIntervalScheduleSec" />
<item type="integer" name="config_wifiConnectedHighRssiScanMinimumWindowSizeSec" />
+ <item type="integer" name="config_wifiDisableReasonAssociationRejectionThreshold" />
+ <item type="integer" name="config_wifiDisableReasonAuthenticationFailureThreshold" />
+ <item type="integer" name="config_wifiDisableReasonDhcpFailureThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorApUnableToHandleNewStaThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorNetworkValidationFailureThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorWrongPasswordThreshold" />
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 28fdade..912c6c1 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -179,6 +179,20 @@
TEST_MAX_NUM_ACTIVE_CHANNELS_FOR_PARTIAL_SCAN);
mResources.setBoolean(R.bool.config_wifi_connected_mac_randomization_supported, true);
mResources.setInteger(R.integer.config_wifiMaxPnoSsidCount, 16);
+ mResources.setInteger(
+ R.integer.config_wifiDisableReasonAssociationRejectionThreshold,
+ NetworkSelectionStatus.DISABLE_REASON_INFOS
+ .get(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION)
+ .mDisableThreshold);
+ mResources.setInteger(
+ R.integer.config_wifiDisableReasonAuthenticationFailureThreshold,
+ NetworkSelectionStatus.DISABLE_REASON_INFOS
+ .get(NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE)
+ .mDisableThreshold);
+ mResources.setInteger(
+ R.integer.config_wifiDisableReasonDhcpFailureThreshold,
+ NetworkSelectionStatus.DISABLE_REASON_INFOS
+ .get(NetworkSelectionStatus.DISABLED_DHCP_FAILURE).mDisableThreshold);
when(mContext.getResources()).thenReturn(mResources);
// Setup UserManager profiles for the default user.
@@ -1219,6 +1233,40 @@
}
/**
+ * Verify that the parameters in DISABLE_REASON_INFOS are overlayable.
+ */
+ @Test
+ public void testNetworkSelectionDisableReasonCustomConfigOverride() {
+ int oldThreshold = NetworkSelectionStatus.DISABLE_REASON_INFOS
+ .get(NetworkSelectionStatus.DISABLED_DHCP_FAILURE).mDisableThreshold;
+
+ // Modify the overlay value and create WifiConfigManager again.
+ int newThreshold = oldThreshold + 1;
+ mResources.setInteger(
+ R.integer.config_wifiDisableReasonDhcpFailureThreshold, newThreshold);
+ createWifiConfigManager();
+
+ // Verify that the threshold is updated in the copied version
+ assertEquals(newThreshold, mWifiConfigManager.getNetworkSelectionDisableThreshold(
+ NetworkSelectionStatus.DISABLED_DHCP_FAILURE));
+ // Verify the original DISABLE_REASON_INFOS is unchanged
+ assertEquals(oldThreshold, NetworkSelectionStatus.DISABLE_REASON_INFOS
+ .get(NetworkSelectionStatus.DISABLED_DHCP_FAILURE).mDisableThreshold);
+ }
+
+ /**
+ * Verify the correctness of the copied DISABLE_REASON_INFOS.
+ */
+ @Test
+ public void testNetworkSelectionDisableReasonClone() {
+ for (int i = 1; i < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; i++) {
+ assertEquals("Disable threshold for reason=" + i + " should be equal",
+ NetworkSelectionStatus.DISABLE_REASON_INFOS.get(i).mDisableThreshold,
+ mWifiConfigManager.getNetworkSelectionDisableThreshold(i));
+ }
+ }
+
+ /**
* Verifies the update of network status using
* {@link WifiConfigManager#updateNetworkSelectionStatus(int, int)}.
*/
@@ -1239,7 +1287,7 @@
// disable it 5 times to actually mark it temporarily disabled.
int assocRejectReason = NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION;
int assocRejectThreshold =
- WifiConfigManager.getNetworkSelectionDisableThreshold(assocRejectReason);
+ mWifiConfigManager.getNetworkSelectionDisableThreshold(assocRejectReason);
for (int i = 1; i <= assocRejectThreshold; i++) {
verifyUpdateNetworkSelectionStatus(result.getNetworkId(), assocRejectReason, i);
}
@@ -1335,7 +1383,7 @@
result.getNetworkId(), NetworkSelectionStatus.DISABLED_NONE, 0);
int disableThreshold =
- WifiConfigManager.getNetworkSelectionDisableThreshold(reason);
+ mWifiConfigManager.getNetworkSelectionDisableThreshold(reason);
for (int i = 1; i <= disableThreshold; i++) {
verifyUpdateNetworkSelectionStatus(result.getNetworkId(), reason, i);
}
@@ -1378,7 +1426,7 @@
int numBssidsInBlocklist = i;
when(mBssidBlocklistMonitor.updateAndGetNumBlockedBssidsForSsid(anyString()))
.thenReturn(numBssidsInBlocklist);
- timeout = WifiConfigManager.getNetworkSelectionDisableTimeoutMillis(disableReason)
+ timeout = mWifiConfigManager.getNetworkSelectionDisableTimeoutMillis(disableReason)
* multiplier;
multiplier *= 2;
verifyNetworkIsEnabledAfter(result.getNetworkId(),
@@ -5306,7 +5354,7 @@
long retrievedDisableTime = retrievedStatus.getDisableTime();
int retrievedDisableReasonCounter = retrievedStatus.getDisableReasonCounter(reason);
int disableReasonThreshold =
- WifiConfigManager.getNetworkSelectionDisableThreshold(reason);
+ mWifiConfigManager.getNetworkSelectionDisableThreshold(reason);
if (reason == NetworkSelectionStatus.DISABLED_NONE) {
assertEquals(reason, retrievedDisableReason);
@@ -5482,7 +5530,7 @@
int assocRejectReason = NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION;
int assocRejectThreshold =
- WifiConfigManager.getNetworkSelectionDisableThreshold(assocRejectReason);
+ mWifiConfigManager.getNetworkSelectionDisableThreshold(assocRejectReason);
for (int i = 1; i <= assocRejectThreshold; i++) {
assertFalse(mWifiConfigManager.updateNetworkSelectionStatus(
networkId, assocRejectReason));