diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java index 901848af43a0c..9e9bc9359cdad 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java @@ -985,25 +985,32 @@ public class AccessPoint implements Comparable { return false; } + /** Attempt to update the AccessPoint and return true if an update occurred. */ public boolean update(WifiConfiguration config, WifiInfo info, NetworkInfo networkInfo) { - boolean reorder = false; + boolean updated = false; + final int oldLevel = getLevel(); if (info != null && isInfoForThisAccessPoint(config, info)) { - reorder = (mInfo == null); - mRssi = info.getRssi(); - mInfo = info; - mNetworkInfo = networkInfo; - if (mAccessPointListener != null) { - mAccessPointListener.onAccessPointChanged(this); + updated = (mInfo == null); + if (mRssi != info.getRssi()) { + mRssi = info.getRssi(); + updated = true; } + mInfo = info; + // TODO(b/37289220): compare NetworkInfo states and set updated = true if necessary + mNetworkInfo = networkInfo; } else if (mInfo != null) { - reorder = true; + updated = true; mInfo = null; mNetworkInfo = null; - if (mAccessPointListener != null) { - mAccessPointListener.onAccessPointChanged(this); + } + if (updated && mAccessPointListener != null) { + mAccessPointListener.onAccessPointChanged(this); + + if (oldLevel != getLevel() /* current level */) { + mAccessPointListener.onLevelChanged(this); } } - return reorder; + return updated; } void update(WifiConfiguration config) { diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index fc8c42cd663fc..f277165d8f317 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -203,6 +203,7 @@ public class WifiTracker { mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); mNetworkRequest = new NetworkRequest.Builder() .clearCapabilities() @@ -640,20 +641,24 @@ public class WifiTracker { (System.currentTimeMillis() - before) + "ms."); } - boolean reorder = false; + boolean updated = false; + boolean reorder = false; // Only reorder if connected AP was changed for (int i = mInternalAccessPoints.size() - 1; i >= 0; --i) { AccessPoint ap = mInternalAccessPoints.get(i); + boolean previouslyConnected = ap.isActive(); if (ap.update(connectionConfig, mLastInfo, mLastNetworkInfo)) { - reorder = true; + updated = true; + if (previouslyConnected != ap.isActive()) reorder = true; } if (ap.update(mScoreCache, mNetworkScoringUiEnabled)) { reorder = true; + updated = true; } } - if (reorder) { - Collections.sort(mInternalAccessPoints); - mMainHandler.scheduleAPCopyingAndCloseWriteLock(); - } + + if (reorder) Collections.sort(mInternalAccessPoints); + + if (updated) mMainHandler.scheduleAPCopyingAndCloseWriteLock(); } /** @@ -718,6 +723,8 @@ public class WifiTracker { mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO, info) .sendToTarget(); mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS); + } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) { + mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO); } } }; 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 b71915f30e1c3..f9e695db447c3 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 @@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; @@ -100,6 +101,16 @@ public class WifiTrackerTest { private static final byte SCORE_2 = 15; private static final int BADGE_2 = NetworkBadging.BADGING_HD; + private static final int CONNECTED_NETWORK_ID = 123; + private static final int CONNECTED_RSSI = -50; + private static final WifiInfo CONNECTED_AP_1_INFO = new WifiInfo(); + static { + CONNECTED_AP_1_INFO.setSSID(WifiSsid.createFromAsciiEncoded(SSID_1)); + CONNECTED_AP_1_INFO.setBSSID(BSSID_1); + CONNECTED_AP_1_INFO.setNetworkId(CONNECTED_NETWORK_ID); + CONNECTED_AP_1_INFO.setRssi(CONNECTED_RSSI); + } + @Captor ArgumentCaptor mScoreCacheCaptor; @Mock private ConnectivityManager mockConnectivityManager; @Mock private NetworkScoreManager mockNetworkScoreManager; @@ -312,18 +323,12 @@ public class WifiTrackerTest { private WifiTracker createTrackerWithScanResultsAndAccessPoint1Connected() throws InterruptedException { - int networkId = 123; - - WifiInfo wifiInfo = new WifiInfo(); - wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(SSID_1)); - wifiInfo.setBSSID(BSSID_1); - wifiInfo.setNetworkId(networkId); - when(mockWifiManager.getConnectionInfo()).thenReturn(wifiInfo); + when(mockWifiManager.getConnectionInfo()).thenReturn(CONNECTED_AP_1_INFO); WifiConfiguration configuration = new WifiConfiguration(); configuration.SSID = SSID_1; configuration.BSSID = BSSID_1; - configuration.networkId = networkId; + configuration.networkId = CONNECTED_NETWORK_ID; when(mockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(configuration)); NetworkInfo networkInfo = new NetworkInfo( @@ -445,7 +450,8 @@ public class WifiTrackerTest { } @Test - public void scoreCacheUpdateScoresShouldTriggerOnAccessPointsChanged() throws InterruptedException { + public void scoreCacheUpdateScoresShouldTriggerOnAccessPointsChanged() + throws InterruptedException { WifiTracker tracker = createMockedWifiTracker(); startTracking(tracker); sendScanResultsAndProcess(tracker); @@ -463,7 +469,7 @@ public class WifiTrackerTest { @Test public void scoreCacheUpdateScoresShouldChangeSortOrder() throws InterruptedException { - WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(); + WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(); List aps = tracker.getAccessPoints(); assertTrue(aps.size() == 2); assertEquals(aps.get(0).getSsidStr(), SSID_1); @@ -636,4 +642,28 @@ public class WifiTrackerTest { tracker.forceUpdate(); verify(mockWifiManager).getMatchingWifiConfig(any(ScanResult.class)); } -} + + @Test + public void rssiChangeBroadcastShouldUpdateConnectedAp() throws Exception { + WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected(); + assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue(); + + WifiConfiguration configuration = new WifiConfiguration(); + configuration.SSID = SSID_1; + configuration.BSSID = BSSID_1; + configuration.networkId = CONNECTED_NETWORK_ID; + when(mockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(configuration)); + + int newRssi = CONNECTED_RSSI + 10; + WifiInfo info = new WifiInfo(CONNECTED_AP_1_INFO); + info.setRssi(newRssi); + when(mockWifiManager.getConnectionInfo()).thenReturn(info); + + mAccessPointsChangedLatch = new CountDownLatch(1); + tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.RSSI_CHANGED_ACTION)); + assertTrue(mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)); + + verify(mockWifiManager, atLeast(2)).getConnectionInfo(); + assertThat(tracker.getAccessPoints().get(0).getRssi()).isEqualTo(newRssi); + } +} \ No newline at end of file