diff options
7 files changed, 250 insertions, 35 deletions
diff --git a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java index 2921729ca..7aab09cc5 100644 --- a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java +++ b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -55,8 +56,8 @@ public class BssidBlocklistMonitor { public static final int REASON_AUTHENTICATION_FAILURE = 6; // DHCP failures public static final int REASON_DHCP_FAILURE = 7; - // Local constant being used to keep track of how many failure reasons there are. - private static final int NUMBER_REASON_CODES = 8; + // Constant being used to keep track of how many failure reasons there are. + public static final int NUMBER_REASON_CODES = 8; @IntDef(prefix = { "REASON_" }, value = { REASON_AP_UNABLE_TO_HANDLE_NEW_STA, @@ -69,7 +70,7 @@ public class BssidBlocklistMonitor { REASON_DHCP_FAILURE }) @Retention(RetentionPolicy.SOURCE) - public @interface BssidBlocklistMonitorFailureReason {} + public @interface FailureReason {} public static final int[] FAILURE_COUNT_DISABLE_THRESHOLD = { 1, // threshold for REASON_AP_UNABLE_TO_HANDLE_NEW_STA @@ -83,7 +84,9 @@ public class BssidBlocklistMonitor { }; private static final int FAILURE_COUNTER_THRESHOLD = 3; - private static final long BASE_BLOCKLIST_DURATION = 5 * 60 * 1000; // 5 minutes + private static final long BASE_BLOCKLIST_DURATION = TimeUnit.MINUTES.toMillis(5); // 5 minutes + private static final long MAX_BLOCKLIST_DURATION = TimeUnit.HOURS.toMillis(18); // 18 hours + private static final int FAILURE_STREAK_CAP = 7; private static final String TAG = "BssidBlocklistMonitor"; private final WifiLastResortWatchdog mWifiLastResortWatchdog; @@ -91,6 +94,7 @@ public class BssidBlocklistMonitor { private final Clock mClock; private final LocalLog mLocalLog; private final Calendar mCalendar; + private final WifiScoreCard mWifiScoreCard; // Map of bssid to BssidStatus private Map<String, BssidStatus> mBssidStatusMap = new ArrayMap<>(); @@ -99,12 +103,14 @@ public class BssidBlocklistMonitor { * Create a new instance of BssidBlocklistMonitor */ BssidBlocklistMonitor(WifiConnectivityHelper connectivityHelper, - WifiLastResortWatchdog wifiLastResortWatchdog, Clock clock, LocalLog localLog) { + WifiLastResortWatchdog wifiLastResortWatchdog, Clock clock, LocalLog localLog, + WifiScoreCard wifiScoreCard) { mConnectivityHelper = connectivityHelper; mWifiLastResortWatchdog = wifiLastResortWatchdog; mClock = clock; mLocalLog = localLog; mCalendar = Calendar.getInstance(); + mWifiScoreCard = wifiScoreCard; } // A helper to log debugging information in the local log buffer, which can @@ -113,10 +119,21 @@ public class BssidBlocklistMonitor { mLocalLog.log(log); } - private long getBlocklistDurationWithExponentialBackoff(String bssid) { - // TODO: b/139287182 implement exponential backoff to extend the blocklist duration for - // BSSIDs that continue to fail. - return BASE_BLOCKLIST_DURATION; + /** + * calculates the blocklist duration based on the current failure streak with exponential + * backoff. + * @param failureStreak should be greater or equal to 0. + * @return duration to block the BSSID in milliseconds + */ + private long getBlocklistDurationWithExponentialBackoff(int failureStreak) { + if (failureStreak > FAILURE_STREAK_CAP) { + return MAX_BLOCKLIST_DURATION; + } + if (failureStreak < 1) { + return BASE_BLOCKLIST_DURATION; + } + long duration = (long) (Math.pow(2.0, (double) failureStreak) * BASE_BLOCKLIST_DURATION); + return Math.min(MAX_BLOCKLIST_DURATION, duration); } /** @@ -129,14 +146,14 @@ public class BssidBlocklistMonitor { pw.println("BssidBlocklistMonitor - Bssid blocklist End ----"); } - private boolean addToBlocklist(@NonNull BssidStatus entry) { + private boolean addToBlocklist(@NonNull BssidStatus entry, int failureStreak) { // Call mWifiLastResortWatchdog.shouldIgnoreBssidUpdate to give watchdog a chance to // trigger before blocklisting the bssid. String bssid = entry.bssid; if (mWifiLastResortWatchdog.shouldIgnoreBssidUpdate(bssid)) { return false; } - long durationMs = getBlocklistDurationWithExponentialBackoff(bssid); + long durationMs = getBlocklistDurationWithExponentialBackoff(failureStreak); entry.addToBlocklist(durationMs); localLog(TAG + " addToBlocklist: bssid=" + bssid + ", ssid=" + entry.ssid + ", durationMs=" + durationMs); @@ -168,7 +185,7 @@ public class BssidBlocklistMonitor { * @return True if the blocklist has been modified. */ public boolean handleBssidConnectionFailure(String bssid, String ssid, - @BssidBlocklistMonitorFailureReason int reasonCode) { + @FailureReason int reasonCode) { if (bssid == null || ssid == null || WifiManager.UNKNOWN_SSID.equals(ssid) || bssid.equals(ClientModeImpl.SUPPLICANT_BSSID_ANY) || reasonCode < 0 || reasonCode >= NUMBER_REASON_CODES) { @@ -178,8 +195,12 @@ public class BssidBlocklistMonitor { } boolean result = false; BssidStatus entry = incrementFailureCountForBssid(bssid, ssid, reasonCode); - if (entry.failureCount[reasonCode] >= FAILURE_COUNT_DISABLE_THRESHOLD[reasonCode]) { - result = addToBlocklist(entry); + + int currentStreak = mWifiScoreCard.getBssidBlocklistStreak(ssid, bssid, reasonCode); + if (currentStreak > 0 + || entry.failureCount[reasonCode] >= FAILURE_COUNT_DISABLE_THRESHOLD[reasonCode]) { + result = addToBlocklist(entry, currentStreak); + mWifiScoreCard.incrementBssidBlocklistStreak(ssid, bssid, reasonCode); } return result; } @@ -187,7 +208,19 @@ public class BssidBlocklistMonitor { /** * Note a connection success event on a bssid and clear appropriate failure counters. */ - public void handleBssidConnectionSuccess(@NonNull String bssid) { + public void handleBssidConnectionSuccess(@NonNull String bssid, @NonNull String ssid) { + /** + * First reset the blocklist streak. + * This needs to be done even if a BssidStatus is not found, since the BssidStatus may + * have been removed due to blocklist timeout. + */ + mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_AP_UNABLE_TO_HANDLE_NEW_STA); + mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_WRONG_PASSWORD); + mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_EAP_FAILURE); + mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_ASSOCIATION_REJECTION); + mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_ASSOCIATION_TIMEOUT); + mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_AUTHENTICATION_FAILURE); + BssidStatus status = mBssidStatusMap.get(bssid); if (status == null) { return; @@ -204,7 +237,8 @@ public class BssidBlocklistMonitor { /** * Note a successful network validation on a BSSID and clear appropriate failure counters. */ - public void handleNetworkValidationSuccess(@NonNull String bssid) { + public void handleNetworkValidationSuccess(@NonNull String bssid, @NonNull String ssid) { + mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_NETWORK_VALIDATION_FAILURE); BssidStatus status = mBssidStatusMap.get(bssid); if (status == null) { return; @@ -215,7 +249,8 @@ public class BssidBlocklistMonitor { /** * Note a successful DHCP provisioning and clear appropriate faliure counters. */ - public void handleDhcpProvisioningSuccess(@NonNull String bssid) { + public void handleDhcpProvisioningSuccess(@NonNull String bssid, @NonNull String ssid) { + mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_DHCP_FAILURE); BssidStatus status = mBssidStatusMap.get(bssid); if (status == null) { return; diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index dfd92d3e2..d95f6e8be 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -2818,7 +2818,7 @@ public class ClientModeImpl extends StateMachine { mWifiInfo.setTrusted(config.trusted); mWifiConfigManager.updateRandomizedMacExpireTime(config, dhcpResults.getLeaseDuration()); - mBssidBlocklistMonitor.handleDhcpProvisioningSuccess(mLastBssid); + mBssidBlocklistMonitor.handleDhcpProvisioningSuccess(mLastBssid, mWifiInfo.getSSID()); } // Set meteredHint if DHCP result says network is metered @@ -4275,7 +4275,7 @@ public class ClientModeImpl extends StateMachine { mCountryCode.setReadyForChange(false); mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED); mWifiScoreCard.noteNetworkAgentCreated(mWifiInfo, mNetworkAgent.netId); - mBssidBlocklistMonitor.handleBssidConnectionSuccess(mLastBssid); + mBssidBlocklistMonitor.handleBssidConnectionSuccess(mLastBssid, mWifiInfo.getSSID()); } @Override @@ -4868,7 +4868,8 @@ public class ClientModeImpl extends StateMachine { sendNetworkStateChangeBroadcast(mLastBssid); // Successful framework roam! (probably) - mBssidBlocklistMonitor.handleBssidConnectionSuccess(mLastBssid); + mBssidBlocklistMonitor.handleBssidConnectionSuccess(mLastBssid, + mWifiInfo.getSSID()); reportConnectionAttemptEnd( WifiMetrics.ConnectionEvent.FAILURE_NONE, WifiMetricsProto.ConnectionEvent.HLF_NONE, @@ -5014,7 +5015,8 @@ public class ClientModeImpl extends StateMachine { mWifiDiagnostics.reportConnectionEvent( WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED); mWifiScoreCard.noteValidationSuccess(mWifiInfo); - mBssidBlocklistMonitor.handleNetworkValidationSuccess(mLastBssid); + mBssidBlocklistMonitor.handleNetworkValidationSuccess(mLastBssid, + mWifiInfo.getSSID()); config = getCurrentWifiConfiguration(); if (config != null) { // re-enable autojoin diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index 646b7a014..3c77c09f7 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -603,7 +603,7 @@ public class WifiInjector { mWifiMetrics, clientModeImpl, mWifiHandlerThread.getLooper(), mDeviceConfigFacade, mWifiThreadRunner); mBssidBlocklistMonitor = new BssidBlocklistMonitor(mWifiConnectivityHelper, - mWifiLastResortWatchdog, mClock, mConnectivityLocalLog); + mWifiLastResortWatchdog, mClock, mConnectivityLocalLog, mWifiScoreCard); mWifiChannelUtilization = new WifiChannelUtilization(mClock); return new WifiConnectivityManager(mContext, getScoringParams(), clientModeImpl, this, diff --git a/service/java/com/android/server/wifi/WifiScoreCard.java b/service/java/com/android/server/wifi/WifiScoreCard.java index 87d9c3403..19f74d0f2 100644 --- a/service/java/com/android/server/wifi/WifiScoreCard.java +++ b/service/java/com/android/server/wifi/WifiScoreCard.java @@ -379,11 +379,40 @@ public class WifiScoreCard { doWrites(); } + /** + * Increment the blocklist streak count for a failure reason on an AP. + * @return the updated count + */ + public int incrementBssidBlocklistStreak(String ssid, String bssid, + @BssidBlocklistMonitor.FailureReason int reason) { + PerBssid perBssid = lookupBssid(ssid, bssid); + return ++perBssid.blocklistStreakCount[reason]; + } + + /** + * Get the blocklist streak count for a failure reason on an AP. + * @return the blocklist streak count + */ + public int getBssidBlocklistStreak(String ssid, String bssid, + @BssidBlocklistMonitor.FailureReason int reason) { + return lookupBssid(ssid, bssid).blocklistStreakCount[reason]; + } + + /** + * Clear the blocklist streak count for a failure reason on an AP. + */ + public void resetBssidBlocklistStreak(String ssid, String bssid, + @BssidBlocklistMonitor.FailureReason int reason) { + lookupBssid(ssid, bssid).blocklistStreakCount[reason] = 0; + } + final class PerBssid { public int id; public final String l2Key; public final String ssid; public final MacAddress bssid; + public final int[] blocklistStreakCount = + new int[BssidBlocklistMonitor.NUMBER_REASON_CODES]; public boolean changed; public boolean referenced; diff --git a/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java b/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java index 985dd45c8..118e3d0df 100644 --- a/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java +++ b/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java @@ -30,6 +30,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.Set; +import java.util.concurrent.TimeUnit; /** * Unit tests for {@link com.android.server.wifi.BssidBlocklistMonitor}. @@ -45,13 +46,16 @@ public class BssidBlocklistMonitorTest { private static final String TEST_BSSID_3 = "0a:08:5c:67:89:02"; private static final int TEST_L2_FAILURE = BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION; private static final int TEST_DHCP_FAILURE = BssidBlocklistMonitor.REASON_DHCP_FAILURE; - private static final long BASE_BLOCKLIST_DURATION = 5 * 60 * 1000; // 5 minutes + private static final long BASE_BLOCKLIST_DURATION = TimeUnit.MINUTES.toMillis(5); // 5 minutes + private static final long MAX_BLOCKLIST_DURATION = TimeUnit.HOURS.toMillis(18); // 18 hours + private static final int FAILURE_STREAK_CAP = 7; private static final int NUM_FAILURES_TO_BLOCKLIST = 3; @Mock private WifiConnectivityHelper mWifiConnectivityHelper; @Mock private WifiLastResortWatchdog mWifiLastResortWatchdog; @Mock private Clock mClock; @Mock private LocalLog mLocalLog; + @Mock private WifiScoreCard mWifiScoreCard; private BssidBlocklistMonitor mBssidBlocklistMonitor; @@ -63,7 +67,7 @@ public class BssidBlocklistMonitorTest { when(mWifiConnectivityHelper.getMaxNumBlacklistBssid()) .thenReturn(TEST_NUM_MAX_FIRMWARE_SUPPORT_BSSIDS); mBssidBlocklistMonitor = new BssidBlocklistMonitor(mWifiConnectivityHelper, - mWifiLastResortWatchdog, mClock, mLocalLog); + mWifiLastResortWatchdog, mClock, mLocalLog, mWifiScoreCard); } private void verifyAddTestBssidToBlocklist() { @@ -115,11 +119,49 @@ public class BssidBlocklistMonitorTest { assertTrue(mBssidBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_1)); // Verify that TEST_BSSID_1 is removed from the blocklist after the timeout duration. + // By default there is no blocklist streak so the timeout duration is simply + // BASE_BLOCKLIST_DURATION when(mClock.getWallClockMillis()).thenReturn(BASE_BLOCKLIST_DURATION + 1); assertEquals(0, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size()); } /** + * Verify that when adding a AP that had already been failing (therefore has a blocklist + * streak), we are setting the blocklist duration using an exponential backoff technique. + */ + @Test + public void testBssidIsRemoveFromBlocklistAfterTimoutExponentialBackoff() { + verifyAddTestBssidToBlocklist(); + int multiplier = 2; + for (int i = 1; i <= FAILURE_STREAK_CAP; i++) { + when(mWifiScoreCard.getBssidBlocklistStreak(anyString(), anyString(), anyInt())) + .thenReturn(i); + when(mClock.getWallClockMillis()).thenReturn(0L); + verifyAddTestBssidToBlocklist(); + + // calculate the expected blocklist duration then verify that timeout happens + // exactly after the duration. + long duration = multiplier * BASE_BLOCKLIST_DURATION; + when(mClock.getWallClockMillis()).thenReturn(duration); + assertTrue(mBssidBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_1)); + when(mClock.getWallClockMillis()).thenReturn(duration + 1); + assertEquals(0, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size()); + + multiplier *= 2; + } + + // finally verify that the timout is capped at some max value + when(mWifiScoreCard.getBssidBlocklistStreak(anyString(), anyString(), anyInt())) + .thenReturn(FAILURE_STREAK_CAP + 1); + when(mClock.getWallClockMillis()).thenReturn(0L); + verifyAddTestBssidToBlocklist(); + when(mClock.getWallClockMillis()).thenReturn(MAX_BLOCKLIST_DURATION); + assertTrue(mBssidBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_1)); + when(mClock.getWallClockMillis()).thenReturn(MAX_BLOCKLIST_DURATION + 1); + assertEquals(0, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size()); + } + + /** * Verify that consecutive failures will add a BSSID to blocklist. */ @Test @@ -140,6 +182,19 @@ public class BssidBlocklistMonitorTest { } /** + * Verify that when the BSSID blocklist streak is greater or equal to 1, then we block a + * BSSID on a single failure regardless of failure type. + */ + @Test + public void testBlocklistStreakExpeditesAddingToBlocklist() { + when(mWifiScoreCard.getBssidBlocklistStreak(anyString(), anyString(), anyInt())) + .thenReturn(1); + assertTrue(mBssidBlocklistMonitor.handleBssidConnectionFailure( + TEST_BSSID_1, TEST_SSID_1, TEST_L2_FAILURE)); + assertTrue(mBssidBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_1)); + } + + /** * Verify that onSuccessfulConnection resets L2 related failure counts. */ @Test @@ -149,7 +204,7 @@ public class BssidBlocklistMonitorTest { NUM_FAILURES_TO_BLOCKLIST - 1); // Verify that a connection success event will clear the failure count. - mBssidBlocklistMonitor.handleBssidConnectionSuccess(TEST_BSSID_1); + mBssidBlocklistMonitor.handleBssidConnectionSuccess(TEST_BSSID_1, TEST_SSID_1); handleBssidConnectionFailureMultipleTimes(TEST_BSSID_1, TEST_L2_FAILURE, NUM_FAILURES_TO_BLOCKLIST - 1); @@ -170,8 +225,8 @@ public class BssidBlocklistMonitorTest { handleBssidConnectionFailureMultipleTimes(TEST_BSSID_1, TEST_DHCP_FAILURE, NUM_FAILURES_TO_BLOCKLIST - 1); - // Verify that a network validation success event will clear the failure count. - mBssidBlocklistMonitor.handleDhcpProvisioningSuccess(TEST_BSSID_1); + // Verify that a dhcp provisioning success event will clear appropirate failure counts. + mBssidBlocklistMonitor.handleDhcpProvisioningSuccess(TEST_BSSID_1, TEST_SSID_1); handleBssidConnectionFailureMultipleTimes(TEST_BSSID_1, TEST_DHCP_FAILURE, NUM_FAILURES_TO_BLOCKLIST - 1); @@ -184,6 +239,46 @@ public class BssidBlocklistMonitorTest { } /** + * Verify that handleBssidConnectionSuccess resets appropriate blocklist streak counts. + */ + @Test + public void testNetworkConnectionResetsBlocklistStreak() { + mBssidBlocklistMonitor.handleBssidConnectionSuccess(TEST_BSSID_1, TEST_SSID_1); + verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA); + verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_WRONG_PASSWORD); + verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_EAP_FAILURE); + verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION); + verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT); + verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_AUTHENTICATION_FAILURE); + } + + /** + * Verify that handleDhcpProvisioningSuccess resets appropriate blocklist streak counts. + */ + @Test + public void testDhcpProvisioningResetsBlocklistStreak() { + mBssidBlocklistMonitor.handleDhcpProvisioningSuccess(TEST_BSSID_1, TEST_SSID_1); + verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_DHCP_FAILURE); + } + + /** + * Verify that handleNetworkValidationSuccess resets appropriate blocklist streak counts. + */ + @Test + public void testNetworkValidationResetsBlocklistStreak() { + mBssidBlocklistMonitor.handleNetworkValidationSuccess(TEST_BSSID_1, TEST_SSID_1); + verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE); + } + + /** * Verify that L3 failure counts are not affected when L2 failure counts are reset. */ @Test @@ -194,12 +289,31 @@ public class BssidBlocklistMonitorTest { assertEquals(0, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size()); // Verify that the failure counter is not cleared by |handleBssidConnectionSuccess|. - mBssidBlocklistMonitor.handleBssidConnectionSuccess(TEST_BSSID_1); + mBssidBlocklistMonitor.handleBssidConnectionSuccess(TEST_BSSID_1, TEST_SSID_1); handleBssidConnectionFailureMultipleTimes(TEST_BSSID_1, TEST_DHCP_FAILURE, 1); assertEquals(1, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size()); } /** + * Verify that the blocklist streak is incremented after adding a BSSID to blocklist. + * And then verify the blocklist streak is not reset by a regular timeout. + */ + public void testIncrementingBlocklistStreakCount() { + verifyAddTestBssidToBlocklist(); + // verify that the blocklist streak is incremented + verify(mWifiScoreCard).incrementBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA); + + // Verify that TEST_BSSID_1 is removed from the blocklist after the timeout duration. + when(mClock.getWallClockMillis()).thenReturn(BASE_BLOCKLIST_DURATION + 1); + assertEquals(0, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size()); + + // But the blacklist streak count is not cleared + verify(mWifiScoreCard, never()).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA); + } + + /** * Verify that when a failure signal is received for a BSSID with different SSID from before, * then the failure counts are reset. */ diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index b59ee2a2a..51300190a 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -958,6 +958,10 @@ public class ClientModeImplTest extends WifiBaseTest { when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); + mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, + new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.ASSOCIATED)); + mLooper.dispatchAll(); + mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); mLooper.dispatchAll(); @@ -1550,10 +1554,14 @@ public class ClientModeImplTest extends WifiBaseTest { verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); + mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, + new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.ASSOCIATED)); + mLooper.dispatchAll(); + mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); mLooper.dispatchAll(); + verify(mBssidBlocklistMonitor).handleBssidConnectionSuccess(sBSSID, sSSID); - verify(mBssidBlocklistMonitor).handleBssidConnectionSuccess(sBSSID); mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); mLooper.dispatchAll(); @@ -1571,8 +1579,8 @@ public class ClientModeImplTest extends WifiBaseTest { sSSID, BssidBlocklistMonitor.REASON_DHCP_FAILURE); verify(mBssidBlocklistMonitor, times(2)).handleBssidConnectionFailure(sBSSID, sSSID, BssidBlocklistMonitor.REASON_DHCP_FAILURE); - verify(mBssidBlocklistMonitor, never()).handleDhcpProvisioningSuccess(sBSSID); - verify(mBssidBlocklistMonitor, never()).handleNetworkValidationSuccess(sBSSID); + verify(mBssidBlocklistMonitor, never()).handleDhcpProvisioningSuccess(sBSSID, sSSID); + verify(mBssidBlocklistMonitor, never()).handleNetworkValidationSuccess(sBSSID, sSSID); } /** @@ -3402,9 +3410,9 @@ public class ClientModeImplTest extends WifiBaseTest { public void verifyNetworkSelectionEnableOnInternetValidation() throws Exception { // Simulate the first connection. connect(); - verify(mBssidBlocklistMonitor).handleBssidConnectionSuccess(sBSSID); - verify(mBssidBlocklistMonitor).handleDhcpProvisioningSuccess(sBSSID); - verify(mBssidBlocklistMonitor, never()).handleNetworkValidationSuccess(sBSSID); + verify(mBssidBlocklistMonitor).handleBssidConnectionSuccess(sBSSID, sSSID); + verify(mBssidBlocklistMonitor).handleDhcpProvisioningSuccess(sBSSID, sSSID); + verify(mBssidBlocklistMonitor, never()).handleNetworkValidationSuccess(sBSSID, sSSID); ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), @@ -3425,7 +3433,7 @@ public class ClientModeImplTest extends WifiBaseTest { verify(mWifiConfigManager).updateNetworkSelectionStatus( FRAMEWORK_NETWORK_ID, NETWORK_SELECTION_ENABLE); verify(mWifiScoreCard).noteValidationSuccess(any()); - verify(mBssidBlocklistMonitor).handleNetworkValidationSuccess(sBSSID); + verify(mBssidBlocklistMonitor).handleNetworkValidationSuccess(sBSSID, sSSID); } /** diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java index 5c2fc0a27..f1590144a 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java @@ -61,6 +61,9 @@ public class WifiScoreCardTest extends WifiBaseTest { static final double TOL = 1e-6; // for assertEquals(double, double, tolerance) + static final int TEST_BSSID_FAILURE_REASON = + BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION; + WifiScoreCard mWifiScoreCard; @Mock Clock mClock; @@ -127,6 +130,30 @@ public class WifiScoreCardTest extends WifiBaseTest { } /** + * Test the get, increment, and removal of Bssid blocklist streak counts. + */ + @Test + public void testBssidBlocklistStreakOperations() { + mWifiInfo.setSSID(TEST_SSID_1); + mWifiInfo.setBSSID(TEST_BSSID_1.toString()); + mWifiScoreCard.noteIpConfiguration(mWifiInfo); + + String ssid = mWifiInfo.getSSID(); + String bssid = mWifiInfo.getBSSID(); + assertEquals(0, mWifiScoreCard.getBssidBlocklistStreak( + ssid, bssid, TEST_BSSID_FAILURE_REASON)); + for (int i = 1; i < 3; i++) { + assertEquals(i, mWifiScoreCard.incrementBssidBlocklistStreak( + ssid, bssid, TEST_BSSID_FAILURE_REASON)); + assertEquals(i, mWifiScoreCard.getBssidBlocklistStreak( + ssid, bssid, TEST_BSSID_FAILURE_REASON)); + } + mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, TEST_BSSID_FAILURE_REASON); + assertEquals(0, mWifiScoreCard.getBssidBlocklistStreak( + ssid, bssid, TEST_BSSID_FAILURE_REASON)); + } + + /** * Test identifiers. */ @Test |