Loading packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +17 −3 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro private static final long DEFAULT_MAX_CACHED_SCORE_AGE_MILLIS = 20 * DateUtils.MINUTE_IN_MILLIS; /** Maximum age of scan results to hold onto while actively scanning. **/ private static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000; @VisibleForTesting static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000; private static final String TAG = "WifiTracker"; private static final boolean DBG() { Loading Loading @@ -142,6 +142,13 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro */ private boolean mStaleScanResults = true; /** * Tracks whether the latest SCAN_RESULTS_AVAILABLE_ACTION contained new scans. If not, then * we treat the last scan as an aborted scan and increase the eviction timeout window to avoid * completely flushing the AP list before the next successful scan completes. */ private boolean mLastScanSucceeded = true; // Does not need to be locked as it only updated on the worker thread, with the exception of // during onStart, which occurs before the receiver is registered on the work handler. private final HashMap<String, ScanResult> mScanResultCache = new HashMap<>(); Loading Loading @@ -478,17 +485,22 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro } /** * Remove old scan results from the cache. * Remove old scan results from the cache. If {@link #mLastScanSucceeded} is false, then * increase the timeout window to avoid completely flushing the AP list before the next * successful scan completes. * * <p>Should only ever be invoked from {@link #updateScanResultCache(List)} when * {@link #mStaleScanResults} is false. */ private void evictOldScans() { long evictionTimeoutMillis = mLastScanSucceeded ? MAX_SCAN_RESULT_AGE_MILLIS : MAX_SCAN_RESULT_AGE_MILLIS * 2; long nowMs = SystemClock.elapsedRealtime(); for (Iterator<ScanResult> iter = mScanResultCache.values().iterator(); iter.hasNext(); ) { ScanResult result = iter.next(); // result timestamp is in microseconds if (nowMs - result.timestamp / 1000 > MAX_SCAN_RESULT_AGE_MILLIS) { if (nowMs - result.timestamp / 1000 > evictionTimeoutMillis) { iter.remove(); } } Loading Loading @@ -840,6 +852,8 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro WifiManager.WIFI_STATE_UNKNOWN)); } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) { mStaleScanResults = false; mLastScanSucceeded = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, true); fetchScansAndConfigsAndUpdateAccessPoints(); } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) Loading packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java +37 −4 Original line number Diff line number Diff line Loading @@ -270,7 +270,7 @@ public class WifiTrackerTest { SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */); } private static ScanResult buildStaleScanResult() { private static ScanResult buildScanResultWithTimestamp(long timestampMillis) { return new ScanResult( WifiSsid.createFromAsciiEncoded(SSID_3), BSSID_3, Loading @@ -280,7 +280,7 @@ public class WifiTrackerTest { "", // capabilities RSSI_3, 0, // frequency 0 /* microsecond timestamp */); timestampMillis * 1000 /* microsecond timestamp */); } private static WifiConfiguration buildPasspointConfiguration(String fqdn, String friendlyName) { Loading Loading @@ -379,6 +379,12 @@ public class WifiTrackerTest { tracker.mReceiver.onReceive(mContext, i); } private void sendFailedScanResults(WifiTracker tracker) throws InterruptedException { Intent i = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); i.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, false); tracker.mReceiver.onReceive(mContext, i); } private void sendUpdatedScores() throws InterruptedException { Bundle attr1 = new Bundle(); attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve1); Loading Loading @@ -982,8 +988,8 @@ public class WifiTrackerTest { @Test public void onStart_updateScanResults_evictOldScanResult() { when(mockWifiManager.getScanResults()).thenReturn( Arrays.asList(buildScanResult1(), buildScanResult2(), buildStaleScanResult())); when(mockWifiManager.getScanResults()).thenReturn(Arrays.asList( buildScanResult1(), buildScanResult2(), buildScanResultWithTimestamp(0))); WifiTracker tracker = createMockedWifiTracker(); tracker.forceUpdate(); Loading @@ -994,6 +1000,33 @@ public class WifiTrackerTest { assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2); } /** * Verifies that a failed scan reported on SCAN_RESULTS_AVAILABLE_ACTION should increase the * ScanResult eviction timeout to twice the default. */ @Test public void failedScan_increasesEvictionTimeout() throws InterruptedException { when(mockWifiManager.getScanResults()).thenReturn(Arrays.asList( buildScanResult1(), buildScanResult2(), buildScanResultWithTimestamp( SystemClock.elapsedRealtime() - WifiTracker.MAX_SCAN_RESULT_AGE_MILLIS))); WifiTracker tracker = createMockedWifiTracker(); sendFailedScanResults(tracker); // Failed scan increases timeout window to include the stale scan assertThat(tracker.getAccessPoints()).hasSize(3); assertThat(tracker.getAccessPoints().get(0).getBssid()).isEqualTo(BSSID_1); assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2); assertThat(tracker.getAccessPoints().get(2).getBssid()).isEqualTo(BSSID_3); sendScanResults(tracker); // Successful scan resets the timeout window to remove the stale scan assertThat(tracker.getAccessPoints()).hasSize(2); assertThat(tracker.getAccessPoints().get(0).getBssid()).isEqualTo(BSSID_1); assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2); } /** * Verifies that updatePasspointAccessPoints will only return AccessPoints whose * isPasspoint() evaluates as true. Loading Loading
packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +17 −3 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro private static final long DEFAULT_MAX_CACHED_SCORE_AGE_MILLIS = 20 * DateUtils.MINUTE_IN_MILLIS; /** Maximum age of scan results to hold onto while actively scanning. **/ private static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000; @VisibleForTesting static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000; private static final String TAG = "WifiTracker"; private static final boolean DBG() { Loading Loading @@ -142,6 +142,13 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro */ private boolean mStaleScanResults = true; /** * Tracks whether the latest SCAN_RESULTS_AVAILABLE_ACTION contained new scans. If not, then * we treat the last scan as an aborted scan and increase the eviction timeout window to avoid * completely flushing the AP list before the next successful scan completes. */ private boolean mLastScanSucceeded = true; // Does not need to be locked as it only updated on the worker thread, with the exception of // during onStart, which occurs before the receiver is registered on the work handler. private final HashMap<String, ScanResult> mScanResultCache = new HashMap<>(); Loading Loading @@ -478,17 +485,22 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro } /** * Remove old scan results from the cache. * Remove old scan results from the cache. If {@link #mLastScanSucceeded} is false, then * increase the timeout window to avoid completely flushing the AP list before the next * successful scan completes. * * <p>Should only ever be invoked from {@link #updateScanResultCache(List)} when * {@link #mStaleScanResults} is false. */ private void evictOldScans() { long evictionTimeoutMillis = mLastScanSucceeded ? MAX_SCAN_RESULT_AGE_MILLIS : MAX_SCAN_RESULT_AGE_MILLIS * 2; long nowMs = SystemClock.elapsedRealtime(); for (Iterator<ScanResult> iter = mScanResultCache.values().iterator(); iter.hasNext(); ) { ScanResult result = iter.next(); // result timestamp is in microseconds if (nowMs - result.timestamp / 1000 > MAX_SCAN_RESULT_AGE_MILLIS) { if (nowMs - result.timestamp / 1000 > evictionTimeoutMillis) { iter.remove(); } } Loading Loading @@ -840,6 +852,8 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro WifiManager.WIFI_STATE_UNKNOWN)); } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) { mStaleScanResults = false; mLastScanSucceeded = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, true); fetchScansAndConfigsAndUpdateAccessPoints(); } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) Loading
packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java +37 −4 Original line number Diff line number Diff line Loading @@ -270,7 +270,7 @@ public class WifiTrackerTest { SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */); } private static ScanResult buildStaleScanResult() { private static ScanResult buildScanResultWithTimestamp(long timestampMillis) { return new ScanResult( WifiSsid.createFromAsciiEncoded(SSID_3), BSSID_3, Loading @@ -280,7 +280,7 @@ public class WifiTrackerTest { "", // capabilities RSSI_3, 0, // frequency 0 /* microsecond timestamp */); timestampMillis * 1000 /* microsecond timestamp */); } private static WifiConfiguration buildPasspointConfiguration(String fqdn, String friendlyName) { Loading Loading @@ -379,6 +379,12 @@ public class WifiTrackerTest { tracker.mReceiver.onReceive(mContext, i); } private void sendFailedScanResults(WifiTracker tracker) throws InterruptedException { Intent i = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); i.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, false); tracker.mReceiver.onReceive(mContext, i); } private void sendUpdatedScores() throws InterruptedException { Bundle attr1 = new Bundle(); attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve1); Loading Loading @@ -982,8 +988,8 @@ public class WifiTrackerTest { @Test public void onStart_updateScanResults_evictOldScanResult() { when(mockWifiManager.getScanResults()).thenReturn( Arrays.asList(buildScanResult1(), buildScanResult2(), buildStaleScanResult())); when(mockWifiManager.getScanResults()).thenReturn(Arrays.asList( buildScanResult1(), buildScanResult2(), buildScanResultWithTimestamp(0))); WifiTracker tracker = createMockedWifiTracker(); tracker.forceUpdate(); Loading @@ -994,6 +1000,33 @@ public class WifiTrackerTest { assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2); } /** * Verifies that a failed scan reported on SCAN_RESULTS_AVAILABLE_ACTION should increase the * ScanResult eviction timeout to twice the default. */ @Test public void failedScan_increasesEvictionTimeout() throws InterruptedException { when(mockWifiManager.getScanResults()).thenReturn(Arrays.asList( buildScanResult1(), buildScanResult2(), buildScanResultWithTimestamp( SystemClock.elapsedRealtime() - WifiTracker.MAX_SCAN_RESULT_AGE_MILLIS))); WifiTracker tracker = createMockedWifiTracker(); sendFailedScanResults(tracker); // Failed scan increases timeout window to include the stale scan assertThat(tracker.getAccessPoints()).hasSize(3); assertThat(tracker.getAccessPoints().get(0).getBssid()).isEqualTo(BSSID_1); assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2); assertThat(tracker.getAccessPoints().get(2).getBssid()).isEqualTo(BSSID_3); sendScanResults(tracker); // Successful scan resets the timeout window to remove the stale scan assertThat(tracker.getAccessPoints()).hasSize(2); assertThat(tracker.getAccessPoints().get(0).getBssid()).isEqualTo(BSSID_1); assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2); } /** * Verifies that updatePasspointAccessPoints will only return AccessPoints whose * isPasspoint() evaluates as true. Loading