From d4a79acdfa6565279c772eba944fb72abec83dc3 Mon Sep 17 00:00:00 2001 From: Sundeep Ghuman Date: Wed, 7 Jun 2017 18:11:39 -0700 Subject: [PATCH] Create a staleScanResults bit. This bit is set to true during stop tracking and will not change until fresh scan results come in. This bit is used to prevent onAccessPointsChanged callbacks from being invoked until other new scan results are processed. This is necessary to fix a UI issue in WifiSettings during app resumption where sticky broadcasts from other intents come in before a new scan result is available, causing us to clear out all shown APs since the ScanResults are stale and thus removed from the picker. Bug: b/38212080 Test: runtest --path frameworks/base/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java Change-Id: I2f1fd84d1ab3461d9c8eac9511b90ba7533879c1 --- .../android/settingslib/wifi/WifiTracker.java | 17 ++++++++-- .../settingslib/wifi/WifiTrackerTest.java | 33 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index 40a59cf1ab824..fcc9090fc2f31 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -142,6 +142,7 @@ public class WifiTracker { @VisibleForTesting Scanner mScanner; + private boolean mStaleScanResults = false; public WifiTracker(Context context, WifiListener wifiListener, boolean includeSaved, boolean includeScans) { @@ -330,7 +331,11 @@ public class WifiTracker { * Stop tracking wifi networks and scores. * *

This should always be called when done with a WifiTracker (if startTracking was called) to - * ensure proper cleanup and prevent any further callbacks from occuring. + * ensure proper cleanup and prevent any further callbacks from occurring. + * + *

Calling this method will set the {@link #mStaleScanResults} bit, which prevents + * {@link WifiListener#onAccessPointsChanged()} callbacks from being invoked (until the bit + * is unset on the next SCAN_RESULTS_AVAILABLE_ACTION). */ @MainThread public void stopTracking() { @@ -346,6 +351,7 @@ public class WifiTracker { mWorkHandler.removePendingMessages(); mMainHandler.removePendingMessages(); } + mStaleScanResults = true; } private void unregisterAndClearScoreCache() { @@ -712,6 +718,11 @@ public class WifiTracker { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); + + if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) { + mStaleScanResults = false; + } + if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) { updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)); @@ -822,7 +833,9 @@ public class WifiTracker { switch (msg.what) { case MSG_UPDATE_ACCESS_POINTS: - updateAccessPointsLocked(); + if (!mStaleScanResults) { + updateAccessPointsLocked(); + } break; case MSG_UPDATE_NETWORK_INFO: updateNetworkInfo((NetworkInfo) msg.obj); diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java index c52643243063b..eb9a7f6d08435 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -748,4 +749,36 @@ public class WifiTrackerTest { verifyNoMoreInteractions(mockWifiListener); } + + @Test + public void stopTrackingShouldSetStaleBitWhichPreventsCallbacksUntilNextScanResult() + throws Exception { + WifiTracker tracker = createMockedWifiTracker(); + startTracking(tracker); + tracker.stopTracking(); + + CountDownLatch latch1 = new CountDownLatch(1); + tracker.mMainHandler.post(() -> { + latch1.countDown(); + }); + assertTrue("Latch 1 timed out", latch1.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)); + + startTracking(tracker); + + tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); + tracker.mReceiver.onReceive( + mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION)); + tracker.mReceiver.onReceive( + mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION)); + + CountDownLatch latch2 = new CountDownLatch(1); + tracker.mMainHandler.post(() -> { + latch2.countDown(); + }); + assertTrue("Latch 2 timed out", latch2.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)); + + verify(mockWifiListener, never()).onAccessPointsChanged(); + + sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked + } }