Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95f28cf1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Increase ScanResult cache eviction timeout for failed/aborted scans"

parents 5e4bd68c 85bbc6e0
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -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() {
@@ -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<>();
@@ -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();
            }
        }
@@ -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)
+37 −4
Original line number Diff line number Diff line
@@ -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,
@@ -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) {
@@ -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);
@@ -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();
@@ -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.