From 80d0986ea4ec6d2bff2af02a9e1a31593c200540 Mon Sep 17 00:00:00 2001 From: xshu Date: Thu, 10 Sep 2020 19:46:04 -0700 Subject: Exponential backoff for external score blocklist (cherry-picked from 89ab95af87eff69a5865124fc4bc529e1f6efb52) Changes: 1. When the external scorer marks a network as unacceptable, block the BSSID for 0.5/1/2/... up to 64 minutes instead of the previous fixed 30 seconds. 2. Modified test cases to increase coverage. Bug: 158695052 Test: atest com.android.server.wifi Change-Id: I0f1413563530c8e66ea6a061c78bc49bffd61091 --- .../server/wifi/BssidBlocklistMonitorTest.java | 104 ++++++++++++++------- .../android/server/wifi/WifiScoreReportTest.java | 15 ++- 2 files changed, 79 insertions(+), 40 deletions(-) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java b/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java index d6333b363..1007391e3 100644 --- a/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java +++ b/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java @@ -18,6 +18,7 @@ package com.android.server.wifi; import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import static org.mockito.Mockito.times; import android.content.Context; import android.net.wifi.ScanResult; @@ -34,6 +35,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -57,23 +59,28 @@ public class BssidBlocklistMonitorTest { 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 = TimeUnit.MINUTES.toMillis(5); // 5 minutes + private static final long BASE_CONNECTED_SCORE_BLOCKLIST_DURATION = + TimeUnit.SECONDS.toMillis(30); private static final long ABNORMAL_DISCONNECT_TIME_WINDOW_MS = TimeUnit.SECONDS.toMillis(30); private static final long ABNORMAL_DISCONNECT_RESET_TIME_MS = TimeUnit.HOURS.toMillis(3); private static final int FAILURE_STREAK_CAP = 7; - private static final int[] FAILURE_COUNT_DISABLE_THRESHOLD = { - 1, // threshold for REASON_AP_UNABLE_TO_HANDLE_NEW_STA - 1, // threshold for REASON_NETWORK_VALIDATION_FAILURE - 1, // threshold for REASON_WRONG_PASSWORD - 1, // threshold for REASON_EAP_FAILURE - 3, // threshold for REASON_ASSOCIATION_REJECTION - 3, // threshold for REASON_ASSOCIATION_TIMEOUT - 3, // threshold for REASON_AUTHENTICATION_FAILURE - 3, // threshold for REASON_DHCP_FAILURE - 3 // threshold for REASON_ABNORMAL_DISCONNECT - }; + private static final Map BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP = + Map.ofEntries( + Map.entry(BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA, 1), + Map.entry(BssidBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE, 1), + Map.entry(BssidBlocklistMonitor.REASON_WRONG_PASSWORD, 1), + Map.entry(BssidBlocklistMonitor.REASON_EAP_FAILURE, 1), + Map.entry(BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION, 3), + Map.entry(BssidBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT, 3), + Map.entry(BssidBlocklistMonitor.REASON_AUTHENTICATION_FAILURE, 3), + Map.entry(BssidBlocklistMonitor.REASON_DHCP_FAILURE, 3), + Map.entry(BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT, 3), + Map.entry(BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_MBO_OCE, 1), + Map.entry(BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_FAST_RECONNECT, 1), + Map.entry(BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE, 1) + ); private static final int NUM_FAILURES_TO_BLOCKLIST = - FAILURE_COUNT_DISABLE_THRESHOLD[TEST_L2_FAILURE]; - + BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(TEST_L2_FAILURE); @Mock private Context mContext; @Mock private WifiConnectivityHelper mWifiConnectivityHelper; @@ -97,34 +104,46 @@ public class BssidBlocklistMonitorTest { mResources = new MockResources(); mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorBaseBlockDurationMs, (int) BASE_BLOCKLIST_DURATION); + mResources.setInteger( + R.integer.config_wifiBssidBlocklistMonitorConnectedScoreBaseBlockDurationMs, + (int) BASE_CONNECTED_SCORE_BLOCKLIST_DURATION); mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorFailureStreakCap, FAILURE_STREAK_CAP); mResources.setInteger(R.integer.config_wifiBssidBlocklistAbnormalDisconnectTimeWindowMs, (int) ABNORMAL_DISCONNECT_TIME_WINDOW_MS); mResources.setInteger( R.integer.config_wifiBssidBlocklistMonitorApUnableToHandleNewStaThreshold, - FAILURE_COUNT_DISABLE_THRESHOLD[0]); + BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get( + BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA)); mResources.setInteger( R.integer.config_wifiBssidBlocklistMonitorNetworkValidationFailureThreshold, - FAILURE_COUNT_DISABLE_THRESHOLD[1]); + BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get( + BssidBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE)); mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorWrongPasswordThreshold, - FAILURE_COUNT_DISABLE_THRESHOLD[2]); + BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get( + BssidBlocklistMonitor.REASON_WRONG_PASSWORD)); mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorEapFailureThreshold, - FAILURE_COUNT_DISABLE_THRESHOLD[3]); + BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get( + BssidBlocklistMonitor.REASON_EAP_FAILURE)); mResources.setInteger( R.integer.config_wifiBssidBlocklistMonitorAssociationRejectionThreshold, - FAILURE_COUNT_DISABLE_THRESHOLD[4]); + BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get( + BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION)); mResources.setInteger( R.integer.config_wifiBssidBlocklistMonitorAssociationTimeoutThreshold, - FAILURE_COUNT_DISABLE_THRESHOLD[5]); + BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get( + BssidBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT)); mResources.setInteger( R.integer.config_wifiBssidBlocklistMonitorAuthenticationFailureThreshold, - FAILURE_COUNT_DISABLE_THRESHOLD[6]); + BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get( + BssidBlocklistMonitor.REASON_AUTHENTICATION_FAILURE)); mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorDhcpFailureThreshold, - FAILURE_COUNT_DISABLE_THRESHOLD[7]); + BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get( + BssidBlocklistMonitor.REASON_DHCP_FAILURE)); mResources.setInteger( R.integer.config_wifiBssidBlocklistMonitorAbnormalDisconnectThreshold, - FAILURE_COUNT_DISABLE_THRESHOLD[8]); + BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get( + BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT)); when(mContext.getResources()).thenReturn(mResources); mBssidBlocklistMonitor = new BssidBlocklistMonitor(mContext, mWifiConnectivityHelper, @@ -394,6 +413,8 @@ public class BssidBlocklistMonitorTest { ABNORMAL_DISCONNECT_RESET_TIME_MS + 1); verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT); + verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE); } /** @@ -409,6 +430,20 @@ public class BssidBlocklistMonitorTest { BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT); } + /** + * Verify that the streak count for REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE is not reset + * if insufficient time has passed. + */ + @Test + public void testNetworkConnectionNotResetConnectedScoreStreak() { + when(mClock.getWallClockMillis()).thenReturn(ABNORMAL_DISCONNECT_RESET_TIME_MS); + mBssidBlocklistMonitor.handleBssidConnectionSuccess(TEST_BSSID_1, TEST_SSID_1); + verify(mWifiScoreCard).setBssidConnectionTimestampMs(TEST_SSID_1, TEST_BSSID_1, + ABNORMAL_DISCONNECT_RESET_TIME_MS); + verify(mWifiScoreCard, never()).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE); + } + /** * Verify that handleDhcpProvisioningSuccess resets appropriate blocklist streak counts. */ @@ -454,18 +489,23 @@ public class BssidBlocklistMonitorTest { */ @Test 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); + for (Map.Entry entry : BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.entrySet()) { + int reason = entry.getKey(); + int threshold = entry.getValue(); + when(mClock.getWallClockMillis()).thenReturn(0L); + handleBssidConnectionFailureMultipleTimes(TEST_BSSID_1, TEST_SSID_1, reason, threshold); - // 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()); + // verify that the blocklist streak is incremented + verify(mWifiScoreCard).incrementBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, reason); - // 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 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 blocklist streak count is not cleared + verify(mWifiScoreCard, never()).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, + reason); + } } /** diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java index 954d4fe82..b85f223b7 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java @@ -20,16 +20,15 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.AdditionalAnswers.answerVoid; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atMost; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -782,7 +781,7 @@ public class WifiScoreReportTest extends WifiBaseTest { } /** - * Verify BSSID blocklist doesnot happen when score stays below threshold for less than the + * Verify BSSID blocklist does not happen when score stays below threshold for less than the * minimum duration */ @Test @@ -802,7 +801,7 @@ public class WifiScoreReportTest extends WifiBaseTest { mLooper.dispatchAll(); mWifiScoreReport.stopConnectedNetworkScorer(); mLooper.dispatchAll(); - verify(mBssidBlocklistMonitor, never()).blockBssidForDurationMs(any(), any(), anyLong(), + verify(mBssidBlocklistMonitor, never()).handleBssidConnectionFailure(any(), any(), anyInt(), anyInt()); } @@ -827,12 +826,12 @@ public class WifiScoreReportTest extends WifiBaseTest { mLooper.dispatchAll(); mWifiScoreReport.stopConnectedNetworkScorer(); mLooper.dispatchAll(); - verify(mBssidBlocklistMonitor).blockBssidForDurationMs(any(), any(), anyLong(), anyInt(), - anyInt()); + verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(any(), any(), + eq(BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE), anyInt()); } /** - * Verify BSSID blocklist doesnot happen when there is score flip flop + * Verify BSSID blocklist does not happen when there is score flip flop */ @Test public void bssidBlockListDoesnotHappenWhenExitingIsReset() throws Exception { @@ -854,7 +853,7 @@ public class WifiScoreReportTest extends WifiBaseTest { mLooper.dispatchAll(); mWifiScoreReport.stopConnectedNetworkScorer(); mLooper.dispatchAll(); - verify(mBssidBlocklistMonitor, never()).blockBssidForDurationMs(any(), any(), anyLong(), + verify(mBssidBlocklistMonitor, never()).handleBssidConnectionFailure(any(), any(), anyInt(), anyInt()); } -- cgit v1.2.3